Stefan Dösinger : wined3d: Start the state splitup.

Alexandre Julliard julliard at winehq.org
Tue Jul 8 06:10:49 CDT 2008


Module: wine
Branch: master
Commit: 98faed8ff58d92bc6c138310b46608fff1ace9a1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=98faed8ff58d92bc6c138310b46608fff1ace9a1

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Jul  1 18:23:44 2008 -0500

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 99f1fd4..8377917 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 6f5424c..b09707b 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 26c1c9c..74bb676 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 8811d0a..f121cde 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 1fc1309..94a27fa 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 d1456d2..5e988df 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                */




More information about the wine-cvs mailing list