[PATCH 3/5] d3dx9_36: Parse struct member information in parse_ctab_constant_type(try 4)

Travis Athougies iammisc at gmail.com
Thu Jul 14 16:06:50 CDT 2011


---
 dlls/d3dx9_36/shader.c |  129 +++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 122 insertions(+), 7 deletions(-)

diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 6a67f04..c0793a3 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -615,6 +615,8 @@ HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
 
 typedef struct ctab_constant {
     D3DXCONSTANT_DESC desc;
+
+    UINT member_count;
     struct ctab_constant *members;
 } ctab_constant;
 
@@ -705,6 +707,17 @@ static ULONG WINAPI ID3DXConstantTableImpl_AddRef(ID3DXConstantTable* iface)
     return InterlockedIncrement(&This->ref);
 }
 
+static void release_constants(ctab_constant *constants, UINT count)
+{
+    UINT i;
+
+    for (i = 0; i < count; i++)
+        if (constants[i].member_count > 0)
+            release_constants(constants[i].members, constants[i].member_count);
+
+    HeapFree(GetProcessHeap(), 0, constants);
+}
+
 static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
 {
     ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
@@ -714,7 +727,8 @@ static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
 
     if (!ref)
     {
-        HeapFree(GetProcessHeap(), 0, This->constants);
+        release_constants(This->constants, This->desc.Constants);
+
         HeapFree(GetProcessHeap(), 0, This->ctab);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -1149,15 +1163,18 @@ static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
     ID3DXConstantTableImpl_SetMatrixTransposePointerArray
 };
 
-static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant)
+static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant, char* ctab);
+
+static HRESULT parse_ctab_constant_element_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant, char *ctab)
 {
+    HRESULT hr;
+
     constant->desc.Class = type->Class;
     constant->desc.Type = type->Type;
     constant->desc.Rows = type->Rows;
     constant->desc.Columns = type->Columns;
-    constant->desc.Elements = type->Elements;
+    constant->desc.Elements = 1;
     constant->desc.StructMembers = type->StructMembers;
-    constant->desc.Bytes = calc_bytes(&constant->desc);
 
     TRACE("class = %d, type = %d, rows = %d, columns = %d, elements = %d, struct_members = %d\n",
           constant->desc.Class, constant->desc.Type, constant->desc.Elements,
@@ -1165,11 +1182,109 @@ static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_co
 
     if ((constant->desc.Class == D3DXPC_STRUCT) && constant->desc.StructMembers)
     {
-        FIXME("Struct not supported yet\n");
-        return E_NOTIMPL;
+        D3DXSHADER_STRUCTMEMBERINFO* members = (LPD3DXSHADER_STRUCTMEMBERINFO)(ctab + type->StructMemberInfo);
+        UINT i;
+        WORD reg = constant->desc.RegisterIndex;
+        DWORD default_value_offset = 0;
+
+        constant->member_count = constant->desc.StructMembers;
+        constant->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ctab_constant) * constant->member_count);
+
+        for (i = 0; i < constant->member_count; i++)
+        {
+            constant->members[i].desc.Name = ctab + members[i].Name;
+
+            constant->members[i].desc.RegisterSet = constant->desc.RegisterSet;
+            constant->members[i].desc.RegisterIndex = reg;
+            constant->members[i].desc.RegisterCount = 0;
+
+            constant->members[i].desc.DefaultValue = (LPVOID)((DWORD_PTR)constant->desc.DefaultValue + default_value_offset);
+
+            hr = parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO)(ctab + members[i].TypeInfo), &constant->members[i], ctab);
+            if (hr != D3D_OK)
+                goto error;
+
+            TRACE("  name = %s (under %s), rs = %d, index = %d, count = %d\n", constant->members[i].desc.Name, constant->desc.Name,
+                    constant->members[i].desc.RegisterSet, constant->members[i].desc.RegisterIndex, constant->members[i].desc.RegisterCount);
+
+            reg += constant->members[i].desc.RegisterCount;
+            default_value_offset += constant->members[i].desc.Bytes;
+        }
+
+        if (constant->desc.RegisterCount == 0)
+            /* If RegisterCount wasn't calculated for us, we have to calculate it */
+            constant->desc.RegisterCount = reg - constant->desc.RegisterIndex;
+    } else {
+        constant->member_count = 0;
+        constant->members = NULL;
     }
 
+    constant->desc.Bytes = calc_bytes(&constant->desc);
+
     return D3D_OK;
+
+error:
+    if (constant->members)
+        release_constants(constant->members, constant->desc.StructMembers);
+
+    return hr;
+}
+
+static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant, char* ctab)
+{
+    HRESULT hr;
+
+    constant->desc.Class = type->Class;
+    constant->desc.Type = type->Type;
+    constant->desc.Rows = type->Rows;
+    constant->desc.Columns = type->Columns;
+    constant->desc.Elements = type->Elements;
+    constant->desc.StructMembers = type->StructMembers;
+
+    TRACE("class = %d, type = %d, rows = %d, columns = %d, elements = %d, struct_members = %d\n",
+          constant->desc.Class, constant->desc.Type, constant->desc.Elements,
+          constant->desc.Rows, constant->desc.Columns, constant->desc.StructMembers);
+
+    if (constant->desc.RegisterCount == 0)
+        /* If RegisterCount wasn't calculated for us, we have to calculate it */
+        constant->desc.RegisterCount = constant->desc.Elements * constant->desc.Rows;
+
+    constant->desc.Bytes = calc_bytes(&constant->desc);
+
+    if (constant->desc.Elements > 1)
+    {
+        DWORD bytes_per_element = constant->desc.Bytes / constant->desc.Elements;
+        DWORD registers_per_element = constant->desc.RegisterCount / constant->desc.Elements;
+        UINT i;
+
+        constant->member_count = constant->desc.Elements;
+        constant->members = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ctab_constant) * constant->member_count);
+
+        for (i = 0; i < constant->desc.Elements; i++)
+        {
+            constant->members[i].desc.Name = constant->desc.Name;
+            constant->members[i].desc.RegisterSet = constant->desc.RegisterSet;
+            constant->members[i].desc.RegisterIndex = constant->desc.RegisterIndex + registers_per_element * i;
+            constant->members[i].desc.RegisterCount = registers_per_element;
+            constant->members[i].desc.DefaultValue = (LPVOID)((DWORD_PTR)constant->desc.DefaultValue + bytes_per_element * i);
+
+            hr = parse_ctab_constant_element_type(type, &constant->members[i], ctab);
+            if (hr != D3D_OK)
+                goto error;
+
+            TRACE("  elem %d (under %s), rs = %d, index = %d, count = %d\n", i, constant->desc.Name, constant->desc.RegisterSet,
+                    constant->members[i].desc.RegisterIndex, constant->members[i].desc.RegisterCount);
+        }
+    } else
+        return parse_ctab_constant_element_type(type, constant, ctab);
+
+    return D3D_OK;
+
+error:
+    if (constant->members)
+        release_constants(constant->members, constant->desc.Elements);
+
+    return hr;
 }
 
 HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
@@ -1255,7 +1370,7 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
         object->constants[i].desc.DefaultValue = object->ctab + constant_info[i].DefaultValue;
 
         hr = parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO)(object->ctab + constant_info[i].TypeInfo),
-             &object->constants[i]);
+                 &object->constants[i], object->ctab);
         if (hr != D3D_OK)
             goto error;
     }
-- 
1.6.4.4




More information about the wine-patches mailing list