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

Paul Gofman gofmanp at gmail.com
Wed May 3 17:04:23 CDT 2017


Fixes #36820, #34551.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
 dlls/d3dx9_36/effect.c       | 47 ++++++++++++++++++++++++++++++++++++++------
 dlls/d3dx9_36/tests/effect.c |  9 ++++-----
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 1a14edb..4dda07d 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -209,6 +209,9 @@ static struct d3dx_parameter *get_annotation_by_name(UINT count, struct d3dx_par
 static HRESULT d3dx9_parse_state(struct d3dx9_base_effect *base, struct d3dx_state *state,
         const char *data, const char **ptr, struct d3dx_object *objects);
 static void free_parameter(struct d3dx_parameter *param, BOOL element, BOOL child);
+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);
 
 typedef BOOL (*walk_parameter_dep_func)(void *data, struct d3dx_parameter *param);
 
@@ -1020,23 +1023,55 @@ static HRESULT d3dx9_base_effect_get_technique_desc(struct d3dx9_base_effect *ba
 }
 
 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)
+        {
+            HRESULT hr;
+            struct d3dx_parameter *param;
+            void *param_value;
+            BOOL param_dirty;
+
+            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;
 }
 
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 6d3d237..9823788 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -6231,7 +6231,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;
@@ -6242,21 +6242,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");
 
@@ -6267,6 +6265,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);
@@ -6275,7 +6274,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.9.3




More information about the wine-patches mailing list