[PATCH] d3dx9: Return shader functions in d3dx9_base_effect_get_pass_desc().

Matteo Bruni mbruni at codeweavers.com
Thu May 4 17:03:50 CDT 2017


From: Paul Gofman <gofmanp at gmail.com>

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
 dlls/d3dx9_36/effect.c       | 210 +++++++++++++++++++++++++------------------
 dlls/d3dx9_36/tests/effect.c |   9 +-
 2 files changed, 125 insertions(+), 94 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 1a14edb..864c390 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -1019,24 +1019,139 @@ static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *ba
     return D3D_OK;
 }
 
+static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
+        void **param_value, struct d3dx_parameter **out_param,
+        BOOL update_all, BOOL *param_dirty)
+{
+    struct d3dx_parameter *param = &state->parameter;
+
+    *param_value = NULL;
+    *out_param = NULL;
+    *param_dirty = FALSE;
+
+    switch (state->type)
+    {
+        case ST_PARAMETER:
+            param = param->referenced_param;
+            *param_dirty = is_param_dirty(param);
+            /* fallthrough */
+        case ST_CONSTANT:
+            *out_param = param;
+            *param_value = param->data;
+            return D3D_OK;
+        case ST_ARRAY_SELECTOR:
+        {
+            unsigned int array_idx;
+            static const struct d3dx_parameter array_idx_param =
+                {"", NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, sizeof(array_idx)};
+            HRESULT hr;
+            struct d3dx_parameter *ref_param, *selected_param;
+
+            if (!param->param_eval)
+            {
+                FIXME("Preshader structure is null.\n");
+                return D3DERR_INVALIDCALL;
+            }
+            if (update_all || is_param_eval_input_dirty(param->param_eval))
+            {
+                if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param,
+                        &array_idx, update_all)))
+                    return hr;
+            }
+            else
+            {
+                array_idx = state->index;
+            }
+            ref_param = param->referenced_param;
+            TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
+                    ref_param->element_count);
+
+            if (array_idx >= ref_param->element_count)
+            {
+                WARN("Computed array index %u is larger than array size %u.\n",
+                        array_idx, ref_param->element_count);
+                return E_FAIL;
+            }
+            selected_param = &ref_param->members[array_idx];
+            *param_dirty = state->index != array_idx || is_param_dirty(selected_param);
+            state->index = array_idx;
+
+            *param_value = selected_param->data;
+            *out_param = selected_param;
+            return D3D_OK;
+        }
+        case ST_FXLC:
+            if (param->param_eval)
+            {
+                *out_param = param;
+                *param_value = param->data;
+                if (update_all || is_param_eval_input_dirty(param->param_eval))
+                {
+                    *param_dirty = TRUE;
+                    return d3dx_evaluate_parameter(param->param_eval, param, *param_value, update_all);
+                }
+                else
+                    return D3D_OK;
+            }
+            else
+            {
+                FIXME("No preshader for FXLC parameter.\n");
+                return D3DERR_INVALIDCALL;
+            }
+    }
+    return E_NOTIMPL;
+}
+
 static HRESULT d3dx9_base_effect_get_pass_desc(struct d3dx9_base_effect *base,
-        D3DXHANDLE pass, D3DXPASS_DESC *desc)
+        D3DXHANDLE pass_handle, D3DXPASS_DESC *desc)
 {
-    struct d3dx_pass *p = get_valid_pass(base, pass);
+    struct d3dx_pass *pass = get_valid_pass(base, pass_handle);
+    unsigned int i;
 
-    if (!desc || !p)
+    if (!desc || !pass)
     {
         WARN("Invalid argument specified.\n");
         return D3DERR_INVALIDCALL;
     }
 
-    desc->Name = p->name;
-    desc->Annotations = p->annotation_count;
+    desc->Name = pass->name;
+    desc->Annotations = pass->annotation_count;
 
-    FIXME("Pixel shader and vertex shader are not supported, yet.\n");
     desc->pVertexShaderFunction = NULL;
     desc->pPixelShaderFunction = NULL;
 
+    if (base->flags & D3DXFX_NOT_CLONEABLE)
+        return D3D_OK;
+
+    for (i = 0; i < pass->state_count; ++i)
+    {
+        struct d3dx_state *state = &pass->states[i];
+
+        if (state_table[state->operation].class == SC_VERTEXSHADER
+                || state_table[state->operation].class == SC_PIXELSHADER)
+        {
+            struct d3dx_parameter *param;
+            void *param_value;
+            BOOL param_dirty;
+            HRESULT hr;
+
+            if (FAILED(hr = d3dx9_get_param_value_ptr(pass, &pass->states[i], &param_value, &param,
+                    TRUE, &param_dirty)))
+                return hr;
+
+            if (!param->object_id)
+            {
+                FIXME("Zero object ID in shader parameter.\n");
+                return E_FAIL;
+            }
+
+            if (state_table[state->operation].class == SC_VERTEXSHADER)
+                desc->pVertexShaderFunction = base->objects[param->object_id].data;
+            else
+                desc->pPixelShaderFunction = base->objects[param->object_id].data;
+        }
+    }
+
     return D3D_OK;
 }
 
@@ -2579,89 +2694,6 @@ static HRESULT d3dx9_base_effect_set_array_range(struct d3dx9_base_effect *base,
     return E_NOTIMPL;
 }
 
-static HRESULT d3dx9_get_param_value_ptr(struct d3dx_pass *pass, struct d3dx_state *state,
-        void **param_value, struct d3dx_parameter **out_param,
-        BOOL update_all, BOOL *param_dirty)
-{
-    struct d3dx_parameter *param = &state->parameter;
-
-    *param_value = NULL;
-    *out_param = NULL;
-    *param_dirty = FALSE;
-
-    switch (state->type)
-    {
-        case ST_PARAMETER:
-            param = param->referenced_param;
-            *param_dirty = is_param_dirty(param);
-            /* fallthrough */
-        case ST_CONSTANT:
-            *out_param = param;
-            *param_value = param->data;
-            return D3D_OK;
-        case ST_ARRAY_SELECTOR:
-        {
-            unsigned int array_idx;
-            static const struct d3dx_parameter array_idx_param =
-                {"", NULL, NULL, NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, sizeof(array_idx)};
-            HRESULT hr;
-            struct d3dx_parameter *ref_param, *selected_param;
-
-            if (!param->param_eval)
-            {
-                FIXME("Preshader structure is null.\n");
-                return D3DERR_INVALIDCALL;
-            }
-            if (update_all || is_param_eval_input_dirty(param->param_eval))
-            {
-                if (FAILED(hr = d3dx_evaluate_parameter(param->param_eval, &array_idx_param,
-                        &array_idx, update_all)))
-                    return hr;
-            }
-            else
-            {
-                array_idx = state->index;
-            }
-            ref_param = param->referenced_param;
-            TRACE("Array index %u, stored array index %u, element_count %u.\n", array_idx, state->index,
-                    ref_param->element_count);
-
-            if (array_idx >= ref_param->element_count)
-            {
-                WARN("Computed array index %u is larger than array size %u.\n",
-                        array_idx, ref_param->element_count);
-                return E_FAIL;
-            }
-            selected_param = &ref_param->members[array_idx];
-            *param_dirty = state->index != array_idx || is_param_dirty(selected_param);
-            state->index = array_idx;
-
-            *param_value = selected_param->data;
-            *out_param = selected_param;
-            return D3D_OK;
-        }
-        case ST_FXLC:
-            if (param->param_eval)
-            {
-                *out_param = param;
-                *param_value = param->data;
-                if (update_all || is_param_eval_input_dirty(param->param_eval))
-                {
-                    *param_dirty = TRUE;
-                    return d3dx_evaluate_parameter(param->param_eval, param, *param_value, update_all);
-                }
-                else
-                    return D3D_OK;
-            }
-            else
-            {
-                FIXME("No preshader for FXLC parameter.\n");
-                return D3DERR_INVALIDCALL;
-            }
-    }
-    return E_NOTIMPL;
-}
-
 static void d3dx9_set_light_parameter(enum LIGHT_TYPE op, D3DLIGHT9 *light, void *value)
 {
     static const struct
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 8b2fb5d..f3bc9e3 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -6227,7 +6227,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
 
     hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
-    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, TRUE);
+    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE);
 
     fvect.x = fvect.y = fvect.w = 0.0f;
     fvect.z = 0.0f;
@@ -6238,21 +6238,19 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(!desc.pPixelShaderFunction, "Unexpected non null desc.pPixelShaderFunction.\n");
 
-    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, TRUE);
+    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, FALSE);
 
     fvect.z = 3.0f;
     hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
-    todo_wine
     ok(hr == E_FAIL, "Got result %#x.\n", hr);
     ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
 
     /* Repeating call to confirm GetPassDesc() returns same error on the second call,
      * as it is not the case sometimes for BeginPass() with out of bound access. */
     hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
-    todo_wine
     ok(hr == E_FAIL, "Got result %#x.\n", hr);
     ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
 
@@ -6263,6 +6261,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+    todo_wine
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, TRUE);
@@ -6271,7 +6270,7 @@ static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
     hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
-    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, TRUE);
+    test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE);
 
     effect->lpVtbl->Release(effect);
 
-- 
2.10.2




More information about the wine-patches mailing list