[4/7] d3dx9: Implement ID3DXConstantTable::SetValue.
Józef Kucia
joseph.kucia at gmail.com
Thu Aug 16 10:21:20 CDT 2012
---
dlls/d3dx9_36/shader.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 800622c..4dee641 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -905,6 +905,135 @@ static HRESULT set_scalar_array(ID3DXConstantTable *iface, IDirect3DDevice9 *dev
return D3D_OK;
}
+static HRESULT set_vector_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, const void *data,
+ UINT count, D3DXPARAMETER_TYPE type)
+{
+ struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
+ D3DXCONSTANT_DESC desc;
+ HRESULT hr;
+ UINT i, j, desc_count = 1;
+ float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
+ if (FAILED(hr))
+ {
+ TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
+ return D3DERR_INVALIDCALL;
+ }
+
+ switch (desc.RegisterSet)
+ {
+ case D3DXRS_FLOAT4:
+ for (i = 0; i < min(count, desc.RegisterCount); i++)
+ {
+ switch (type)
+ {
+ case D3DXPT_FLOAT:
+ memcpy(vec, ((float *)data) + i * desc.Columns, desc.Columns * sizeof(float));
+ break;
+ case D3DXPT_INT:
+ for (j = 0; j < desc.Columns; j++)
+ vec[j] = (float)((int *)data)[i * desc.Columns + j];
+ break;
+ case D3DXPT_BOOL:
+ for (j = 0; j < desc.Columns; j++)
+ vec[j] = ((BOOL *)data)[i * desc.Columns + j] ? 1.0f : 0.0f;
+ break;
+ default:
+ FIXME("Unhandled type %#x\n", type);
+ return D3DERR_INVALIDCALL;
+ }
+
+ set_float_shader_constant(This, device, desc.RegisterIndex + i, vec, 1);
+ }
+ break;
+ default:
+ FIXME("Unhandled register set %#x\n", desc.RegisterSet);
+ return E_NOTIMPL;
+ }
+
+ return D3D_OK;
+}
+
+static HRESULT set_matrix_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, const void *data,
+ UINT count, D3DXPARAMETER_TYPE type, UINT rows, UINT columns)
+{
+ struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
+ D3DXCONSTANT_DESC desc;
+ HRESULT hr;
+ UINT registers_per_matrix;
+ UINT i, j, k, desc_count = 1;
+ UINT row_offset, column_offset;
+ FLOAT matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f};
+
+ hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
+ if (FAILED(hr))
+ {
+ TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (desc.Class == D3DXPC_MATRIX_COLUMNS)
+ {
+ column_offset = 4;
+ row_offset = 1;
+ registers_per_matrix = desc.Columns;
+ }
+ else if (desc.Class == D3DXPC_MATRIX_ROWS)
+ {
+ column_offset = 1;
+ row_offset = 4;
+ registers_per_matrix = desc.Rows;
+ }
+ else
+ {
+ FIXME("Unhandled variable class %#x\n", desc.Class);
+ return D3D_OK;
+ }
+
+ switch (desc.RegisterSet)
+ {
+ case D3DXRS_FLOAT4:
+ for (i = 0; i < count; i++)
+ {
+ if (registers_per_matrix * (i + 1) > desc.RegisterCount)
+ break;
+
+ switch (type)
+ {
+ case D3DXPT_FLOAT:
+ for (j = 0; j < min(desc.Rows, rows); j++)
+ {
+ for (k = 0; k < min(desc.Columns, columns); k++)
+ matrix[j * row_offset + k * column_offset] = ((float *)data)[i * rows * columns + j * columns + k];
+ }
+ break;
+ case D3DXPT_INT:
+ for (j = 0; j < min(desc.Rows, rows); j++)
+ {
+ for (k = 0; k < min(desc.Columns, columns); k++)
+ matrix[j * row_offset + k * column_offset] = (float)((int *)data)[i * rows * columns + j * columns + k];
+ }
+ break;
+ default:
+ FIXME("Unhandled type %#x", type);
+ return D3DERR_INVALIDCALL;
+ }
+
+ set_float_shader_constant(This, device, desc.RegisterIndex + i * registers_per_matrix, matrix, registers_per_matrix);
+ }
+ break;
+ default:
+ FIXME("Unhandled register set %#x\n", desc.RegisterSet);
+ return E_NOTIMPL;
+ }
+
+ return D3D_OK;
+}
+
static HRESULT WINAPI ID3DXConstantTableImpl_SetDefaults(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device)
{
struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
@@ -932,10 +1061,35 @@ static HRESULT WINAPI ID3DXConstantTableImpl_SetValue(ID3DXConstantTable *iface,
D3DXHANDLE constant, LPCVOID data, UINT bytes)
{
struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
+ HRESULT hr;
+ UINT elements;
+ UINT count = 1;
+ D3DXCONSTANT_DESC desc;
- FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, data, bytes);
+ TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, data, bytes);
- return E_NOTIMPL;
+ if (!device || !constant || !data)
+ return D3DERR_INVALIDCALL;
+
+ hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &count);
+ if (FAILED(hr))
+ return hr;
+
+ elements = bytes / (desc.Bytes / desc.Elements);
+
+ switch (desc.Class)
+ {
+ case D3DXPC_SCALAR:
+ return set_scalar_array(iface, device, constant, data, elements, desc.Type);
+ case D3DXPC_VECTOR:
+ return set_vector_array(iface, device, constant, data,elements, desc.Type);
+ case D3DXPC_MATRIX_ROWS:
+ case D3DXPC_MATRIX_COLUMNS:
+ return set_matrix_array(iface, device, constant, data, elements, desc.Type, desc.Rows, desc.Columns);
+ default:
+ FIXME("Unhandled parameter class %#x", desc.Class);
+ return D3DERR_INVALIDCALL;
+ }
}
static HRESULT WINAPI ID3DXConstantTableImpl_SetBool(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
--
1.7.8.6
More information about the wine-patches
mailing list