[PATCH 4/5] d3dx9_36: Added support for structures and arrays to constant tables
Travis Athougies
iammisc at gmail.com
Tue Jul 5 16:45:03 CDT 2011
---
dlls/d3dx9_36/shader.c | 120 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 112 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index b3b7bbc..4ee5c6e 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -769,6 +769,19 @@ static DWORD calc_constant_size(D3DXCONSTANT_DESC *desc)
return 4 * desc->Elements * desc->Rows * desc->Columns;
}
+static HRESULT calc_offset_of_element_constant(D3DXCONSTANT_DESC *desc, UINT element, UINT *offset)
+{
+ UINT element_size = desc->RegisterCount / desc->Elements;
+
+ if (element < desc->Elements)
+ {
+ *offset = element_size * element;
+ return D3D_OK;
+ }
+ else
+ return D3DXERR_INVALIDDATA;
+}
+
static HRESULT WINAPI ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable* iface, D3DXCONSTANTTABLE_DESC *desc)
{
ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
@@ -857,28 +870,119 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable*
static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable* iface, D3DXHANDLE constant, LPCSTR name)
{
ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
- UINT i;
+ UINT i, constant_count;
+ char *saveptr = NULL, *copied_name, *token, *membername, *index;
+ ctab_constant *constants, *cur_constant = NULL;
+ DWORD register_offset = 0, array_divisor = 1;
+ D3DXCONSTANT_DESC desc;
+ HRESULT hr;
TRACE("(%p)->(%p, %s)\n", This, constant, name);
if (!name)
return NULL;
+ for (i = 0; i < This->handle_count; i++)
+ if (!strcmp(This->handles[i].full_name, name))
+ return (D3DXHANDLE)(DWORD_PTR)(i + 1);
+
if (constant)
{
FIXME("Only top level constants supported\n");
return NULL;
}
+ else
+ {
+ constants = This->constants;
+ constant_count = This->desc.Constants;
+ }
- for (i = 0; i < This->handle_count; i++)
- if (!strcmp(This->handles[i].full_name, name))
- return (D3DXHANDLE)(DWORD_PTR)(i + 1);
+ copied_name = strdup(name);
- for (i = 0; i < This->desc.Constants; i++)
- if (!strcmp(This->constants[i].desc.Name, name))
- return (D3DXHANDLE)(DWORD_PTR)new_handle(This, &This->constants[i]);
+ for(token = strtok_r(copied_name, ".", &saveptr); token; token = strtok_r(NULL, ".", &saveptr))
+ {
+ if (!constants || !constant_count) {
+ free(copied_name);
+ return NULL;
+ }
- return NULL;
+ membername = token;
+
+ index = strchr(token, '[');
+ if (index) {
+ *index = '\0';
+ index++;
+ }
+
+ for (i = 0; i < constant_count; i++)
+ if (!strcmp(constants[i].desc.Name, membername))
+ {
+ cur_constant = &constants[i];
+ constants = cur_constant->members;
+ break;
+ }
+
+ if (i == constant_count)
+ {
+ TRACE("Couldn't find constant %s: quit at %s\n", name, membername);
+ free(copied_name);
+ return NULL;
+ }
+
+ if (index)
+ {
+ /* We need to calculate an offset to add to the RegisterIndex of the associated D3DXCONSTANT_DESC */
+ /* Also, we need to calculate a value which we can use to calculate the number of registers in array elements */
+ char *endptr;
+ UINT index_i = strtoul(index, &endptr, 10), offset;
+
+ if (endptr == index || *endptr != ']' || *(endptr + 1) != '\0')
+ {
+ TRACE("Invalid index specified: %s in %s\n", index, name);
+ free(copied_name);
+ return NULL;
+ }
+
+ hr = calc_offset_of_element_constant(&cur_constant->desc, index_i, &offset);
+ if (FAILED(hr))
+ {
+ WARN("Could not calculate offset of element %d of %s in %s\n", index_i, membername, name);
+ free(copied_name);
+ return NULL;
+ }
+
+ register_offset += offset;
+ array_divisor = cur_constant->desc.Elements;
+ }
+ else
+ array_divisor = 1;
+ }
+
+ if (cur_constant)
+ {
+ WORD handle;
+
+ /* Copy over the base descriptor and make adjustments for indexing */
+ desc = cur_constant->desc;
+ desc.RegisterIndex += register_offset;
+ desc.RegisterCount /= array_divisor;
+ desc.Elements /= array_divisor;
+ desc.Bytes = calc_constant_size(&desc);
+
+ TRACE("Found constant: name = %s(%s), set = %d, index = %d, count = %d, class = %d, type = %d, rows = %d, "
+ "columns = %d, elements = %d, members = %d\n", membername, name, desc.RegisterSet, desc.RegisterIndex,
+ desc.RegisterCount, desc.Class, desc.Type, desc.Rows, desc.Columns, desc.Elements, desc.StructMembers);
+
+ handle = new_handle_with_desc_and_name(This, &desc, membername, name);
+
+ free(copied_name);
+ return (D3DXHANDLE)(DWORD_PTR)handle;
+ }
+ else
+ {
+ free(copied_name);
+ return NULL;
+ }
}
static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable* iface, D3DXHANDLE constant, UINT index)
--
1.6.4.4
More information about the wine-patches
mailing list