=?UTF-8?Q?Rico=20Sch=C3=BCller=20?=: d3dx9: Parse structs and sub constants in ID3DXConstantTable.
Alexandre Julliard
julliard at winehq.org
Fri Aug 24 13:46:43 CDT 2012
Module: wine
Branch: master
Commit: b565e8fb4fd33c614088ad21f001a913177c2534
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b565e8fb4fd33c614088ad21f001a913177c2534
Author: Rico Schüller <kgbricola at web.de>
Date: Thu Aug 23 21:36:50 2012 +0200
d3dx9: Parse structs and sub constants in ID3DXConstantTable.
---
dlls/d3dx9_36/shader.c | 152 +++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 130 insertions(+), 22 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 02727fd..69bb40e 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -618,7 +618,7 @@ HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
struct ctab_constant {
D3DXCONSTANT_DESC desc;
- struct ctab_constant *members;
+ struct ctab_constant *constants;
};
static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
@@ -632,9 +632,32 @@ struct ID3DXConstantTableImpl {
struct ctab_constant *constants;
};
+static void free_constant(struct ctab_constant *constant)
+{
+ if (constant->constants)
+ {
+ UINT i, count = constant->desc.Elements > 1 ? constant->desc.Elements : constant->desc.StructMembers;
+
+ for (i = 0; i < count; ++i)
+ {
+ free_constant(&constant->constants[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, constant->constants);
+ }
+}
+
static void free_constant_table(struct ID3DXConstantTableImpl *table)
{
- HeapFree(GetProcessHeap(), 0, table->constants);
+ if (table->constants)
+ {
+ UINT i;
+
+ for (i = 0; i < table->desc.Constants; ++i)
+ {
+ free_constant(&table->constants[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, table->constants);
+ }
HeapFree(GetProcessHeap(), 0, table->ctab);
}
@@ -1426,27 +1449,117 @@ static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
ID3DXConstantTableImpl_SetMatrixTransposePointerArray
};
-static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, struct ctab_constant *constant)
+static HRESULT parse_ctab_constant_type(const char *ctab, DWORD typeoffset, struct ctab_constant *constant,
+ BOOL is_element, WORD index, WORD max, DWORD *offset, DWORD nameoffset, UINT regset)
{
+ const D3DXSHADER_TYPEINFO *type = (LPD3DXSHADER_TYPEINFO)(ctab + typeoffset);
+ const D3DXSHADER_STRUCTMEMBERINFO *memberinfo = NULL;
+ HRESULT hr = D3D_OK;
+ UINT i, count = 0;
+ WORD size = 0;
+
+ constant->desc.DefaultValue = offset ? ctab + *offset : NULL;
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 = is_element ? 1 : type->Elements;
constant->desc.StructMembers = type->StructMembers;
- constant->desc.Bytes = calc_bytes(&constant->desc);
+ constant->desc.Name = ctab + nameoffset;
+ constant->desc.RegisterSet = regset;
+ constant->desc.RegisterIndex = index;
- TRACE("class = %d, type = %d, rows = %d, columns = %d, elements = %d, struct_members = %d\n",
- constant->desc.Class, constant->desc.Type, constant->desc.Rows,
- constant->desc.Columns, constant->desc.Elements, constant->desc.StructMembers);
+ TRACE("name %s, elements %u, index %u, defaultvalue %p\n", constant->desc.Name,
+ constant->desc.Elements, index, constant->desc.DefaultValue);
+ TRACE("class %d, type %d, rows %d, columns %d, elements %d, struct_members %d\n",
+ type->Class, type->Type, type->Rows, type->Columns, type->Elements, type->StructMembers);
- if ((constant->desc.Class == D3DXPC_STRUCT) && constant->desc.StructMembers)
+ if (type->Elements > 1 && !is_element)
+ {
+ count = type->Elements;
+ }
+ else if ((type->Class == D3DXPC_STRUCT) && type->StructMembers)
{
- FIXME("Struct not supported yet\n");
- return E_NOTIMPL;
+ memberinfo = (D3DXSHADER_STRUCTMEMBERINFO*)(ctab + type->StructMemberInfo);
+ count = type->StructMembers;
}
+ if (count)
+ {
+ WORD size_element = 0;
+
+ constant->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*constant->constants) * count);
+ if (!constant->constants)
+ {
+ ERR("Out of memory\n");
+ hr = E_OUTOFMEMORY;
+ goto error;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ hr = parse_ctab_constant_type(ctab, memberinfo ? memberinfo[i].TypeInfo : typeoffset,
+ &constant->constants[i], memberinfo == NULL, index + size, max, offset,
+ memberinfo ? memberinfo[i].Name : nameoffset, regset);
+ if (hr != D3D_OK)
+ goto error;
+
+ if (i == 0) size_element = constant->constants[i].desc.RegisterCount;
+ size += size_element;
+ }
+ }
+ else
+ {
+ WORD offsetdiff = 0;
+
+ switch (type->Class)
+ {
+ case D3DXPC_SCALAR:
+ case D3DXPC_VECTOR:
+ offsetdiff = 1;
+ size = 1;
+ break;
+
+ case D3DXPC_MATRIX_ROWS:
+ size = is_element ? type->Rows : max(type->Rows, type->Columns);
+ offsetdiff = type->Rows;
+ break;
+
+ case D3DXPC_MATRIX_COLUMNS:
+ size = type->Columns;
+ offsetdiff = type->Columns;
+ break;
+
+ case D3DXPC_OBJECT:
+ size = 1;
+ break;
+
+ default:
+ FIXME("Unhandled type class %u\n", type->Class);
+ break;
+ }
+
+ /* offset in bytes => offsetdiff * components(4) * sizeof(DWORD) */
+ if (offset) *offset += offsetdiff * 4 * 4;
+ }
+
+ constant->desc.RegisterCount = max(0, min(max - index, size));
+ constant->desc.Bytes = calc_bytes(&constant->desc);
+
return D3D_OK;
+
+error:
+ if (constant->constants)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ free_constant(&constant->constants[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, constant->constants);
+ constant->constants = NULL;
+ }
+
+ return hr;
}
HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD *byte_code,
@@ -1537,16 +1650,12 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD *byte_code,
constant_info = (LPD3DXSHADER_CONSTANTINFO)(object->ctab + ctab_header->ConstantInfo);
for (i = 0; i < ctab_header->Constants; i++)
{
- TRACE("name = %s\n", object->ctab + constant_info[i].Name);
- object->constants[i].desc.Name = object->ctab + constant_info[i].Name;
- object->constants[i].desc.RegisterSet = constant_info[i].RegisterSet;
- object->constants[i].desc.RegisterIndex = constant_info[i].RegisterIndex;
- object->constants[i].desc.RegisterCount = constant_info[i].RegisterCount;
- object->constants[i].desc.DefaultValue = constant_info[i].DefaultValue
- ? object->ctab + constant_info[i].DefaultValue : NULL;
-
- hr = parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO)(object->ctab + constant_info[i].TypeInfo),
- &object->constants[i]);
+ DWORD offset = constant_info[i].DefaultValue;
+
+ hr = parse_ctab_constant_type(object->ctab, constant_info[i].TypeInfo,
+ &object->constants[i], FALSE, constant_info[i].RegisterIndex,
+ constant_info[i].RegisterIndex + constant_info[i].RegisterCount,
+ offset ? &offset : NULL, constant_info[i].Name, constant_info[i].RegisterSet);
if (hr != D3D_OK)
goto error;
}
@@ -1556,7 +1665,6 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD *byte_code,
return D3D_OK;
error:
-
free_constant_table(object);
HeapFree(GetProcessHeap(), 0, object);
More information about the wine-cvs
mailing list