diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 8ddab49c7d2..1331bf8b66e 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1883,6 +1883,6 @@ const shader_backend_t arb_program_shader_backend = { &shader_arb_destroy, &shader_arb_alloc, &shader_arb_free, - &shader_arb_dirty_const - + &shader_arb_dirty_const, + FFPStateTable }; diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index b5328b0af1d..11b4861da11 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -1109,7 +1109,8 @@ const shader_backend_t none_shader_backend = { &shader_none_destroy, &shader_none_alloc, &shader_none_free, - &shader_none_dirty_const + &shader_none_dirty_const, + FFPStateTable }; /* ******************************************* diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 9a5ed78f702..ad31a488866 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -39,9 +39,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); * Params: * context: Context to mark the state dirty in * state: State to mark dirty + * StateTable: Pointer to the state table in use(for state grouping) * *****************************************************************************/ -static void Context_MarkStateDirty(WineD3DContext *context, DWORD state) { +static void Context_MarkStateDirty(WineD3DContext *context, DWORD state, const struct StateEntry *StateTable) { DWORD rep = StateTable[state].representative; DWORD idx; BYTE shift; @@ -101,7 +102,7 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand /* Mark all states dirty to force a proper initialization of the states on the first use of the context */ for(state = 0; state <= STATE_HIGHEST; state++) { - Context_MarkStateDirty(This->contexts[This->numContexts], state); + Context_MarkStateDirty(This->contexts[This->numContexts], state, This->shader_backend->StateTable); } This->numContexts++; @@ -514,6 +515,7 @@ void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) { *****************************************************************************/ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) { int i; + const struct StateEntry *StateTable = This->shader_backend->StateTable; TRACE("Setting up context %p for blitting\n", context); if(context->last_was_blit) { @@ -526,8 +528,8 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex /* Disable shaders */ This->shader_backend->shader_cleanup((IWineD3DDevice *) This); - Context_MarkStateDirty(context, STATE_VSHADER); - Context_MarkStateDirty(context, STATE_PIXELSHADER); + Context_MarkStateDirty(context, STATE_VSHADER, StateTable); + Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable); /* Disable all textures. The caller can then bind a texture it wants to blit * from @@ -556,8 +558,8 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);"); - Context_MarkStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)); - Context_MarkStateDirty(context, STATE_SAMPLER(i)); + Context_MarkStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), StateTable); + Context_MarkStateDirty(context, STATE_SAMPLER(i), StateTable); } GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB)); checkGLcall("glActiveTextureARB"); @@ -577,7 +579,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex checkGLcall("glMatrixMode(GL_TEXTURE)"); glLoadIdentity(); checkGLcall("glLoadIdentity()"); - Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0)); + Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0), StateTable); if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) { glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, @@ -585,50 +587,50 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex 0.0); checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ..."); } - Context_MarkStateDirty(context, STATE_SAMPLER(0)); - Context_MarkStateDirty(context, STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)); + Context_MarkStateDirty(context, STATE_SAMPLER(0), StateTable); + Context_MarkStateDirty(context, STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), StateTable); /* Other misc states */ glDisable(GL_ALPHA_TEST); checkGLcall("glDisable(GL_ALPHA_TEST)"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHATESTENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHATESTENABLE), StateTable); glDisable(GL_LIGHTING); checkGLcall("glDisable GL_LIGHTING"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING), StateTable); glDisable(GL_DEPTH_TEST); checkGLcall("glDisable GL_DEPTH_TEST"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE), StateTable); glDisable(GL_FOG); checkGLcall("glDisable GL_FOG"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE), StateTable); glDisable(GL_BLEND); checkGLcall("glDisable GL_BLEND"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); glDisable(GL_CULL_FACE); checkGLcall("glDisable GL_CULL_FACE"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CULLMODE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CULLMODE), StateTable); glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_STENCILENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_STENCILENABLE), StateTable); glDisable(GL_SCISSOR_TEST); checkGLcall("glDisable GL_SCISSOR_TEST"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable); if(GL_SUPPORT(ARB_POINT_SPRITE)) { glDisable(GL_POINT_SPRITE_ARB); checkGLcall("glDisable GL_POINT_SPRITE_ARB"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), StateTable); } glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); checkGLcall("glColorMask"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable); if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { glDisable(GL_COLOR_SUM_EXT); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable); checkGLcall("glDisable(GL_COLOR_SUM_EXT)"); } if (GL_SUPPORT(NV_REGISTER_COMBINERS)) { GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB)); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable); checkGLcall("glFinalCombinerInputNV"); } @@ -637,7 +639,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex checkGLcall("glMatrixMode(GL_MODELVIEW)"); glLoadIdentity(); checkGLcall("glLoadIdentity()"); - Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))); + Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), StateTable); glMatrixMode(GL_PROJECTION); checkGLcall("glMatrixMode(GL_PROJECTION)"); @@ -645,10 +647,10 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex checkGLcall("glLoadIdentity()"); glOrtho(0, width, height, 0, 0.0, -1.0); checkGLcall("glOrtho"); - Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)); + Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); context->last_was_rhw = TRUE; - Context_MarkStateDirty(context, STATE_VDECL); /* because of last_was_rhw = TRUE */ + Context_MarkStateDirty(context, STATE_VDECL, StateTable); /* because of last_was_rhw = TRUE */ glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); @@ -656,11 +658,11 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable); glViewport(0, 0, width, height); checkGLcall("glViewport"); - Context_MarkStateDirty(context, STATE_VIEWPORT); + Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { glDisable(GL_TEXTURE_SHADER_NV); @@ -709,6 +711,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf BOOL oldRenderOffscreen = This->render_offscreen; const WINED3DFORMAT oldFmt = ((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->resource.format; const WINED3DFORMAT newFmt = ((IWineD3DSurfaceImpl *) target)->resource.format; + const struct StateEntry *StateTable = This->shader_backend->StateTable; /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers * the alpha blend state changes with different render target formats @@ -718,7 +721,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf const StaticPixelFormatDesc *new = getFormatDescEntry(newFmt, NULL, NULL); if((old->alphaMask && !new->alphaMask) || (!old->alphaMask && new->alphaMask)) { - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE)); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); } } @@ -747,11 +750,11 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf IWineD3DSwapChain_Release(swapchain); if(oldRenderOffscreen) { - Context_MarkStateDirty(context, WINED3DTS_PROJECTION); - Context_MarkStateDirty(context, STATE_VDECL); - Context_MarkStateDirty(context, STATE_VIEWPORT); - Context_MarkStateDirty(context, STATE_SCISSORRECT); - Context_MarkStateDirty(context, STATE_FRONTFACE); + Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable); + Context_MarkStateDirty(context, STATE_VDECL, StateTable); + Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); + Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); + Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); } } else { @@ -834,11 +837,11 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf } if(!oldRenderOffscreen) { - Context_MarkStateDirty(context, WINED3DTS_PROJECTION); - Context_MarkStateDirty(context, STATE_VDECL); - Context_MarkStateDirty(context, STATE_VIEWPORT); - Context_MarkStateDirty(context, STATE_SCISSORRECT); - Context_MarkStateDirty(context, STATE_FRONTFACE); + Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable); + Context_MarkStateDirty(context, STATE_VDECL, StateTable); + Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); + Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); + Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); } } if (readTexture) { @@ -887,6 +890,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU BYTE shift; WineD3DContext *context; GLint drawBuffer=0; + const struct StateEntry *StateTable = This->shader_backend->StateTable; TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid); if(This->lastActiveRenderTarget != target || tid != This->lastThread) { @@ -949,8 +953,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU glEnable(GL_SCISSOR_TEST); checkGLcall("glEnable GL_SCISSOR_TEST"); context->last_was_blit = FALSE; - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); - Context_MarkStateDirty(context, STATE_SCISSORRECT); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable); + Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); break; case CTXUSAGE_DRAWPRIM: diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7d208dc9623..dea417c6f74 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4411,7 +4411,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if } if(Stage > This->stateBlock->lowest_disabled_stage && - StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) { + This->shader_backend->StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) { /* Colorop change above lowest disabled stage? That won't change anything in the gl setup * Changes in other states are important on disabled stages too */ @@ -7778,7 +7778,7 @@ const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S] = { }; void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { - DWORD rep = StateTable[state].representative; + DWORD rep = This->shader_backend->StateTable[state].representative; DWORD idx; BYTE shift; UINT i; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7fe504a2fdf..400b2a7a158 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3372,5 +3372,6 @@ const shader_backend_t glsl_shader_backend = { &shader_glsl_destroy, &shader_glsl_alloc, &shader_glsl_free, - &shader_glsl_dirty_const + &shader_glsl_dirty_const, + FFPStateTable }; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 355a5b6d965..a786458c9f7 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -435,7 +435,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state, so it may need updating */ if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) { - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); + FFPStateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } } @@ -484,7 +484,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D } if(enable_ckey || context->last_was_ckey) { - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); + FFPStateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } context->last_was_ckey = enable_ckey; @@ -2605,7 +2605,7 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D update_fog = TRUE; } - if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) { + if(!isStateDirty(context, FFPStateTable[STATE_VSHADER].representative)) { device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader); if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) { @@ -3915,7 +3915,7 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo } } -const struct StateEntry StateTable[] = +const struct StateEntry FFPStateTable[] = { /* State name representative, apply function */ { /* 0, Undefined */ 0, state_undefined }, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8da308e11dc..dbaa0baeafc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -260,6 +260,7 @@ typedef struct { HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); void (*shader_free_private)(IWineD3DDevice *iface); BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface); + const struct StateEntry *StateTable; } shader_backend_t; extern const shader_backend_t glsl_shader_backend; @@ -543,8 +544,8 @@ struct StateEntry APPLYSTATEFUNC apply; }; -/* Global state table */ -extern const struct StateEntry StateTable[]; +/* "Base" state table */ +extern const struct StateEntry FFPStateTable[]; /* The new context manager that should deal with onscreen and offscreen rendering */ struct WineD3DContext {