[v2 PATCH 1/8] d3d10/effect: Use effect variable pointers to store per-pass shader objects.

Nikolay Sivov nsivov at codeweavers.com
Wed Oct 6 02:53:32 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d10/d3d10_private.h | 12 +++++--
 dlls/d3d10/effect.c        | 74 +++++++++++++++++++-------------------
 dlls/d3d10/tests/effect.c  | 28 +++++++++++++++
 3 files changed, 75 insertions(+), 39 deletions(-)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 1ebbbd11ea3..f799d27b323 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -226,6 +226,12 @@ struct d3d10_effect_variable
     } u;
 };
 
+struct d3d10_effect_pass_shader_desc
+{
+    struct d3d10_effect_variable *shader;
+    unsigned int index;
+};
+
 /* ID3D10EffectPass */
 struct d3d10_effect_pass
 {
@@ -238,9 +244,9 @@ struct d3d10_effect_pass
     struct d3d10_effect_object *objects;
     struct d3d10_effect_variable *annotations;
 
-    D3D10_PASS_SHADER_DESC vs;
-    D3D10_PASS_SHADER_DESC ps;
-    D3D10_PASS_SHADER_DESC gs;
+    struct d3d10_effect_pass_shader_desc vs;
+    struct d3d10_effect_pass_shader_desc ps;
+    struct d3d10_effect_pass_shader_desc gs;
     UINT stencil_ref;
     UINT sample_mask;
     float blend_factor[4];
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 301c7cb55dd..dd4e04d6374 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -1944,8 +1944,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
             ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable);
             if (FAILED(hr = sv->lpVtbl->GetVertexShader(sv, variable_idx, &o->object.vs)))
                 return hr;
-            o->pass->vs.pShaderVariable = sv;
-            o->pass->vs.ShaderIndex = variable_idx;
+            o->pass->vs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv);
+            o->pass->vs.index = variable_idx;
             break;
         }
 
@@ -1954,8 +1954,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
             ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable);
             if (FAILED(hr = sv->lpVtbl->GetPixelShader(sv, variable_idx, &o->object.ps)))
                 return hr;
-            o->pass->ps.pShaderVariable = sv;
-            o->pass->ps.ShaderIndex = variable_idx;
+            o->pass->ps.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv);
+            o->pass->ps.index = variable_idx;
             break;
         }
 
@@ -1964,8 +1964,8 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
             ID3D10EffectShaderVariable *sv = variable->lpVtbl->AsShader(variable);
             if (FAILED(hr = sv->lpVtbl->GetGeometryShader(sv, variable_idx, &o->object.gs)))
                 return hr;
-            o->pass->gs.pShaderVariable = sv;
-            o->pass->gs.ShaderIndex = variable_idx;
+            o->pass->gs.shader = impl_from_ID3D10EffectVariable((ID3D10EffectVariable *)sv);
+            o->pass->gs.index = variable_idx;
             break;
         }
 
@@ -2018,9 +2018,9 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size,
         return E_OUTOFMEMORY;
     }
 
-    p->vs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface;
-    p->ps.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface;
-    p->gs.pShaderVariable = (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface;
+    p->vs.shader = &null_shader_variable;
+    p->ps.shader = &null_shader_variable;
+    p->gs.shader = &null_shader_variable;
 
     for (i = 0; i < p->object_count; ++i)
     {
@@ -3819,7 +3819,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa
         return E_INVALIDARG;
     }
 
-    s = &impl_from_ID3D10EffectShaderVariable(pass->vs.pShaderVariable)->u.shader;
+    s = &pass->vs.shader->u.shader;
 
     desc->Name = pass->name;
     desc->Annotations = pass->annotation_count;
@@ -3843,23 +3843,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa
 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10EffectPass *iface,
         D3D10_PASS_SHADER_DESC *desc)
 {
-    struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface);
+    struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
 
-    TRACE("iface %p, desc %p\n", iface, desc);
+    TRACE("iface %p, desc %p.\n", iface, desc);
 
-    if (This == &null_pass)
+    if (pass == &null_pass)
     {
-        WARN("Null pass specified\n");
+        WARN("Null pass specified.\n");
         return E_FAIL;
     }
 
     if (!desc)
     {
-        WARN("Invalid argument specified\n");
+        WARN("Invalid argument specified.\n");
         return E_INVALIDARG;
     }
 
-    *desc = This->vs;
+    desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->vs.shader->ID3D10EffectVariable_iface;
+    desc->ShaderIndex = pass->vs.index;
 
     return S_OK;
 }
@@ -3867,23 +3868,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10Eff
 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10EffectPass *iface,
         D3D10_PASS_SHADER_DESC *desc)
 {
-    struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface);
+    struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
 
-    TRACE("iface %p, desc %p\n", iface, desc);
+    TRACE("iface %p, desc %p.\n", iface, desc);
 
-    if (This == &null_pass)
+    if (pass == &null_pass)
     {
-        WARN("Null pass specified\n");
+        WARN("Null pass specified.\n");
         return E_FAIL;
     }
 
     if (!desc)
     {
-        WARN("Invalid argument specified\n");
+        WARN("Invalid argument specified.\n");
         return E_INVALIDARG;
     }
 
-    *desc = This->gs;
+    desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->gs.shader->ID3D10EffectVariable_iface;
+    desc->ShaderIndex = pass->gs.index;
 
     return S_OK;
 }
@@ -3891,23 +3893,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10E
 static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetPixelShaderDesc(ID3D10EffectPass *iface,
         D3D10_PASS_SHADER_DESC *desc)
 {
-    struct d3d10_effect_pass *This = impl_from_ID3D10EffectPass(iface);
+    struct d3d10_effect_pass *pass = impl_from_ID3D10EffectPass(iface);
 
-    TRACE("iface %p, desc %p\n", iface, desc);
+    TRACE("iface %p, desc %p.\n", iface, desc);
 
-    if (This == &null_pass)
+    if (pass == &null_pass)
     {
-        WARN("Null pass specified\n");
+        WARN("Null pass specified.\n");
         return E_FAIL;
     }
 
     if (!desc)
     {
-        WARN("Invalid argument specified\n");
+        WARN("Invalid argument specified.\n");
         return E_INVALIDARG;
     }
 
-    *desc = This->ps;
+    desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->ps.shader->ID3D10EffectVariable_iface;
+    desc->ShaderIndex = pass->ps.index;
 
     return S_OK;
 }
@@ -3992,9 +3995,8 @@ static void set_sampler(ID3D10Device *device, D3D10_SHADER_VARIABLE_TYPE shader_
     }
 }
 
-static void apply_shader_resources(ID3D10Device *device, struct ID3D10EffectShaderVariable *variable)
+static void apply_shader_resources(ID3D10Device *device, struct d3d10_effect_variable *v)
 {
-    struct d3d10_effect_variable *v = impl_from_ID3D10EffectShaderVariable(variable);
     struct d3d10_effect_shader_variable *sv = &v->u.shader;
     struct d3d10_effect_shader_resource *sr;
     struct d3d10_effect_variable *rsrc_v;
@@ -4092,12 +4094,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface
 
     if (flags) FIXME("Ignoring flags (%#x)\n", flags);
 
-    if (pass->vs.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface)
-        apply_shader_resources(device, pass->vs.pShaderVariable);
-    if (pass->gs.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface)
-        apply_shader_resources(device, pass->gs.pShaderVariable);
-    if (pass->ps.pShaderVariable != (ID3D10EffectShaderVariable *)&null_shader_variable.ID3D10EffectVariable_iface)
-        apply_shader_resources(device, pass->ps.pShaderVariable);
+    if (pass->vs.shader != &null_shader_variable)
+        apply_shader_resources(device, pass->vs.shader);
+    if (pass->gs.shader != &null_shader_variable)
+        apply_shader_resources(device, pass->gs.shader);
+    if (pass->ps.shader != &null_shader_variable)
+        apply_shader_resources(device, pass->ps.shader);
 
     for (i = 0; i < pass->object_count; ++i)
     {
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c
index 3561e99f338..06c5aa68776 100644
--- a/dlls/d3d10/tests/effect.c
+++ b/dlls/d3d10/tests/effect.c
@@ -2911,6 +2911,7 @@ static void test_effect_local_shader(void)
         *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;
+    D3D10_STATE_BLOCK_MASK mask;
     ID3D10Device *device;
     ULONG refcount;
 
@@ -3010,6 +3011,20 @@ if (0)
 
     /* pass 0 */
     p = t->lpVtbl->GetPassByIndex(t, 0);
+
+    /* Pass without Set*Shader() instructions */
+    hr = D3D10StateBlockMaskDisableAll(&mask);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = p->lpVtbl->ComputeStateBlockMask(p, &mask);
+todo_wine
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0);
+    ok(!ret, "Unexpected mask.\n");
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_PS, 0);
+    ok(!ret, "Unexpected mask.\n");
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_GS, 0);
+    ok(!ret, "Unexpected mask.\n");
+
     hr = p->lpVtbl->GetVertexShaderDesc(p, &pdesc);
     ok(hr == S_OK, "GetVertexShaderDesc got %x, expected %x\n", hr, S_OK);
     ok(pdesc.pShaderVariable == null_shader, "Got %p, expected %p\n", pdesc.pShaderVariable, null_shader);
@@ -3145,6 +3160,19 @@ if (0)
     ok(typedesc.UnpackedSize == 0x0, "UnpackedSize is %#x, expected 0x0\n", typedesc.UnpackedSize);
     ok(typedesc.Stride == 0x0, "Stride is %#x, expected 0x0\n", typedesc.Stride);
 
+    /* Pass is using Set*Shader(NULL) */
+    hr = D3D10StateBlockMaskDisableAll(&mask);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = p->lpVtbl->ComputeStateBlockMask(p, &mask);
+todo_wine {
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_VS, 0);
+    ok(ret, "Unexpected mask.\n");
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_PS, 0);
+    ok(ret, "Unexpected mask.\n");
+    ret = D3D10StateBlockMaskGetSetting(&mask, D3D10_DST_GS, 0);
+    ok(ret, "Unexpected mask.\n");
+}
     /* pass 2 */
     p = t->lpVtbl->GetPassByIndex(t, 2);
 
-- 
2.33.0




More information about the wine-devel mailing list