From 98faed8ff58d92bc6c138310b46608fff1ace9a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Tue, 1 Jul 2008 18:23:44 -0500 Subject: [PATCH] wined3d: Start the state splitup. The idea of this patchset is to split the monolithic state set into 3 parts, vertex processing, fragment processing and other states(depth, stencil, scissor, ...). The states will be provided in templates which can be (mostly) independently combined, and are merged into a single state table at device creation time. This way we retain the advantages of the single state table and having the advantage of separated pipeline implementations which can be combined without any manually written glue code. --- dlls/wined3d/ati_fragment_shader.c | 2 +- dlls/wined3d/context.c | 8 ++++---- dlls/wined3d/device.c | 4 ++-- dlls/wined3d/directx.c | 2 ++ dlls/wined3d/state.c | 11 +++++++++-- dlls/wined3d/wined3d_private.h | 4 +++- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 99f1fd474a8..83779170a7c 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -859,7 +859,7 @@ struct StateEntry ATIFSStateTable[STATE_HIGHEST + 1]; static void init_state_table() { unsigned int i; const DWORD rep = STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP); - memcpy(ATIFSStateTable, arb_program_shader_backend.StateTable, sizeof(ATIFSStateTable)); + memcpy(ATIFSStateTable, arb_program_shader_backend.StateTable_remove, sizeof(ATIFSStateTable)); for(i = 0; i < MAX_TEXTURES; i++) { ATIFSStateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply = set_tex_op_atifs; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 6f5424c6472..b09707bf31d 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -102,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, This->shader_backend->StateTable); + Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable); } This->numContexts++; @@ -641,7 +641,7 @@ static inline void set_blit_dimension(UINT width, UINT height) { *****************************************************************************/ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) { int i; - const struct StateEntry *StateTable = This->shader_backend->StateTable; + const struct StateEntry *StateTable = This->StateTable; TRACE("Setting up context %p for blitting\n", context); if(context->last_was_blit) { @@ -836,7 +836,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; + const struct StateEntry *StateTable = This->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 @@ -1034,7 +1034,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU BYTE shift; WineD3DContext *context; GLint drawBuffer=0; - const struct StateEntry *StateTable = This->shader_backend->StateTable; + const struct StateEntry *StateTable = This->StateTable; TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid); if(This->lastActiveRenderTarget != target || tid != This->lastThread) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 26c1c9caad3..74bb67670fa 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4507,7 +4507,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if } if(Stage > This->stateBlock->lowest_disabled_stage && - This->shader_backend->StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) { + This->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 */ @@ -7977,7 +7977,7 @@ const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S] = { }; void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { - DWORD rep = This->shader_backend->StateTable[state].representative; + DWORD rep = This->StateTable[state].representative; DWORD idx; BYTE shift; UINT i; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 8811d0ab434..f121cde37a0 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3446,6 +3446,8 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode); object->shader_backend = select_shader_backend(Adapter, DeviceType); + compile_state_table(object->StateTable, object->shader_backend->StateTable_remove); + /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader * model can deal with that. It is essentially the same, just with adjusted * Set*ShaderConstantF implementations diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1fc1309cd83..94a27fae1de 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -446,7 +446,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]) { - const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable; + const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable; StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } } @@ -496,7 +496,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D } if(enable_ckey || context->last_was_ckey) { - const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable; + const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable; StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } context->last_was_ckey = enable_ckey; @@ -4885,3 +4885,10 @@ const struct StateEntry FFPStateTable[] = { /* STATE_MATERIAL */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, { /* STATE_FRONTFACE */ STATE_FRONTFACE, frontface }, }; + +/* Remove the temptable, but instead pass a fragment pipeline table, vertex pipeline and misc pipeline + * table in + */ +void compile_state_table(struct StateEntry *StateTable, const struct StateEntry *temptable) { + memcpy(StateTable, temptable, sizeof(*StateTable) * (STATE_HIGHEST + 1)); +} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d1456d2d498..5e988df7392 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -302,7 +302,7 @@ typedef struct { void (*shader_get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps); void (*shader_dll_load_init)(void); void (*shader_fragment_enable)(IWineD3DDevice *iface, BOOL enable); - const struct StateEntry *StateTable; + const struct StateEntry *StateTable_remove; /* TODO: This has to go away */ } shader_backend_t; extern const shader_backend_t atifs_shader_backend; @@ -588,6 +588,7 @@ struct StateEntry /* "Base" state table */ extern const struct StateEntry FFPStateTable[]; +void compile_state_table(struct StateEntry *StateTable, const struct StateEntry *temptable); /* The new context manager that should deal with onscreen and offscreen rendering */ struct WineD3DContext { @@ -812,6 +813,7 @@ struct IWineD3DDeviceImpl const shader_backend_t *shader_backend; hash_table_t *glsl_program_lookup; void *shader_priv; + struct StateEntry StateTable[STATE_HIGHEST + 1]; /* To store */ BOOL view_ident; /* true iff view matrix is identity */ -- 2.11.4.GIT