[PATCH 09/10] d3d10: Get resources used by effect shaders.

Connor McAdams conmanx360 at gmail.com
Sat Dec 7 12:22:59 CST 2019


Get the resources that the shader will need to be bound for use by
searching the effect framework buffers + local variables.

Signed-off-by: Connor McAdams <conmanx360 at gmail.com>
---
 dlls/d3d10/d3d10_private.h | 12 ++++++
 dlls/d3d10/effect.c        | 82 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index f3b4e65e1c..87e506d668 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -76,6 +76,15 @@ struct d3d10_effect_object
     } object;
 };
 
+struct d3d10_effect_shader_resource
+{
+    D3D10_SHADER_INPUT_TYPE in_type;
+    UINT bind_point;
+    UINT bind_count;
+
+    struct d3d10_effect_variable *resource_variable;
+};
+
 struct d3d10_effect_shader_signature
 {
     char *signature;
@@ -94,6 +103,9 @@ struct d3d10_effect_shader_variable
         ID3D10PixelShader *ps;
         ID3D10GeometryShader *gs;
     } shader;
+
+    UINT resources;
+    struct d3d10_effect_shader_resource *shader_resource;
 };
 
 struct d3d10_effect_state_object_variable
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 9898b7f79f..df95724f95 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -657,6 +657,82 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag
     return S_OK;
 }
 
+static HRESULT get_fx10_shader_resources(struct d3d10_effect_variable *v, const void *data, size_t data_size)
+{
+    struct d3d10_effect_variable *tmp;
+    struct d3d10_effect_shader_variable *shader_var = &v->u.shader;
+    ID3D10ShaderReflection *reflector;
+    D3D10_SHADER_DESC desc;
+    D3D10_SHADER_INPUT_BIND_DESC rsrc_desc;
+    unsigned int i, y;
+    HRESULT hr;
+
+    hr = D3D10ReflectShader(data, data_size, &reflector);
+    if (FAILED(hr)) return hr;
+
+    reflector->lpVtbl->GetDesc(reflector, &desc);
+    shader_var->resources = desc.BoundResources;
+
+    if (!(shader_var->shader_resource = heap_calloc(shader_var->resources, sizeof(struct d3d10_effect_shader_resource))))
+    {
+        ERR("Failed to allocate shader resource binding information memory.\n");
+        hr = E_OUTOFMEMORY;
+        goto exit;
+    }
+
+    for (i = 0; i < desc.BoundResources; i++)
+    {
+        reflector->lpVtbl->GetResourceBindingDesc(reflector, i, &rsrc_desc);
+        shader_var->shader_resource[i].in_type    = rsrc_desc.Type;
+        shader_var->shader_resource[i].bind_point = rsrc_desc.BindPoint;
+        shader_var->shader_resource[i].bind_count = rsrc_desc.BindCount;
+
+        switch (rsrc_desc.Type)
+        {
+            case D3D10_SIT_CBUFFER:
+            case D3D10_SIT_TBUFFER:
+                for (y = 0; y < v->effect->local_buffer_count; y++)
+                {
+                    tmp = &v->effect->local_buffers[y];
+
+                    if (tmp->name && !strcmp(rsrc_desc.Name, tmp->name))
+                    {
+                        shader_var->shader_resource[i].resource_variable = tmp;
+                        break;
+                    }
+                }
+                break;
+            case D3D10_SIT_SAMPLER:
+            case D3D10_SIT_TEXTURE:
+                for (y = 0; y < v->effect->local_variable_count; y++)
+                {
+                    tmp = &v->effect->local_variables[y];
+
+                    if (tmp->name && !strcmp(rsrc_desc.Name, tmp->name))
+                    {
+                        shader_var->shader_resource[i].resource_variable = tmp;
+                        break;
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+
+        if (!shader_var->shader_resource[i].resource_variable)
+        {
+            ERR("Failed to find shader resource.\n");
+            hr = E_FAIL;
+            goto exit;
+        }
+    }
+
+exit:
+    reflector->lpVtbl->Release(reflector);
+
+    return hr;
+}
+
 static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offset, struct d3d10_effect_variable *v)
 {
     ID3D10Device *device = v->effect->device;
@@ -692,6 +768,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;
 
+    hr = get_fx10_shader_resources(v, (const void *)ptr, dxbc_size);
+    if (FAILED(hr)) return hr;
+
     switch (v->type->basetype)
     {
         case D3D10_SVT_VERTEXSHADER:
@@ -2635,6 +2714,9 @@ static void d3d10_effect_shader_variable_destroy(struct d3d10_effect_shader_vari
             FIXME("Unhandled shader type %s.\n", debug_d3d10_shader_variable_type(type));
             break;
     }
+
+    if (s->resources)
+        heap_free(s->shader_resource);
 }
 
 static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)
-- 
2.20.1




More information about the wine-devel mailing list