Module: wine Branch: master Commit: b565e8fb4fd33c614088ad21f001a913177c2534 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b565e8fb4fd33c614088ad21f0...
Author: Rico Schüller kgbricola@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);