d3dx9: Constant table parsing foundations.
This commit is contained in:
parent
b4736bd767
commit
128cf64371
|
@ -609,14 +609,20 @@ HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
|
|||
|
||||
}
|
||||
|
||||
typedef struct ctab_constant {
|
||||
D3DXCONSTANT_DESC desc;
|
||||
struct ctab_constant *members;
|
||||
} ctab_constant;
|
||||
|
||||
static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
|
||||
|
||||
typedef struct ID3DXConstantTableImpl {
|
||||
const ID3DXConstantTableVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
LPVOID ctab;
|
||||
char *ctab;
|
||||
DWORD size;
|
||||
D3DXCONSTANTTABLE_DESC desc;
|
||||
ctab_constant *constants;
|
||||
} ID3DXConstantTableImpl;
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
|
@ -658,6 +664,7 @@ static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
|
|||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This->constants);
|
||||
HeapFree(GetProcessHeap(), 0, This->ctab);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
@ -703,10 +710,31 @@ 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;
|
||||
|
||||
/* Applications can pass the name of the constant in place of the handle */
|
||||
if (!((UINT_PTR)constant >> 16))
|
||||
constant_info = &This->constants[(UINT_PTR)constant - 1];
|
||||
else
|
||||
{
|
||||
D3DXHANDLE c = ID3DXConstantTable_GetConstantByName(iface, NULL, constant);
|
||||
if (!c)
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
constant_info = &This->constants[(UINT_PTR)c - 1];
|
||||
}
|
||||
|
||||
if (desc)
|
||||
*desc = constant_info->desc;
|
||||
if (count)
|
||||
*count = 1;
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
static UINT WINAPI ID3DXConstantTableImpl_GetSamplerIndex(LPD3DXCONSTANTTABLE iface, D3DXHANDLE constant)
|
||||
|
@ -722,16 +750,39 @@ 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);
|
||||
|
||||
if (constant)
|
||||
{
|
||||
FIXME("Only top level constants supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (index >= This->desc.Constants)
|
||||
return NULL;
|
||||
|
||||
return (D3DXHANDLE)(DWORD_PTR)(index + 1);
|
||||
}
|
||||
|
||||
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 (D3DXHANDLE)(DWORD_PTR)(i + 1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -937,6 +988,27 @@ static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
|
|||
ID3DXConstantTableImpl_SetMatrixTransposePointerArray
|
||||
};
|
||||
|
||||
static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant)
|
||||
{
|
||||
constant->desc.Class = type->Class;
|
||||
constant->desc.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)
|
||||
|
@ -946,8 +1018,10 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
|
|||
LPCVOID data;
|
||||
UINT size;
|
||||
const D3DXSHADER_CONSTANTTABLE* ctab_header;
|
||||
D3DXSHADER_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;
|
||||
|
@ -967,24 +1041,66 @@ 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.Creator = ctab_header->Creator ? 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", object->ctab + ctab_header->Target);
|
||||
|
||||
if (object->desc.Constants > 65535)
|
||||
{
|
||||
FIXME("Too many constants (%u)\n", object->desc.Constants);
|
||||
hr = E_NOTIMPL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
object->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(*object->constants) * object->desc.Constants);
|
||||
if (!object->constants)
|
||||
{
|
||||
ERR("Out of memory\n");
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
hr = parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO)(object->ctab + constant_info[i].TypeInfo),
|
||||
&object->constants[i]);
|
||||
if (hr != D3D_OK)
|
||||
goto error;
|
||||
}
|
||||
|
||||
*constant_table = (LPD3DXCONSTANTTABLE)object;
|
||||
|
||||
|
@ -992,10 +1108,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,
|
||||
|
|
|
@ -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;
|
||||
|
@ -157,6 +174,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 (SUCCEEDED(hr))
|
||||
{
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue