[v2 3/4] d3dx9: Support effect state manager.

Paul Gofman gofmanp at gmail.com
Mon Apr 10 04:57:40 CDT 2017


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
    v2: no changes
---
 dlls/d3dx9_36/d3dx9_private.h |  6 +++-
 dlls/d3dx9_36/effect.c        | 74 ++++++++++++++++++++++++++++---------------
 dlls/d3dx9_36/preshader.c     | 22 ++++++-------
 dlls/d3dx9_36/tests/effect.c  |  2 --
 4 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index abb3114..e50f4d3 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -232,12 +232,16 @@ struct d3dx9_base_effect;
 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
         struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
 
+#define SET_D3D_STATE_(manager, device, method, args...) (manager ? manager->lpVtbl->method(manager, args) \
+        : device->lpVtbl->method(device, args))
+#define SET_D3D_STATE(base_effect, args...) SET_D3D_STATE_(base_effect->manager, base_effect->device, args)
+
 void d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
         unsigned int byte_code_size, D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval) DECLSPEC_HIDDEN;
 void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
 HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval,
         const struct d3dx_parameter *param, void *param_value, BOOL update_all) DECLSPEC_HIDDEN;
-HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device,
+HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
         struct d3dx_param_eval *peval, BOOL update_all) DECLSPEC_HIDDEN;
 BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
 
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 374cbf4..10f603c 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -174,7 +174,9 @@ struct ID3DXEffectImpl
     DWORD flags;
 
     D3DLIGHT9 current_light[8];
+    BOOL light_updated[8];
     D3DMATERIAL9 current_material;
+    BOOL material_updated;
 };
 
 struct ID3DXEffectCompilerImpl
@@ -2740,7 +2742,7 @@ static void d3dx9_set_material_parameter(enum MATERIAL_TYPE op, D3DMATERIAL9 *ma
     }
 }
 
-static HRESULT d3dx_set_shader_const_state(IDirect3DDevice9 *device, enum SHADER_CONSTANT_TYPE op, UINT index,
+static HRESULT d3dx_set_shader_const_state(struct ID3DXEffectImpl *effect, enum SHADER_CONSTANT_TYPE op, UINT index,
         struct d3dx_parameter *param, void *value_ptr)
 {
     static const struct
@@ -2781,17 +2783,17 @@ static HRESULT d3dx_set_shader_const_state(IDirect3DDevice9 *device, enum SHADER
     switch (op)
     {
         case SCT_VSFLOAT:
-            return IDirect3DDevice9_SetVertexShaderConstantF(device, index, (const float *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetVertexShaderConstantF, index, (const float *)value_ptr, element_count);
         case SCT_VSBOOL:
-            return IDirect3DDevice9_SetVertexShaderConstantB(device, index, (const BOOL *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetVertexShaderConstantB, index, (const BOOL *)value_ptr, element_count);
         case SCT_VSINT:
-            return IDirect3DDevice9_SetVertexShaderConstantI(device, index, (const int *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetVertexShaderConstantI, index, (const int *)value_ptr, element_count);
         case SCT_PSFLOAT:
-            return IDirect3DDevice9_SetPixelShaderConstantF(device, index, (const float *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetPixelShaderConstantF, index, (const float *)value_ptr, element_count);
         case SCT_PSBOOL:
-            return IDirect3DDevice9_SetPixelShaderConstantB(device, index, (const BOOL *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetPixelShaderConstantB, index, (const BOOL *)value_ptr, element_count);
         case SCT_PSINT:
-            return IDirect3DDevice9_SetPixelShaderConstantI(device, index, (const int *)value_ptr, element_count);
+            return SET_D3D_STATE(effect, SetPixelShaderConstantI, index, (const int *)value_ptr, element_count);
     }
     return D3D_OK;
 }
@@ -2802,7 +2804,6 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
 static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
         struct d3dx_parameter *param, BOOL vs, BOOL update_all)
 {
-    IDirect3DDevice9 *device = effect->device;
     HRESULT hr, ret;
     struct d3dx_parameter **params;
     D3DXCONSTANT_DESC *cdesc;
@@ -2814,7 +2815,8 @@ static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct
         FIXME("param_eval structure is null.\n");
         return D3DERR_INVALIDCALL;
     }
-    if (FAILED(hr = d3dx_param_eval_set_shader_constants(device, param->param_eval, update_all)))
+    if (FAILED(hr = d3dx_param_eval_set_shader_constants(effect->manager, effect->device,
+            param->param_eval, update_all)))
         return hr;
     params = param->param_eval->shader_inputs.inputs_param;
     cdesc = param->param_eval->shader_inputs.inputs;
@@ -2843,7 +2845,6 @@ static HRESULT d3dx_set_shader_constants(struct ID3DXEffectImpl *effect, struct
 static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pass *pass,
         struct d3dx_state *state, unsigned int parent_index, BOOL update_all)
 {
-    IDirect3DDevice9 *device = effect->device;
     struct d3dx_parameter *param;
     void *param_value;
     BOOL param_dirty;
@@ -2878,10 +2879,10 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
         case SC_RENDERSTATE:
             TRACE("%s, operation %u, value %u.\n", state_table[state->operation].name,
                     state_table[state->operation].op, *(DWORD *)param_value);
-            return IDirect3DDevice9_SetRenderState(device, state_table[state->operation].op, *(DWORD *)param_value);
+            return SET_D3D_STATE(effect, SetRenderState, state_table[state->operation].op, *(DWORD *)param_value);
         case SC_FVF:
             TRACE("%s, value %#x.\n", state_table[state->operation].name, *(DWORD *)param_value);
-            return IDirect3DDevice9_SetFVF(device, *(DWORD *)param_value);
+            return SET_D3D_STATE(effect, SetFVF, *(DWORD *)param_value);
         case SC_TEXTURE:
         {
             UINT unit;
@@ -2889,12 +2890,12 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
             unit = parent_index == ~0u ? state->index : parent_index;
             TRACE("%s, unit %u, value %p.\n", state_table[state->operation].name, unit,
                     *(IDirect3DBaseTexture9 **)param_value);
-            return IDirect3DDevice9_SetTexture(device, unit, *(IDirect3DBaseTexture9 **)param_value);
+            return SET_D3D_STATE(effect, SetTexture, unit, *(IDirect3DBaseTexture9 **)param_value);
         }
         case SC_TEXTURESTAGE:
             TRACE("%s, stage %u, value %u.\n", state_table[state->operation].name, state->index, *(DWORD *)param_value);
-            return IDirect3DDevice9_SetTextureStageState(device, state->index,
-                    state_table[state->operation].op, *(DWORD *)param_value);
+            return SET_D3D_STATE(effect, SetTextureStageState, state->index,
+                        state_table[state->operation].op, *(DWORD *)param_value);
         case SC_SETSAMPLER:
         {
             struct d3dx_sampler *sampler;
@@ -2918,13 +2919,13 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
 
             sampler = parent_index == ~0u ? state->index : parent_index;
             TRACE("%s, sampler %u, value %u.\n", state_table[state->operation].name, sampler, *(DWORD *)param_value);
-            return IDirect3DDevice9_SetSamplerState(device, sampler, state_table[state->operation].op,
+            return SET_D3D_STATE(effect, SetSamplerState, sampler, state_table[state->operation].op,
                     *(DWORD *)param_value);
         }
         case SC_VERTEXSHADER:
             TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
             if ((update_all || param_dirty)
-                    && FAILED(hr = IDirect3DDevice9_SetVertexShader(device,
+                    && FAILED(hr = SET_D3D_STATE(effect, SetVertexShader,
                     *(IDirect3DVertexShader9 **)param_value)))
                 ERR("Could not set vertex shader, hr %#x.\n", hr);
             else if (*(IDirect3DVertexShader9 **)param_value)
@@ -2933,7 +2934,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
         case SC_PIXELSHADER:
             TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
             if ((update_all || param_dirty)
-                    && FAILED(hr = IDirect3DDevice9_SetPixelShader(device,
+                    && FAILED(hr = SET_D3D_STATE(effect, SetPixelShader,
                     *(IDirect3DPixelShader9 **)param_value)))
                 ERR("Could not set pixel shader, hr %#x.\n", hr);
             else if (*(IDirect3DPixelShader9 **)param_value)
@@ -2941,18 +2942,19 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
             return hr;
         case SC_TRANSFORM:
             TRACE("%s, state %u.\n", state_table[state->operation].name, state->index);
-            return IDirect3DDevice9_SetTransform(device, state_table[state->operation].op + state->index,
+            return SET_D3D_STATE(effect, SetTransform, state_table[state->operation].op + state->index,
                     (D3DMATRIX *)param_value);
         case SC_LIGHTENABLE:
             TRACE("%s, index %u, value %u.\n", state_table[state->operation].name, state->index, *(BOOL *)param_value);
-            return IDirect3DDevice9_LightEnable(device, state->index, *(BOOL *)param_value);
+            return SET_D3D_STATE(effect, LightEnable, state->index, *(BOOL *)param_value);
         case SC_LIGHT:
         {
             TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
                     state_table[state->operation].op);
             d3dx9_set_light_parameter(state_table[state->operation].op,
                     &effect->current_light[state->index], param_value);
-            return IDirect3DDevice9_SetLight(device, state->index, &effect->current_light[state->index]);
+            effect->light_updated[state->index] = TRUE;
+            return D3D_OK;
         }
         case SC_MATERIAL:
         {
@@ -2960,15 +2962,16 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
                     state_table[state->operation].op);
             d3dx9_set_material_parameter(state_table[state->operation].op,
                     &effect->current_material, param_value);
-            return IDirect3DDevice9_SetMaterial(device, &effect->current_material);
+            effect->material_updated = TRUE;
+            return D3D_OK;
         }
         case SC_NPATCHMODE:
             TRACE("%s, nsegments %f.\n", state_table[state->operation].name, *(float *)param_value);
-            return IDirect3DDevice9_SetNPatchMode(device, *(float *)param_value);
+            return SET_D3D_STATE(effect, SetNPatchMode, *(float *)param_value);
         case SC_SHADERCONST:
             TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
                 state_table[state->operation].op);
-            return d3dx_set_shader_const_state(device, state_table[state->operation].op, state->index,
+            return d3dx_set_shader_const_state(effect, state_table[state->operation].op, state->index,
                 param, param_value);
         default:
             FIXME("%s not handled.\n", state_table[state->operation].name);
@@ -2981,13 +2984,13 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
 {
     unsigned int i;
     HRESULT ret;
+    HRESULT hr;
 
     TRACE("effect %p, pass %p, state_count %u.\n", effect, pass, pass->state_count);
 
     ret = D3D_OK;
-    for (i = 0; i < pass->state_count; i++)
+    for (i = 0; i < pass->state_count; ++i)
     {
-        HRESULT hr;
 
         if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], ~0u, update_all)))
         {
@@ -2995,6 +2998,25 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
             ret = hr;
         }
     }
+    for (i = 0; i < ARRAY_SIZE(effect->current_light); ++i)
+    {
+        if (effect->light_updated[i]
+                && FAILED(hr = SET_D3D_STATE(effect, SetLight, i, &effect->current_light[i])))
+        {
+            WARN("Error setting light, hr %#x.\n", hr);
+            ret = hr;
+        }
+        effect->light_updated[i] = FALSE;
+    }
+
+    if (effect->material_updated
+            && FAILED(hr = SET_D3D_STATE(effect, SetMaterial, &effect->current_material)))
+    {
+        WARN("Error setting material, hr %#x.\n", hr);
+        ret = hr;
+    }
+    effect->material_updated = FALSE;
+
     clear_dirty_params(&effect->base_effect);
     return ret;
 }
diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index 6cd1d60..896aca5 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -1302,8 +1302,8 @@ HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx
     return D3D_OK;
 }
 
-static HRESULT set_shader_constants_device(struct IDirect3DDevice9 *device, struct d3dx_regstore *rs,
-        D3DXPARAMETER_TYPE type, enum pres_reg_tables table)
+static HRESULT set_shader_constants_device(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
+        struct d3dx_regstore *rs, D3DXPARAMETER_TYPE type, enum pres_reg_tables table)
 {
     unsigned int start, count;
     void *ptr;
@@ -1328,13 +1328,13 @@ static HRESULT set_shader_constants_device(struct IDirect3DDevice9 *device, stru
             switch(table)
             {
                 case PRES_REGTAB_OCONST:
-                    hr = IDirect3DDevice9_SetVertexShaderConstantF(device, start, (const float *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetVertexShaderConstantF, start, (const float *)ptr, count);
                     break;
                 case PRES_REGTAB_OICONST:
-                    hr = IDirect3DDevice9_SetVertexShaderConstantI(device, start, (const int *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetVertexShaderConstantI, start, (const int *)ptr, count);
                     break;
                 case PRES_REGTAB_OBCONST:
-                    hr = IDirect3DDevice9_SetVertexShaderConstantB(device, start, (const BOOL *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetVertexShaderConstantB, start, (const BOOL *)ptr, count);
                     break;
                 default:
                     FIXME("Unexpected register table %u.\n", table);
@@ -1346,13 +1346,13 @@ static HRESULT set_shader_constants_device(struct IDirect3DDevice9 *device, stru
             switch(table)
             {
                 case PRES_REGTAB_OCONST:
-                    hr = IDirect3DDevice9_SetPixelShaderConstantF(device, start, (const float *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetPixelShaderConstantF, start, (const float *)ptr, count);
                     break;
                 case PRES_REGTAB_OICONST:
-                    hr = IDirect3DDevice9_SetPixelShaderConstantI(device, start, (const int *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetPixelShaderConstantI, start, (const int *)ptr, count);
                     break;
                 case PRES_REGTAB_OBCONST:
-                    hr = IDirect3DDevice9_SetPixelShaderConstantB(device, start, (const BOOL *)ptr, count);
+                    hr = SET_D3D_STATE_(manager, device, SetPixelShaderConstantB, start, (const BOOL *)ptr, count);
                     break;
                 default:
                     FIXME("Unexpected register table %u.\n", table);
@@ -1376,8 +1376,8 @@ static HRESULT set_shader_constants_device(struct IDirect3DDevice9 *device, stru
     return result;
 }
 
-HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device, struct d3dx_param_eval *peval,
-        BOOL update_all)
+HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
+        struct d3dx_param_eval *peval, BOOL update_all)
 {
     static const enum pres_reg_tables set_tables[] =
             {PRES_REGTAB_OCONST, PRES_REGTAB_OICONST, PRES_REGTAB_OBCONST};
@@ -1399,7 +1399,7 @@ HRESULT d3dx_param_eval_set_shader_constants(struct IDirect3DDevice9 *device, st
     result = D3D_OK;
     for (i = 0; i < ARRAY_SIZE(set_tables); ++i)
     {
-        if (FAILED(hr = set_shader_constants_device(device, rs, peval->param_type, set_tables[i])))
+        if (FAILED(hr = set_shader_constants_device(manager, device, rs, peval->param_type, set_tables[i])))
             result = hr;
     }
     return result;
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 6da7686..70e1ccf 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -5653,14 +5653,12 @@ static void test_effect_state_manager(IDirect3DDevice9 *device)
     qsort(state_manager->update_record, state_manager->update_record_count,
             sizeof(*state_manager->update_record), compare_update_record);
 
-    todo_wine
     ok(ARRAY_SIZE(expected_updates) == state_manager->update_record_count,
             "Expected %u update records, got %u.\n", ARRAY_SIZE(expected_updates),
             state_manager->update_record_count);
     n = min(ARRAY_SIZE(expected_updates), state_manager->update_record_count);
     for (i = 0; i < n; ++i)
     {
-        todo_wine
         ok(!memcmp(&expected_updates[i], &state_manager->update_record[i],
                 sizeof(expected_updates[i])),
                 "Update record mismatch, expected %s, %u, %u, got %s, %u, %u.\n",
-- 
2.9.3




More information about the wine-patches mailing list