[PATCH 1/5] d3d10/effect: Use shader reflection to return output signature description.

Nikolay Sivov nsivov at codeweavers.com
Mon Aug 23 03:23:03 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d10/d3d10_private.h |  2 +-
 dlls/d3d10/effect.c        | 54 ++++++++------------------------------
 dlls/d3d10/tests/effect.c  | 37 +++++++++++++++++++++++++-
 3 files changed, 48 insertions(+), 45 deletions(-)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 249d4ea384a..359c1f017f7 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -106,7 +106,7 @@ struct d3d10_effect_shader_signature
 struct d3d10_effect_shader_variable
 {
     struct d3d10_effect_shader_signature input_signature;
-    struct d3d10_effect_shader_signature output_signature;
+    ID3D10ShaderReflection *reflection;
     union
     {
         ID3D10VertexShader *vs;
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 520f816098f..3f0916e60d5 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -599,16 +599,12 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag
     switch(tag)
     {
         case TAG_ISGN:
-        case TAG_OSGN:
         {
             /* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */
             UINT size = 44 + data_size;
-            struct d3d10_effect_shader_signature *sig;
+            struct d3d10_effect_shader_signature *sig = &s->input_signature;
             char *ptr;
 
-            if (tag == TAG_ISGN) sig = &s->input_signature;
-            else sig = &s->output_signature;
-
             if (!(sig->signature = heap_alloc_zero(size)))
             {
                 ERR("Failed to allocate input signature data\n");
@@ -666,28 +662,22 @@ static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const
     struct d3d10_effect_shader_variable *sv = &v->u.shader;
     struct d3d10_effect_shader_resource *sr;
     D3D10_SHADER_INPUT_BIND_DESC bind_desc;
-    ID3D10ShaderReflection *reflection;
     struct d3d10_effect_variable *var;
     D3D10_SHADER_DESC desc;
     unsigned int i, y;
-    HRESULT hr;
-
-    if (FAILED(hr = D3D10ReflectShader(data, data_size, &reflection)))
-        return hr;
 
-    reflection->lpVtbl->GetDesc(reflection, &desc);
+    sv->reflection->lpVtbl->GetDesc(sv->reflection, &desc);
     sv->resource_count = desc.BoundResources;
 
     if (!(sv->resources = heap_calloc(sv->resource_count, sizeof(*sv->resources))))
     {
         ERR("Failed to allocate shader resource binding information memory.\n");
-        reflection->lpVtbl->Release(reflection);
         return E_OUTOFMEMORY;
     }
 
     for (i = 0; i < desc.BoundResources; ++i)
     {
-        reflection->lpVtbl->GetResourceBindingDesc(reflection, i, &bind_desc);
+        sv->reflection->lpVtbl->GetResourceBindingDesc(sv->reflection, i, &bind_desc);
         sr = &sv->resources[i];
 
         sr->in_type = bind_desc.Type;
@@ -731,7 +721,6 @@ static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const
         if (!sr->variable)
         {
             WARN("Failed to find shader resource.\n");
-            reflection->lpVtbl->Release(reflection);
             return E_FAIL;
         }
     }
@@ -774,6 +763,9 @@ static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offse
     /* We got a shader VertexShader vs = NULL, so it is fine to skip this. */
     if (!dxbc_size) return S_OK;
 
+    if (FAILED(hr = D3D10ReflectShader(ptr, dxbc_size, &v->u.shader.reflection)))
+        return hr;
+
     if (FAILED(hr = get_fx10_shader_resources(v, ptr, dxbc_size)))
         return hr;
 
@@ -2747,8 +2739,9 @@ static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o)
 static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_variable *s,
         D3D10_SHADER_VARIABLE_TYPE type)
 {
+    if (s->reflection)
+        s->reflection->lpVtbl->Release(s->reflection);
     shader_free_signature(&s->input_signature);
-    shader_free_signature(&s->output_signature);
 
     switch (type)
     {
@@ -7068,7 +7061,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
 {
     struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
     struct d3d10_effect_shader_variable *s;
-    D3D10_SIGNATURE_PARAMETER_DESC *d;
 
     TRACE("iface %p, shader_index %u, element_index %u, desc %p\n",
             iface, shader_index, element_index, desc);
@@ -7087,35 +7079,11 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
     }
 
     s = &v->effect->used_shaders[shader_index]->u.shader;
-    if (!s->output_signature.signature)
-    {
-        WARN("No shader signature\n");
-        return D3DERR_INVALIDCALL;
-    }
-
-    /* Check desc for NULL, this crashes on W7/DX10 */
-    if (!desc)
-    {
-        WARN("This should crash on W7/DX10!\n");
-        return E_FAIL;
-    }
-
-    if (element_index >= s->output_signature.element_count)
-    {
-        WARN("Invalid element index specified\n");
-        return E_INVALIDARG;
-    }
 
-    d = &s->output_signature.elements[element_index];
-    desc->SemanticName = d->SemanticName;
-    desc->SemanticIndex  =  d->SemanticIndex;
-    desc->SystemValueType =  d->SystemValueType;
-    desc->ComponentType =  d->ComponentType;
-    desc->Register =  d->Register;
-    desc->ReadWriteMask  =  d->ReadWriteMask;
-    desc->Mask =  d->Mask;
+    if (!s->reflection)
+        return D3DERR_INVALIDCALL;
 
-    return S_OK;
+    return s->reflection->lpVtbl->GetOutputParameterDesc(s->reflection, element_index, desc);
 }
 
 
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c
index 9a217993e7e..df0d1a99ef4 100644
--- a/dlls/d3d10/tests/effect.c
+++ b/dlls/d3d10/tests/effect.c
@@ -23,6 +23,8 @@
 
 #include <float.h>
 
+#define D3DERR_INVALIDCALL 0x8876086c
+
 static ID3D10Device *create_device(void)
 {
     ID3D10Device *device;
@@ -2796,8 +2798,9 @@ static void test_effect_local_shader(void)
     D3D10_EFFECT_TYPE_DESC typedesc;
     D3D10_EFFECT_DESC effect_desc;
     ID3D10EffectShaderVariable *null_shader, *null_anon_vs, *null_anon_ps, *null_anon_gs,
-        *p3_anon_vs, *p3_anon_ps, *p3_anon_gs, *p6_vs, *p6_ps, *p6_gs, *gs;
+        *p3_anon_vs, *p3_anon_ps, *p3_anon_gs, *p6_vs, *p6_ps, *p6_gs, *gs, *ps, *vs;
     D3D10_EFFECT_SHADER_DESC shaderdesc;
+    D3D10_SIGNATURE_PARAMETER_DESC sign;
     ID3D10Device *device;
     ULONG refcount;
 
@@ -3648,6 +3651,38 @@ todo_wine
                 shaderdesc.SODecl);
     }
 
+    /* Output signature description */
+    v = effect->lpVtbl->GetVariableByName(effect, "p");
+    ps = v->lpVtbl->AsShader(v);
+
+    hr = ps->lpVtbl->GetOutputSignatureElementDesc(ps, 0, 0, &sign);
+todo_wine
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+        ok(!strcmp(sign.SemanticName, "SV_Target"), "Unexpected semantic %s.\n", sign.SemanticName);
+
+    v = effect->lpVtbl->GetVariableByName(effect, "v");
+    vs = v->lpVtbl->AsShader(v);
+
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 0, 0, &sign);
+todo_wine
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+        ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
+
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 1, 0, &sign);
+todo_wine
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+        ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
+
+    /* NULL shader variable */
+    v = effect->lpVtbl->GetVariableByName(effect, "v0");
+    vs = v->lpVtbl->AsShader(v);
+
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 0, 0, &sign);
+    ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
+
     effect->lpVtbl->Release(effect);
 
     refcount = ID3D10Device_Release(device);
-- 
2.32.0




More information about the wine-devel mailing list