Rico Schüller : d3d10: Implement ID3DEffectVariable:: GetInputSignatureElementDesc().

Alexandre Julliard julliard at winehq.org
Thu Apr 8 11:12:44 CDT 2010


Module: wine
Branch: master
Commit: 055a0f0d6c251745164e1730aea28d4fd75737e2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=055a0f0d6c251745164e1730aea28d4fd75737e2

Author: Rico Schüller <kgbricola at web.de>
Date:   Wed Apr  7 18:34:24 2010 +0200

d3d10: Implement ID3DEffectVariable::GetInputSignatureElementDesc().

---

 dlls/d3d10/d3d10_private.h |   13 ++++-
 dlls/d3d10/effect.c        |  136 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 143 insertions(+), 6 deletions(-)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 50fe710..0cad484 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -29,6 +29,13 @@
 
 #include "d3d10.h"
 
+/*
+ * This doesn't belong here, but for some functions it is possible to return that value,
+ * see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
+ * The original definition is in D3DX10core.h.
+ */
+#define D3DERR_INVALIDCALL 0x8876086c
+
 /* TRACE helper functions */
 const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type) DECLSPEC_HIDDEN;
 const char *debug_d3d10_shader_variable_class(D3D10_SHADER_VARIABLE_CLASS c) DECLSPEC_HIDDEN;
@@ -66,6 +73,8 @@ struct d3d10_effect_shader_signature
 {
     char *signature;
     UINT signature_size;
+    UINT element_count;
+    D3D10_SIGNATURE_PARAMETER_DESC *elements;
 };
 
 struct d3d10_effect_shader_variable
@@ -188,15 +197,17 @@ struct d3d10_effect
     DWORD samplerstate_count;
     DWORD rendertargetview_count;
     DWORD depthstencilview_count;
-    DWORD shader_call_count;
+    DWORD used_shader_count;
     DWORD anonymous_shader_count;
 
+    DWORD used_shader_current;
     DWORD anonymous_shader_current;
 
     struct wine_rb_tree types;
     struct d3d10_effect_variable *local_buffers;
     struct d3d10_effect_variable *local_variables;
     struct d3d10_effect_anonymous_shader *anonymous_shaders;
+    struct d3d10_effect_variable **used_shaders;
     struct d3d10_effect_technique *techniques;
 };
 
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index da4e344..9c98b2c 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -223,9 +223,63 @@ static BOOL copy_name(const char *ptr, char **name)
     return TRUE;
 }
 
+static HRESULT shader_parse_signature(const char *data, DWORD data_size, struct d3d10_effect_shader_signature *s)
+{
+    D3D10_SIGNATURE_PARAMETER_DESC *e;
+    const char *ptr = data;
+    unsigned int i;
+    DWORD count;
+
+    read_dword(&ptr, &count);
+    TRACE("%u elements\n", count);
+
+    skip_dword_unknown(&ptr, 1);
+
+    e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e));
+    if (!e)
+    {
+        ERR("Failed to allocate signature memory.\n");
+        return E_OUTOFMEMORY;
+    }
+
+    for (i = 0; i < count; ++i)
+    {
+        UINT name_offset;
+        UINT mask;
+
+        read_dword(&ptr, &name_offset);
+        e[i].SemanticName = data + name_offset;
+        read_dword(&ptr, &e[i].SemanticIndex);
+        read_dword(&ptr, &e[i].SystemValueType);
+        read_dword(&ptr, &e[i].ComponentType);
+        read_dword(&ptr, &e[i].Register);
+        read_dword(&ptr, &mask);
+
+        e[i].ReadWriteMask = mask >> 8;
+        e[i].Mask = mask & 0xff;
+
+        TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
+                "type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
+                debugstr_a(e[i].SemanticName), e[i].SemanticIndex, e[i].SystemValueType,
+                e[i].ComponentType, e[i].Register, e[i].Mask, e[i].ReadWriteMask);
+    }
+
+    s->elements = e;
+    s->element_count = count;
+
+    return S_OK;
+}
+
+static void shader_free_signature(struct d3d10_effect_shader_signature *s)
+{
+    HeapFree(GetProcessHeap(), 0, s->signature);
+    HeapFree(GetProcessHeap(), 0, s->elements);
+}
+
 static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
 {
     struct d3d10_effect_shader_variable *s = ctx;
+    HRESULT hr;
 
     TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4));
 
@@ -274,6 +328,14 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag
             write_dword(&ptr, TAG_ISGN);
             write_dword(&ptr, data_size);
             memcpy(ptr, data, data_size);
+
+            hr = shader_parse_signature(ptr, data_size, sig);
+            if (FAILED(hr))
+            {
+                ERR("Failed to parse shader, hr %#x\n", hr);
+                shader_free_signature(sig);
+            }
+
             break;
         }
 
@@ -302,6 +364,15 @@ static HRESULT parse_shader(struct d3d10_effect_variable *v, const char *data)
 
     v->data = s;
 
+    if (v->effect->used_shader_current >= v->effect->used_shader_count)
+    {
+        WARN("Invalid shader? Used shader current(%u) >= used shader count(%u)\n", v->effect->used_shader_current, v->effect->used_shader_count);
+        return E_FAIL;
+    }
+
+    v->effect->used_shaders[v->effect->used_shader_current] = v;
+    ++v->effect->used_shader_current;
+
     if (!ptr) return S_OK;
 
     read_dword(&ptr, &dxbc_size);
@@ -1581,6 +1652,13 @@ static HRESULT parse_fx10_body(struct d3d10_effect *e, const char *data, DWORD d
         return E_OUTOFMEMORY;
     }
 
+    e->used_shaders = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->used_shader_count * sizeof(*e->used_shaders));
+    if (!e->used_shaders)
+    {
+        ERR("Failed to allocate used shaders memory\n");
+        return E_OUTOFMEMORY;
+    }
+
     e->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->technique_count * sizeof(*e->techniques));
     if (!e->techniques)
     {
@@ -1683,8 +1761,8 @@ static HRESULT parse_fx10(struct d3d10_effect *e, const char *data, DWORD data_s
     read_dword(&ptr, &e->depthstencilview_count);
     TRACE("Depthstencilview count: %u\n", e->depthstencilview_count);
 
-    read_dword(&ptr, &e->shader_call_count);
-    TRACE("Shader call count: %u\n", e->shader_call_count);
+    read_dword(&ptr, &e->used_shader_count);
+    TRACE("Used shader count: %u\n", e->used_shader_count);
 
     read_dword(&ptr, &e->anonymous_shader_count);
     TRACE("Anonymous shader count: %u\n", e->anonymous_shader_count);
@@ -1785,7 +1863,7 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)
             case D3D10_SVT_VERTEXSHADER:
             case D3D10_SVT_PIXELSHADER:
             case D3D10_SVT_GEOMETRYSHADER:
-                HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)v->data)->input_signature.signature);
+                shader_free_signature(&((struct d3d10_effect_shader_variable *)v->data)->input_signature);
                 break;
 
             default:
@@ -1957,6 +2035,8 @@ static ULONG STDMETHODCALLTYPE d3d10_effect_Release(ID3D10Effect *iface)
             HeapFree(GetProcessHeap(), 0, This->anonymous_shaders);
         }
 
+        HeapFree(GetProcessHeap(), 0, This->used_shaders);
+
         wine_rb_destroy(&This->types, d3d10_effect_type_destroy, NULL);
 
         ID3D10Device_Release(This->device);
@@ -5160,10 +5240,56 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetInputSignatureE
         ID3D10EffectShaderVariable *iface, UINT shader_index, UINT element_index,
         D3D10_SIGNATURE_PARAMETER_DESC *desc)
 {
-    FIXME("iface %p, shader_index %u, element_index %u, desc %p stub!\n",
+    struct d3d10_effect_variable *This = (struct d3d10_effect_variable *)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);
 
-    return E_NOTIMPL;
+    if (!iface->lpVtbl->IsValid(iface))
+    {
+        WARN("Null variable specified\n");
+        return E_FAIL;
+    }
+
+    /* Check shader_index, this crashes on W7/DX10 */
+    if (shader_index >= This->effect->used_shader_count)
+    {
+        WARN("This should crash on W7/DX10!\n");
+        return E_FAIL;
+    }
+
+    s = This->effect->used_shaders[shader_index]->data;
+    if (!s->input_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->input_signature.element_count)
+    {
+        WARN("Invalid element index specified\n");
+        return E_INVALIDARG;
+    }
+
+    d = &s->input_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;
+
+    return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE d3d10_effect_shader_variable_GetOutputSignatureElementDesc(




More information about the wine-cvs mailing list