Commit e6e09eb4 authored by Rico Schüller's avatar Rico Schüller Committed by Alexandre Julliard

d3dx9: Improve shader constant table parsing.

parent 91cb426c
...@@ -1554,58 +1554,63 @@ static HRESULT parse_ctab_constant_type(const char *ctab, DWORD typeoffset, stru ...@@ -1554,58 +1554,63 @@ static HRESULT parse_ctab_constant_type(const char *ctab, DWORD typeoffset, stru
} }
else else
{ {
WORD offsetdiff = 0; WORD offsetdiff = type->Columns * type->Rows;
BOOL fail = FALSE;
switch (type->Class) size = type->Columns * type->Rows;
switch (regset)
{ {
case D3DXPC_SCALAR: case D3DXRS_BOOL:
case D3DXPC_VECTOR: fail = type->Class != D3DXPC_SCALAR && type->Class != D3DXPC_VECTOR
offsetdiff = 1; && type->Class != D3DXPC_MATRIX_ROWS && type->Class != D3DXPC_MATRIX_COLUMNS;
size = 1;
break; break;
case D3DXPC_MATRIX_ROWS: case D3DXRS_FLOAT4:
size = is_element ? type->Rows : max(type->Rows, type->Columns); case D3DXRS_INT4:
offsetdiff = type->Rows; switch (type->Class)
break; {
case D3DXPC_VECTOR:
size = 1;
/* fall through */
case D3DXPC_SCALAR:
offsetdiff = type->Rows * 4;
break;
case D3DXPC_MATRIX_ROWS:
offsetdiff = type->Rows * 4;
size = is_element ? type->Rows : max(type->Rows, type->Columns);
break;
case D3DXPC_MATRIX_COLUMNS: case D3DXPC_MATRIX_COLUMNS:
size = type->Columns; offsetdiff = type->Columns * 4;
offsetdiff = type->Columns; size = type->Columns;
break;
default:
fail = TRUE;
break;
}
break; break;
case D3DXPC_OBJECT: case D3DXRS_SAMPLER:
size = 1; size = 1;
fail = type->Class != D3DXPC_OBJECT;
break; break;
default: default:
FIXME("Unhandled type class %s\n", debug_d3dxparameter_class(type->Class)); fail = TRUE;
break; break;
} }
/* offset in bytes => offsetdiff * components(4) * sizeof(DWORD) */ if (fail)
if (offset) *offset += offsetdiff * 4 * 4;
/* int and bool registerset have different sizes */
if (regset == D3DXRS_INT4 || regset == D3DXRS_BOOL)
{ {
switch (type->Class) FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset),
{ debug_d3dxparameter_class(type->Class));
case D3DXPC_SCALAR:
case D3DXPC_VECTOR:
size = type->Columns;
break;
case D3DXPC_MATRIX_ROWS:
case D3DXPC_MATRIX_COLUMNS:
size = 4 * type->Columns;
break;
default:
FIXME("Unhandled type class %s\n", debug_d3dxparameter_class(type->Class));
break;
}
} }
/* offset in bytes => offsetdiff * sizeof(DWORD) */
if (offset) *offset += offsetdiff * 4;
} }
constant->desc.RegisterCount = max(0, min(max - index, size)); constant->desc.RegisterCount = max(0, min(max - index, size));
...@@ -1719,6 +1724,18 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(const DWORD *byte_code, DWORD flags, ...@@ -1719,6 +1724,18 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(const DWORD *byte_code, DWORD flags,
offset ? &offset : NULL, constant_info[i].Name, constant_info[i].RegisterSet); offset ? &offset : NULL, constant_info[i].Name, constant_info[i].RegisterSet);
if (hr != D3D_OK) if (hr != D3D_OK)
goto error; goto error;
/*
* Set the register count, it may differ for D3DXRS_INT4, because somehow
* it makes the assumption that the register size is 1 instead of 4, so the
* count is 4 times bigger. This holds true only for toplevel shader
* constants. The count of elements and members is always based on a
* register size of 4.
*/
if (object->constants[i].desc.RegisterSet == D3DXRS_INT4)
{
object->constants[i].desc.RegisterCount = constant_info[i].RegisterCount;
}
} }
*constant_table = &object->ID3DXConstantTable_iface; *constant_table = &object->ID3DXConstantTable_iface;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment