wined3d: Make the state table a property of the shader backend.

This commit is contained in:
Stefan Dösinger 2008-03-09 19:30:08 +01:00 committed by Alexandre Julliard
parent 1e9acad3a0
commit 84258723f9
7 changed files with 58 additions and 51 deletions

View File

@ -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
};

View File

@ -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
};
/* *******************************************

View File

@ -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:

View File

@ -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;

View File

@ -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
};

View File

@ -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 },

View File

@ -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 {