[v8 5/6] d3dx9: Implement array selectors in effect.

Paul Gofman gofmanp at gmail.com
Tue Mar 29 10:22:45 CDT 2016


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
 dlls/d3dx9_36/effect.c       | 89 +++++++++++++++++++++++++++-----------------
 dlls/d3dx9_36/tests/effect.c |  6 +--
 2 files changed, 58 insertions(+), 37 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 78b34bc..2dbb610 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -2510,8 +2510,38 @@ static HRESULT d3dx9_get_param_value_ptr(struct ID3DXEffectImpl *effect, struct
             *out_param = param;
             return D3D_OK;
         case ST_ARRAY_SELECTOR:
-            FIXME("Array selector.\n");
-            break;
+        {
+            struct d3dx_parameter array_idx_par;
+            unsigned int array_idx;
+            unsigned int *idx_value;
+            HRESULT hr;
+
+            if (!param->param_eval)
+            {
+                FIXME("Preshader structure is null.\n");
+                return D3DERR_INVALIDCALL;
+            }
+            memset(&array_idx_par, 0, sizeof(array_idx_par));
+            array_idx_par.data = &array_idx;
+            array_idx_par.type = D3DXPT_INT;
+            array_idx_par.bytes = sizeof(array_idx);
+            array_idx_par.rows = array_idx_par.columns = 1;
+            if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_par, (void **)&idx_value)))
+                return hr;
+
+            param = param->referenced_param;
+            TRACE("Array index %u.\n", *idx_value);
+            if (*idx_value >= param->element_count)
+            {
+                ERR("Computed array index %u is out of bound %u.\n", *idx_value, param->element_count);
+                return D3DERR_INVALIDCALL;
+            }
+            param = &param->members[*idx_value];
+
+            *param_value = param->data;
+            *out_param = param;
+            return D3D_OK;
+        }
         case ST_FXLC:
             if (param->param_eval)
             {
@@ -2657,15 +2687,15 @@ static HRESULT d3dx_set_shader_const_state(IDirect3DDevice9 *device, enum SHADER
         {D3DXPT_BOOL,  sizeof(BOOL),      "SCT_PSBOOL"},
         {D3DXPT_INT,   sizeof(int) * 4,   "SCT_PSINT"},
     };
-    UINT nelem;
+    unsigned int element_count;
 
     if (op < 0 || op > SCT_PSINT)
     {
         FIXME("Unknown op %u.\n", op);
         return D3DERR_INVALIDCALL;
     }
-    nelem = param->bytes / const_tbl[op].elem_size;
-    TRACE("%s, index %u, %u elements.\n", const_tbl[op].name, index, nelem);
+    element_count = param->bytes / const_tbl[op].elem_size;
+    TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
     if (param->type != const_tbl[op].type)
     {
         FIXME("Unexpected param type %u.\n", param->type);
@@ -2680,17 +2710,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, nelem);
+            return IDirect3DDevice9_SetVertexShaderConstantF(device, index, (const float *)value_ptr, element_count);
         case SCT_VSBOOL:
-            return IDirect3DDevice9_SetVertexShaderConstantB(device, index, (const BOOL *)value_ptr, nelem);
+            return IDirect3DDevice9_SetVertexShaderConstantB(device, index, (const BOOL *)value_ptr, element_count);
         case SCT_VSINT:
-            return IDirect3DDevice9_SetVertexShaderConstantI(device, index, (const int *)value_ptr, nelem);
+            return IDirect3DDevice9_SetVertexShaderConstantI(device, index, (const int *)value_ptr, element_count);
         case SCT_PSFLOAT:
-            return IDirect3DDevice9_SetPixelShaderConstantF(device, index, (const float *)value_ptr, nelem);
+            return IDirect3DDevice9_SetPixelShaderConstantF(device, index, (const float *)value_ptr, element_count);
         case SCT_PSBOOL:
-            return IDirect3DDevice9_SetPixelShaderConstantB(device, index, (const BOOL *)value_ptr, nelem);
+            return IDirect3DDevice9_SetPixelShaderConstantB(device, index, (const BOOL *)value_ptr, element_count);
         case SCT_PSINT:
-            return IDirect3DDevice9_SetPixelShaderConstantI(device, index, (const int *)value_ptr, nelem);
+            return IDirect3DDevice9_SetPixelShaderConstantI(device, index, (const int *)value_ptr, element_count);
     }
     return D3D_OK;
 }
@@ -2704,9 +2734,10 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
     HRESULT hr;
 
     TRACE("operation %u, index %u, type %u.\n", state->operation, state->index, state->type);
-    hr = d3dx9_get_param_value_ptr(effect, pass, state, &param_value, &param);
-    if (FAILED(hr))
-        return hr;
+    if (FAILED(hr = d3dx9_get_param_value_ptr(effect, pass, state, &param_value, &param)))
+        /* Native d3dx returns OK from BeginPass or Commit involving out of bound array
+            access, and does not touch affected state. */
+        return D3D_OK;
 
     switch (state_table[state->operation].class)
     {
@@ -2742,8 +2773,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
             ret = D3D_OK;
             for (i = 0; i < sampler->state_count; i++)
             {
-                hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index);
-                if (FAILED(hr))
+                if (FAILED(hr = d3dx9_apply_state(effect, pass, &sampler->states[i], state->index)))
                     ret = hr;
             }
             return ret;
@@ -2759,15 +2789,13 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
         }
         case SC_VERTEXSHADER:
             TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DVertexShader9 **)param_value);
-            hr = IDirect3DDevice9_SetVertexShader(device, *(IDirect3DVertexShader9 **)param_value);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DDevice9_SetVertexShader(device, *(IDirect3DVertexShader9 **)param_value)))
                 ERR("Could not set vertex shader, hr %#x.\n", hr);
             FIXME("Not executing preshader and not setting constants.\n");
             return hr;
         case SC_PIXELSHADER:
             TRACE("%s, shader %p.\n", state_table[state->operation].name, *(IDirect3DPixelShader9 **)param_value);
-            hr = IDirect3DDevice9_SetPixelShader(device, *(IDirect3DPixelShader9 **)param_value);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DDevice9_SetPixelShader(device, *(IDirect3DPixelShader9 **)param_value)))
                 ERR("Could not set pixel shader, hr %#x.\n", hr);
             FIXME("Not executing preshader and not setting constants.\n");
             return hr;
@@ -2784,8 +2812,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
 
             TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
                     state_table[state->operation].op);
-            hr = IDirect3DDevice9_GetLight(device, state->index, &light);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DDevice9_GetLight(device, state->index, &light)))
             {
                 WARN("Could not get light, hr %#x.\n", hr);
                 memset(&light, 0, sizeof(light));
@@ -2799,8 +2826,7 @@ static HRESULT d3dx9_apply_state(struct ID3DXEffectImpl *effect, struct d3dx_pas
 
             TRACE("%s, index %u, op %u.\n", state_table[state->operation].name, state->index,
                     state_table[state->operation].op);
-            hr = IDirect3DDevice9_GetMaterial(device, &material);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DDevice9_GetMaterial(device, &material)))
             {
                 WARN("Could not get material, hr %#x.\n", hr);
                 memset(&material, 0, sizeof(material));
@@ -2835,8 +2861,7 @@ static HRESULT d3dx9_apply_pass_states(struct ID3DXEffectImpl *effect, struct d3
     {
         HRESULT hr;
 
-        hr = d3dx9_apply_state(effect, pass, &pass->states[i], -1);
-        if (FAILED(hr))
+        if (FAILED(hr = d3dx9_apply_state(effect, pass, &pass->states[i], -1)))
         {
             WARN("Error applying state, hr %#x.\n", hr);
             ret = hr;
@@ -3520,17 +3545,14 @@ static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DW
 
             if (!technique->saved_state)
             {
-                hr = IDirect3DDevice9_BeginStateBlock(effect->device);
-                if (FAILED(hr))
+                if (FAILED(hr = IDirect3DDevice9_BeginStateBlock(effect->device)))
                     ERR("BeginStateBlock failed, hr %#x.\n", hr);
                 for (i = 0; i < technique->pass_count; i++)
                     d3dx9_apply_pass_states(effect, &technique->passes[i]);
-                hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state);
-                if (FAILED(hr))
+                if (FAILED(hr = IDirect3DDevice9_EndStateBlock(effect->device, &technique->saved_state)))
                     ERR("EndStateBlock failed, hr %#x.\n", hr);
             }
-            hr = IDirect3DStateBlock9_Capture(technique->saved_state);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DStateBlock9_Capture(technique->saved_state)))
                 ERR("StateBlock Capture failed, hr %#x.\n", hr);
         }
 
@@ -3616,8 +3638,7 @@ static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect *iface)
 
         if (technique && technique->saved_state)
         {
-            hr = IDirect3DStateBlock9_Apply(technique->saved_state);
-            if (FAILED(hr))
+            if (FAILED(hr = IDirect3DStateBlock9_Apply(technique->saved_state)))
                 ERR("State block apply failed, hr %#x.\n", hr);
         }
         else
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 2bc2938..7d74d46 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -3848,7 +3848,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetVector(effect, par, &fvect2);
     ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
     hr = effect->lpVtbl->BeginPass(effect, 1);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
@@ -3860,7 +3860,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
     hr = IDirect3DVertexShader9_GetFunction(vshader, byte_code, &byte_code_size);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(byte_code_size > 1, "Got unexpected byte code size %u.\n", byte_code_size);
-    todo_wine ok(!memcmp(byte_code,
+    ok(!memcmp(byte_code,
             &test_effect_preshader_effect_blob[TEST_EFFECT_PRESHADER_VSHADER_POS +
             TEST_EFFECT_PRESHADER_VSHADER_LEN], byte_code_size),
             "Incorrect shader selected.\n");
@@ -3873,7 +3873,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetVector(effect, par, &fvect1);
     ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(!vshader, "Incorrect shader selected.\n");
-- 
2.5.5




More information about the wine-patches mailing list