[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