[PATCH 2/5] d3d10/effect: Fix indexing in GetOutputSignatureElementDesc().

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


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d10/effect.c       | 52 ++++++++++++++++++++++++++++-----------
 dlls/d3d10/tests/effect.c | 26 +++++++++++++-------
 2 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 3f0916e60d5..e261e5a7cd7 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -6999,6 +6999,43 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetPixelShader(
     return S_OK;
 }
 
+static HRESULT d3d10_get_shader_variable_signature(struct d3d10_effect_variable *v,
+        UINT shader_index, UINT element_index, BOOL output, D3D10_SIGNATURE_PARAMETER_DESC *desc)
+{
+    struct d3d10_effect_shader_variable *s;
+    unsigned int i;
+
+    if (v->type->element_count)
+        v = &v->elements[0];
+
+    if (shader_index == 0)
+    {
+        s = &v->u.shader;
+    }
+    else
+    {
+        /* Index is used as an offset from this variable. */
+
+        for (i = 0; i < v->effect->used_shader_count; ++i)
+        {
+            if (v == v->effect->used_shaders[i]) break;
+        }
+
+        if (i + shader_index >= v->effect->used_shader_count)
+        {
+            WARN("This should crash!\n");
+            return E_FAIL;
+        }
+
+        s = &v->effect->used_shaders[i + shader_index]->u.shader;
+    }
+
+    if (!s->reflection)
+        return D3DERR_INVALIDCALL;
+
+    return s->reflection->lpVtbl->GetOutputParameterDesc(s->reflection, element_index, desc);
+}
+
 static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureElementDesc(
         ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index,
         D3D10_SIGNATURE_PARAMETER_DESC *desc)
@@ -7060,7 +7097,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
         D3D10_SIGNATURE_PARAMETER_DESC *desc)
 {
     struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(iface);
-    struct d3d10_effect_shader_variable *s;
 
     TRACE("iface %p, shader_index %u, element_index %u, desc %p\n",
             iface, shader_index, element_index, desc);
@@ -7071,19 +7107,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignature
         return E_FAIL;
     }
 
-    /* Check shader_index, this crashes on W7/DX10 */
-    if (shader_index >= v->effect->used_shader_count)
-    {
-        WARN("This should crash on W7/DX10!\n");
-        return E_FAIL;
-    }
-
-    s = &v->effect->used_shaders[shader_index]->u.shader;
-
-    if (!s->reflection)
-        return D3DERR_INVALIDCALL;
-
-    return s->reflection->lpVtbl->GetOutputParameterDesc(s->reflection, element_index, desc);
+    return d3d10_get_shader_variable_signature(v, shader_index, element_index, TRUE, desc);
 }
 
 
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c
index df0d1a99ef4..1b8e765a8e6 100644
--- a/dlls/d3d10/tests/effect.c
+++ b/dlls/d3d10/tests/effect.c
@@ -3656,25 +3656,23 @@ todo_wine
     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);
+    ok(!strcmp(sign.SemanticName, "SV_Target"), "Unexpected semantic %s.\n", sign.SemanticName);
+
+    hr = ps->lpVtbl->GetOutputSignatureElementDesc(ps, 4, 0, &sign);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!strcmp(sign.SemanticName, "SV_POSITION"), "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);
+    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);
+    ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
 
     /* NULL shader variable */
     v = effect->lpVtbl->GetVariableByName(effect, "v0");
@@ -3683,6 +3681,16 @@ todo_wine
     hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 0, 0, &sign);
     ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
 
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 1, 0, &sign);
+    ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
+
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 2, 0, &sign);
+    ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
+
+    hr = vs->lpVtbl->GetOutputSignatureElementDesc(vs, 3, 0, &sign);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(!strcmp(sign.SemanticName, "SV_POSITION"), "Unexpected semantic %s.\n", sign.SemanticName);
+
     effect->lpVtbl->Release(effect);
 
     refcount = ID3D10Device_Release(device);
-- 
2.32.0




More information about the wine-devel mailing list