[PATCH 3/4] d3d10: Implement ID3DEffectVariable::GetInputSignatureElementDesc().

Rico Schüller kgbricola at web.de
Tue Apr 6 14:22:51 CDT 2010


---
  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 816db7c..17f801b 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;
@@ -65,6 +72,8 @@ struct d3d10_effect_object
  struct d3d10_effect_shader_signature {
      char *signature;
      UINT signature_size;
+    UINT element_count;
+    D3D10_SIGNATURE_PARAMETER_DESC *elements;
  };
   struct d3d10_effect_shader_variable
@@ -187,15 +196,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(
-- 
1.6.6.1





More information about the wine-patches mailing list