[PATCH] WineD3D: Implement the state merger and start to use it=0A=

Stefan Doesinger stefan at codeweavers.com
Tue Jul 1 19:43:52 CDT 2008


=0A=
This patch adds a bit of code which will allow the move in incremental =
changes and will be removed at the end=0A=
---=0A=
 dlls/wined3d/directx.c         |    4 +-=0A=
 dlls/wined3d/state.c           |  125 =
+++++++++++++++++++++++++++++++++++-----=0A=
 dlls/wined3d/wined3d_private.h |   21 ++++++-=0A=
 3 files changed, 132 insertions(+), 18 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c=0A=
index f121cde..7f77604 100644=0A=
--- a/dlls/wined3d/directx.c=0A=
+++ b/dlls/wined3d/directx.c=0A=
@@ -3446,7 +3446,9 @@ static HRESULT  WINAPI =
IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,=0A=
     select_shader_mode(&GLINFO_LOCATION, DeviceType, =
&object->ps_selected_mode, &object->vs_selected_mode);=0A=
     object->shader_backend =3D select_shader_backend(Adapter, =
DeviceType);=0A=
 =0A=
-    compile_state_table(object->StateTable, =
object->shader_backend->StateTable_remove);=0A=
+    compile_state_table(object->StateTable, object->multistate_funcs,=0A=
+                        NULL, NULL, misc_state_template,=0A=
+                        object->shader_backend->StateTable_remove);=0A=
 =0A=
     /* Prefer the vtable with functions optimized for single =
dirtifyable objects if the shader=0A=
      * model can deal with that. It is essentially the same, just with =
adjusted=0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 94a27fa..4e0f5d8 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -3834,15 +3834,15 @@ const struct StateEntry FFPStateTable[] =3D=0A=
     { /* 16, WINED3DRS_LASTPIXEL                    */      =
STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     =
},=0A=
     { /* 17, WINED3DRS_TEXTUREMAG                   */      0 /* =
Handled in ddraw */,                           state_undefined     },=0A=
     { /* 18, WINED3DRS_TEXTUREMIN                   */      0 /* =
Handled in ddraw */,                           state_undefined     },=0A=
-    { /* 19, WINED3DRS_SRCBLEND                     */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
},=0A=
-    { /* 20, WINED3DRS_DESTBLEND                    */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
},=0A=
+    { /* 19, WINED3DRS_SRCBLEND                     */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
+    { /* 20, WINED3DRS_DESTBLEND                    */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
     { /* 21, WINED3DRS_TEXTUREMAPBLEND              */      0 /* =
Handled in ddraw */,                           state_undefined     },=0A=
     { /* 22, WINED3DRS_CULLMODE                     */      =
STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      =
},=0A=
     { /* 23, WINED3DRS_ZFUNC                        */      =
STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         =
},=0A=
     { /* 24, WINED3DRS_ALPHAREF                     */      =
STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         =
},=0A=
     { /* 25, WINED3DRS_ALPHAFUNC                    */      =
STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         =
},=0A=
     { /* 26, WINED3DRS_DITHERENABLE                 */      =
STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  =
},=0A=
-    { /* 27, WINED3DRS_ALPHABLENDENABLE             */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
},=0A=
+    { /* 27, WINED3DRS_ALPHABLENDENABLE             */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
     { /* 28, WINED3DRS_FOGENABLE                    */      =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
},=0A=
     { /* 29, WINED3DRS_SPECULARENABLE               */      =
STATE_RENDER(WINED3DRS_SPECULARENABLE),             =
state_specularenable},=0A=
     { /* 30, WINED3DRS_ZVISIBLE                     */      0 /* Not =
supported according to the msdn */,        state_nogl          },=0A=
@@ -3855,7 +3855,7 @@ const struct StateEntry FFPStateTable[] =3D=0A=
     { /* 37, WINED3DRS_FOGEND                       */      =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           =
},=0A=
     { /* 38, WINED3DRS_FOGDENSITY                   */      =
STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    =
},=0A=
     { /* 39, WINED3DRS_STIPPLEENABLE                */      =
STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable =
},=0A=
-    { /* 40, WINED3DRS_EDGEANTIALIAS                */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
},=0A=
+    { /* 40, WINED3DRS_EDGEANTIALIAS                */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
     { /* 41, WINED3DRS_COLORKEYENABLE               */      =
STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         =
},=0A=
     { /* 42, undefined                              */      0,          =
                                        state_undefined     },=0A=
     { /* 43, WINED3DRS_BORDERCOLOR                  */      =
STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   =
},=0A=
@@ -3994,7 +3994,7 @@ const struct StateEntry FFPStateTable[] =3D=0A=
       /*173, WINED3DRS_NORMALORDER                  */      /* Value =
assigned to 2 state names */=0A=
     { /*174, WINED3DRS_SCISSORTESTENABLE            */      =
STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       =
},=0A=
     { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS          */      =
STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     =
},=0A=
-    { /*176, WINED3DRS_ANTIALIASEDLINEENABLE        */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
},=0A=
+    { /*176, WINED3DRS_ANTIALIASEDLINEENABLE        */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
     { /*177, undefined                              */      0,          =
                                        state_undefined     },=0A=
     { /*178, WINED3DRS_MINTESSELLATIONLEVEL         */      =
STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  =
},=0A=
     { /*179, WINED3DRS_MAXTESSELLATIONLEVEL         */      =
STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  =
},=0A=
@@ -4024,10 +4024,10 @@ const struct StateEntry FFPStateTable[] =3D=0A=
     { /*203, WINED3DRS_WRAP13                       */      =
STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          =
},=0A=
     { /*204, WINED3DRS_WRAP14                       */      =
STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          =
},=0A=
     { /*205, WINED3DRS_WRAP15                       */      =
STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          =
},=0A=
-    { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE     */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend },=0A=
-    { /*207, WINED3DRS_SRCBLENDALPHA                */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend },=0A=
-    { /*208, WINED3DRS_DESTBLENDALPHA               */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend },=0A=
-    { /*209, WINED3DRS_BLENDOPALPHA                 */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blendop },=0A=
+    { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE     */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
+    { /*207, WINED3DRS_SRCBLENDALPHA                */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
+    { /*208, WINED3DRS_DESTBLENDALPHA               */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
+    { /*209, WINED3DRS_BLENDOPALPHA                 */      =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                =
},=0A=
     /* Texture stage states */=0A=
     { /*0, 01, WINED3DTSS_COLOROP                   */      =
STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         =
},=0A=
     { /*0, 02, WINED3DTSS_COLORARG1                 */      =
STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         =
},=0A=
@@ -4886,9 +4886,106 @@ const struct StateEntry FFPStateTable[] =3D=0A=
     { /* STATE_FRONTFACE                            */      =
STATE_FRONTFACE,                                    frontface           =
},=0A=
 };=0A=
 =0A=
-/* Remove the temptable, but instead pass a fragment pipeline table, =
vertex pipeline and misc pipeline=0A=
- * table in=0A=
- */=0A=
-void compile_state_table(struct StateEntry *StateTable, const struct =
StateEntry *temptable) {=0A=
-    memcpy(StateTable, temptable, sizeof(*StateTable) * (STATE_HIGHEST =
+ 1));=0A=
+const struct StateEntryTemplate misc_state_template[] =3D {=0A=
+    { STATE_RENDER(WINED3DRS_SRCBLEND),                   { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_DESTBLEND),                  { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_EDGEANTIALIAS),              { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE),      { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_SRCBLENDALPHA),              { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    { STATE_RENDER(WINED3DRS_BLENDOPALPHA),               { =
STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         =
}},=0A=
+    {0 /* Terminate */,                                   { 0,          =
                                        0                   }},=0A=
+};=0A=
+=0A=
+static int num_handlers(APPLYSTATEFUNC *funcs) {=0A=
+    unsigned int i;=0A=
+    for(i =3D 0; funcs[i]; i++);=0A=
+    return i;=0A=
+}=0A=
+=0A=
+static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    stateblock->wineD3DDevice->multistate_funcs[state][0](state, =
stateblock, context);=0A=
+    stateblock->wineD3DDevice->multistate_funcs[state][1](state, =
stateblock, context);=0A=
+}=0A=
+=0A=
+static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    stateblock->wineD3DDevice->multistate_funcs[state][0](state, =
stateblock, context);=0A=
+    stateblock->wineD3DDevice->multistate_funcs[state][1](state, =
stateblock, context);=0A=
+    stateblock->wineD3DDevice->multistate_funcs[state][2](state, =
stateblock, context);=0A=
+}=0A=
+=0A=
+void compile_state_table(struct StateEntry *StateTable,=0A=
+                         APPLYSTATEFUNC **dev_multistate_funcs,=0A=
+                         const struct StateEntryTemplate *vertex,=0A=
+                         const struct StateEntryTemplate *fragment,=0A=
+                         const struct StateEntryTemplate *misc,=0A=
+                         const struct StateEntry *temptable /* TODO: =
Remove this */) {=0A=
+    unsigned int i, type, handlers;=0A=
+    APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];=0A=
+    const struct StateEntryTemplate *cur;=0A=
+=0A=
+    /* TODO: Remove this once all states are provided by templates */=0A=
+    BOOL set[STATE_HIGHEST + 1];=0A=
+    memset(set, 0, sizeof(set));=0A=
+=0A=
+    memset(multistate_funcs, 0, sizeof(multistate_funcs));=0A=
+=0A=
+    for(type =3D 0; type < 3; type++) {=0A=
+        /* This switch decides the order in which the states are =
applied */=0A=
+        switch(type) {=0A=
+            case 0: cur =3D misc; break;=0A=
+            case 1: cur =3D fragment; break;=0A=
+            case 2: cur =3D vertex; break;=0A=
+            default: cur =3D NULL; /* Stupid compiler */=0A=
+        }=0A=
+        if(!cur) continue;=0A=
+=0A=
+        for(i =3D 0; cur[i].state; i++) {=0A=
+            set[cur[i].state] =3D TRUE; /* TODO: Remove when done with =
the move */=0A=
+            handlers =3D num_handlers(multistate_funcs[cur[i].state]);=0A=
+            multistate_funcs[cur[i].state][handlers] =3D =
cur[i].content.apply;=0A=
+            switch(handlers) {=0A=
+                case 0:=0A=
+                    StateTable[cur[i].state].apply =3D =
cur[i].content.apply;=0A=
+                    break;=0A=
+                case 1:=0A=
+                    StateTable[cur[i].state].apply =3D =
multistate_apply_2;=0A=
+                    dev_multistate_funcs[cur[i].state] =3D =
HeapAlloc(GetProcessHeap(),=0A=
+                                                                   0,=0A=
+                                                                   =
sizeof(**dev_multistate_funcs) * 2);=0A=
+                    dev_multistate_funcs[cur[i].state][0] =3D =
multistate_funcs[cur[i].state][0];=0A=
+                    dev_multistate_funcs[cur[i].state][1] =3D =
multistate_funcs[cur[i].state][1];=0A=
+                    break;=0A=
+                case 2:=0A=
+                    StateTable[cur[i].state].apply =3D =
multistate_apply_3;=0A=
+                    HeapFree(GetProcessHeap(), 0, =
multistate_funcs[cur[i].state]);=0A=
+                    dev_multistate_funcs[cur[i].state] =3D =
HeapAlloc(GetProcessHeap(),=0A=
+                                                                   0,=0A=
+                                                                   =
sizeof(**dev_multistate_funcs) * 3);=0A=
+                    dev_multistate_funcs[cur[i].state][0] =3D =
multistate_funcs[cur[i].state][0];=0A=
+                    dev_multistate_funcs[cur[i].state][1] =3D =
multistate_funcs[cur[i].state][1];=0A=
+                    dev_multistate_funcs[cur[i].state][2] =3D =
multistate_funcs[cur[i].state][2];=0A=
+                    break;=0A=
+                default:=0A=
+                    ERR("Unexpected amount of state handlers for state =
%u: %u\n",=0A=
+                        cur[i].state, handlers + 1);=0A=
+            }=0A=
+=0A=
+            if(StateTable[cur[i].state].representative &&=0A=
+            StateTable[cur[i].state].representative !=3D =
cur[i].content.representative) {=0A=
+                FIXME("State %u has different representatives in =
different pipeline parts\n",=0A=
+                    cur[i].state);=0A=
+            }=0A=
+            StateTable[cur[i].state].representative =3D =
cur[i].content.representative;=0A=
+        }=0A=
+    }=0A=
+=0A=
+    /* TODO Remove this after the state move is done */=0A=
+    for(i =3D 0; i < STATE_HIGHEST + 1; i++) {=0A=
+        if(set[i]) continue;=0A=
+        StateTable[i] =3D temptable[i];=0A=
+    }=0A=
 }=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 5e988df..90f89fe 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -582,13 +582,26 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, =
IWineD3DStateBlockImpl *stateblock,=0A=
 =0A=
 struct StateEntry=0A=
 {=0A=
-    DWORD           representative;=0A=
-    APPLYSTATEFUNC  apply;=0A=
+    DWORD               representative;=0A=
+    APPLYSTATEFUNC      apply;=0A=
 };=0A=
 =0A=
+struct StateEntryTemplate=0A=
+{=0A=
+    DWORD               state;=0A=
+    struct StateEntry   content;=0A=
+};=0A=
+=0A=
+extern const struct StateEntryTemplate misc_state_template[];=0A=
+=0A=
 /* "Base" state table */=0A=
 extern const struct StateEntry FFPStateTable[];=0A=
-void compile_state_table(struct StateEntry *StateTable, const struct =
StateEntry *temptable);=0A=
+void compile_state_table(struct StateEntry *StateTable,=0A=
+                         APPLYSTATEFUNC **dev_multistate_funcs,=0A=
+                         const struct StateEntryTemplate *vertex,=0A=
+                         const struct StateEntryTemplate *fragment,=0A=
+                         const struct StateEntryTemplate *misc,=0A=
+                         const struct StateEntry *temptable /* TODO: =
Remove this */);=0A=
 =0A=
 /* The new context manager that should deal with onscreen and offscreen =
rendering */=0A=
 struct WineD3DContext {=0A=
@@ -814,6 +827,8 @@ struct IWineD3DDeviceImpl=0A=
     hash_table_t *glsl_program_lookup;=0A=
     void *shader_priv;=0A=
     struct StateEntry StateTable[STATE_HIGHEST + 1];=0A=
+    /* Array of functions for states which are handled by more than one =
pipeline part */=0A=
+    APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];=0A=
 =0A=
     /* To store */=0A=
     BOOL                    view_ident;        /* true iff view matrix =
is identity                */=0A=
-- =0A=
1.5.4.5=0A=
=0A=

------=_NextPart_000_0059_01C8E026.985140A0--




More information about the wine-patches mailing list