[PATCH] d3dx9_36: Beginning of constants parsing + tests (based on work from Luis Busquets) (try 3)
Christian Costa
titan.costa at wanadoo.fr
Mon Apr 5 16:03:27 CDT 2010
--
Use UINT_PTR instead of UINT
---
dlls/d3dx9_36/shader.c | 137 +++++++++++++++++++++++++++++++++++++++---
dlls/d3dx9_36/tests/shader.c | 105 ++++++++++++++++++++++++++++++++
2 files changed, 233 insertions(+), 9 deletions(-)
-------------- next part --------------
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 3aeaf78..bd061ea 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -650,6 +650,29 @@ HRESULT WINAPI D3DXCompileShader(LPCSTR pSrcData,
return D3DERR_INVALIDCALL;
}
+typedef struct ctab_constant ctab_constant;
+
+struct ctab_constant {
+ D3DXCONSTANT_DESC desc;
+ ctab_constant* members;
+};
+
+inline ctab_constant* get_constant(D3DXHANDLE ptr)
+{
+ if (!ptr) return NULL;
+ return (ctab_constant*)~((UINT_PTR)ptr);
+}
+
+inline D3DXHANDLE get_handle(ctab_constant* ptr)
+{
+ return (D3DXHANDLE)~((UINT_PTR)ptr);
+}
+
+inline BOOL isstring(D3DXHANDLE ptr)
+{
+ return !(((UINT_PTR)ptr) & (1 << (sizeof(UINT_PTR)*8-1)));
+}
+
static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
typedef struct ID3DXConstantTableImpl {
@@ -658,6 +681,7 @@ typedef struct ID3DXConstantTableImpl {
LPVOID ctab;
DWORD size;
D3DXCONSTANTTABLE_DESC desc;
+ ctab_constant* constants;
} ID3DXConstantTableImpl;
/*** IUnknown methods ***/
@@ -699,6 +723,7 @@ static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
if (!ref)
{
+ HeapFree(GetProcessHeap(), 0, This->constants);
HeapFree(GetProcessHeap(), 0, This->ctab);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -744,10 +769,23 @@ static HRESULT WINAPI ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable*
D3DXCONSTANT_DESC *desc, UINT *count)
{
ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
+ ctab_constant* constant_info;
- FIXME("(%p)->(%p, %p, %p): stub\n", This, constant, desc, count);
+ TRACE("(%p)->(%p, %p, %p)\n", This, constant, desc, count);
- return E_NOTIMPL;
+ if (!constant)
+ return D3DERR_INVALIDCALL;
+
+ constant_info = get_constant(isstring(constant) ? ID3DXConstantTable_GetConstantByName(iface, NULL, constant) : constant);
+ if (!constant_info)
+ return D3DERR_INVALIDCALL;
+
+ if (desc)
+ *desc = constant_info->desc;
+ if (count)
+ *count = 1;
+
+ return D3D_OK;
}
static UINT WINAPI ID3DXConstantTableImpl_GetSamplerIndex(LPD3DXCONSTANTTABLE iface, D3DXHANDLE constant)
@@ -763,17 +801,40 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable*
{
ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
- FIXME("(%p)->(%p, %d): stub\n", This, constant, index);
+ TRACE("(%p)->(%p, %d)\n", This, constant, index);
- return NULL;
+ if (constant)
+ {
+ FIXME("Only top level constants supported\n");
+ return NULL;
+ }
+
+ if (index >= This->desc.Constants)
+ return NULL;
+
+ return get_handle(This->constants + index);
}
static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable* iface, D3DXHANDLE constant, LPCSTR name)
{
ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
+ UINT i;
- FIXME("(%p)->(%p, %s): stub\n", This, constant, name);
+ TRACE("(%p)->(%p, %s)\n", This, constant, name);
+ if (!name)
+ return NULL;
+
+ if (constant)
+ {
+ FIXME("Only top level constants supported\n");
+ return NULL;
+ }
+
+ for (i = 0; i < This->desc.Constants; i++)
+ if (!strcmp(This->constants[i].desc.Name, name))
+ return get_handle(This->constants + i);
+
return NULL;
}
@@ -978,6 +1039,26 @@ static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
ID3DXConstantTableImpl_SetMatrixTransposePointerArray
};
+HRESULT parse_ctab_constant_type(LPVOID ctab, LPD3DXSHADER_TYPEINFO type, ctab_constant* constant)
+{
+ constant->desc.Class = (D3DXPARAMETER_CLASS)type->Class;
+ constant->desc.Type = (D3DXPARAMETER_TYPE)type->Type;
+ constant->desc.Rows = type->Rows;
+ constant->desc.Columns = type->Columns;
+ constant->desc.StructMembers = type->StructMembers;
+
+ TRACE("class = %d, type = %d, rows = %d, columns = %d, struct_members = %d\n", constant->desc.Class, constant->desc.Type,
+ constant->desc.Rows, constant->desc.Columns, constant->desc.StructMembers);
+
+ if ((constant->desc.Class == D3DXPC_STRUCT) && constant->desc.StructMembers)
+ {
+ FIXME("Struct not supported yet\n");
+ return E_NOTIMPL;
+ }
+
+ return D3D_OK;
+}
+
HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
DWORD flags,
LPD3DXCONSTANTTABLE* constant_table)
@@ -987,8 +1068,10 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
LPCVOID data;
UINT size;
const D3DXSHADER_CONSTANTTABLE* ctab_header;
+ LPD3DXSHADER_CONSTANTINFO constant_info;
+ DWORD i;
- FIXME("(%p, %x, %p): semi-stub\n", byte_code, flags, constant_table);
+ TRACE("(%p, %x, %p)\n", byte_code, flags, constant_table);
if (!byte_code || !constant_table)
return D3DERR_INVALIDCALL;
@@ -1008,24 +1091,59 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
object->ref = 1;
if (size < sizeof(D3DXSHADER_CONSTANTTABLE))
+ {
+ hr = D3DXERR_INVALIDDATA;
goto error;
+ }
object->ctab = HeapAlloc(GetProcessHeap(), 0, size);
if (!object->ctab)
{
- HeapFree(GetProcessHeap(), 0, object);
ERR("Out of memory\n");
- return E_OUTOFMEMORY;
+ hr = E_OUTOFMEMORY;
+ goto error;
}
object->size = size;
memcpy(object->ctab, data, object->size);
ctab_header = (const D3DXSHADER_CONSTANTTABLE*)data;
if (ctab_header->Size != sizeof(D3DXSHADER_CONSTANTTABLE))
+ {
+ hr = D3DXERR_INVALIDDATA;
goto error;
+ }
object->desc.Creator = ctab_header->Creator ? (LPCSTR)object->ctab + ctab_header->Creator : NULL;
object->desc.Version = ctab_header->Version;
object->desc.Constants = ctab_header->Constants;
+ if (object->desc.Creator)
+ TRACE("Creator = %s\n", object->desc.Creator);
+ TRACE("Version = %x\n", object->desc.Version);
+ TRACE("Constants = %d\n", ctab_header->Constants);
+ if (ctab_header->Target)
+ TRACE("Target = %s\n", (LPCSTR)object->ctab + ctab_header->Target);
+
+ object->constants = (ctab_constant*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(ctab_constant)*object->desc.Constants);
+ if (!object->constants)
+ {
+ ERR("Out of memory\n");
+ hr = E_OUTOFMEMORY;
+ goto error;
+ }
+
+ constant_info = (LPD3DXSHADER_CONSTANTINFO)((LPCSTR)object->ctab + ctab_header->ConstantInfo);
+ for (i = 0; i < ctab_header->Constants; i++)
+ {
+ TRACE("name = %s\n", (LPCSTR)object->ctab + constant_info[i].Name);
+ object->constants[i].desc.Name = (LPCSTR)object->ctab + constant_info[i].Name;
+ object->constants[i].desc.RegisterSet = (D3DXREGISTER_SET)constant_info[i].RegisterSet;
+ object->constants[i].desc.RegisterIndex = constant_info[i].RegisterIndex;
+ object->constants[i].desc.RegisterCount = 0;
+ hr = parse_ctab_constant_type(object->ctab, (LPD3DXSHADER_TYPEINFO)((LPCSTR)object->ctab + constant_info[i].TypeInfo),
+ &object->constants[i]);
+ if (hr != D3D_OK)
+ goto error;
+ }
*constant_table = (LPD3DXCONSTANTTABLE)object;
@@ -1033,10 +1151,11 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
error:
+ HeapFree(GetProcessHeap(), 0, object->constants);
HeapFree(GetProcessHeap(), 0, object->ctab);
HeapFree(GetProcessHeap(), 0, object);
- return D3DXERR_INVALIDDATA;
+ return hr;
}
HRESULT WINAPI D3DXGetShaderConstantTable(CONST DWORD* byte_code,
diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c
index 6bf0de3..318ac92 100644
--- a/dlls/d3dx9_36/tests/shader.c
+++ b/dlls/d3dx9_36/tests/shader.c
@@ -55,6 +55,23 @@ static const DWORD shader_with_invalid_ctab[] = {
0x00000000, 0x00000000,
0x0000ffff}; /* END */
+static const DWORD shader_with_ctab_constants[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x002efffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000a4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header */
+ 0x0000009c,
+ 0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000, /* Constant 1 desc */
+ 0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000, /* Constant 2 desc */
+ 0x00000090, 0x00040002, 0x00000003, 0x00000080, 0x00000000, /* Constant 3 desc */
+ 0x736e6f43, 0x746e6174, 0xabab0031, /* Constant 1 name string */
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0032, /* Constant 2 name string */
+ 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* Constant 2 & 3 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0033, /* Constant 3 name string */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
static void test_get_shader_size(void)
{
UINT shader_size, expected;
@@ -156,6 +173,94 @@ static void test_get_shader_constant_table_ex(void)
ID3DXConstantTable_Release(constant_table);
}
+
+ hr = D3DXGetShaderConstantTableEx(shader_with_ctab_constants, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ D3DXHANDLE constant;
+ D3DXCONSTANT_DESC constant_desc;
+ D3DXCONSTANT_DESC constant_desc_save;
+ UINT nb;
+
+ /* Test GetDesc */
+ hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(desc.Creator, "Wine project"), "Got result '%s', expected 'Wine project'\n", desc.Creator);
+ ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
+ ok(desc.Constants == 3, "Got result %x, expected 3\n", desc.Constants);
+
+ /* Test GetConstant */
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant1"), "Got result '%s', expected 'Constant1'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_VECTOR, "Got result %x, expected %u (D3DXPC_VECTOR)\n",
+ constant_desc.Class, D3DXPC_VECTOR);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 1, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 1);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant2"), "Got result '%s', expected 'Constant2'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
+ constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 2);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant3"), "Got result '%s', expected 'Constant3'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
+ constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+ constant_desc_save = constant_desc; /* For GetConstantDesc test */
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 3);
+ ok(constant == NULL, "Got result %p, expected NULL\n", constant);
+
+ /* Test GetConstantByName */
+ constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant unknown");
+ ok(constant == NULL, "Got result %p, expected NULL\n", constant);
+ constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant3");
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
+
+ /* Test GetConstantDesc */
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, NULL, &constant_desc, &nb);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, NULL, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant unknow", &constant_desc, &nb);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant3", &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
+
+ ID3DXConstantTable_Release(constant_table);
+ }
}
START_TEST(shader)
More information about the wine-patches
mailing list