From 9fec159abc3f3011a9d473a31ea1bc1ebb62da66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 21 Aug 2012 14:52:19 +0200 Subject: [PATCH] d3dx9: Implement ID3DXConstantTable::SetMatrixPointerArray. --- dlls/d3dx9_36/shader.c | 98 +++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/shader.c | 52 +++++++++++++++++++ 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 01b2e7c0dd5..621eb883989 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -1079,6 +1079,100 @@ static HRESULT set_matrix_array(ID3DXConstantTable *iface, IDirect3DDevice9 *dev return D3D_OK; } +static HRESULT set_matrix_pointer_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, + const D3DXMATRIX **data, UINT count, D3DXPARAMETER_CLASS class) +{ + struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface); + D3DXCONSTANT_DESC desc; + HRESULT hr; + UINT registers_per_matrix; + UINT i, desc_count = 1; + UINT num_rows, num_columns; + 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_ROWS || desc.Class == D3DXPC_MATRIX_COLUMNS) + { + if (desc.Class == class) + { + column_offset = 1; + row_offset = 4; + } + else + { + column_offset = 4; + row_offset = 1; + } + + if (class == D3DXPC_MATRIX_ROWS) + { + num_rows = desc.Rows; + num_columns = desc.Columns; + } + else + { + num_rows = desc.Columns; + num_columns = desc.Rows; + } + + registers_per_matrix = (desc.Class == D3DXPC_MATRIX_ROWS) ? desc.Rows : desc.Columns; + } + else if (desc.Class == D3DXPC_SCALAR) + { + registers_per_matrix = 1; + column_offset = 1; + row_offset = 1; + num_rows = desc.Rows; + num_columns = desc.Columns; + } + else if (desc.Class == D3DXPC_VECTOR) + { + registers_per_matrix = 1; + column_offset = 1; + row_offset = 4; + num_rows = desc.Rows; + num_columns = desc.Columns; + } + 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; + + hr = set_float_matrix(matrix, &desc, row_offset, column_offset, num_rows, num_columns, *data, D3DXPT_FLOAT, 4); + if (FAILED(hr)) return hr; + + set_float_shader_constant(This, device, desc.RegisterIndex + i * registers_per_matrix, matrix, registers_per_matrix); + + data++; + } + 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); @@ -1242,9 +1336,9 @@ static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixPointerArray(ID3DXConstant { struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface); - FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, matrix, count); + TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, matrix, count); - return E_NOTIMPL; + return set_matrix_pointer_array(iface, device, constant, matrix, count, D3DXPC_MATRIX_ROWS); } static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTranspose(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device, diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index caa0f0b7303..5a58370524f 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -569,6 +569,7 @@ static void test_setting_basic_table(IDirect3DDevice9 *device) static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f}; static const float f = 0.12543f; static const int i = 321; + static const D3DXMATRIX *matrix_pointer[] = {&mvp}; ID3DXConstantTable *ctable; @@ -712,6 +713,27 @@ static void test_setting_basic_table(IDirect3DDevice9 *device) out[0], out[1], out[2], out[3], S(U(mvp))._11, S(U(mvp))._21, S(U(mvp))._31, S(U(mvp))._41); + memset(out, 0, sizeof(out)); + IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1); + res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f", matrix_pointer, 1); + ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f: got %#x\n", res); + + IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1); + ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f, + "The variable f was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, " + "got %f, should be %f\n", + out[0], U(S(mvp))._11); + + res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f4", matrix_pointer, 1); + ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f4: got %#x\n", res); + + IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1); + ok(out[0] == U(S(mvp))._11 && out[1] == U(S(mvp))._12 && out[2] == U(S(mvp))._13 && out[3] == U(S(mvp))._14, + "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, " + "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", + out[0], out[1], out[2], out[3], + U(S(mvp))._11, U(S(mvp))._12, U(S(mvp))._13, U(S(mvp))._14); + refcnt = ID3DXConstantTable_Release(ctable); ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt); } @@ -723,6 +745,7 @@ static void test_setting_matrices_table(IDirect3DDevice9 *device) 5.005f, 3.006f, 3.007f, 6.008f, 9.009f, 5.010f, 7.011f, 1.012f, 5.013f, 5.014f, 5.015f, 9.016f}}}; + static const D3DXMATRIX *matrix_pointer[] = {&fmatrix}; ID3DXConstantTable *ctable; @@ -875,6 +898,35 @@ static void test_setting_matrices_table(IDirect3DDevice9 *device) S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f, S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f); + /* SetMatrixPointerArray */ + res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "c2x3", matrix_pointer, 1); + ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable c2x3: got %#x\n", res); + + res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "r2x3", matrix_pointer, 1); + ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable r2x3: got %#x\n", res); + + IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3); + ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f + && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f + && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f, + "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, " + "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n", + out[0], out[1], out[2], out[3], + out[4], out[5], out[6], out[7], + out[8], out[9], out[10], out[11], + S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f, + S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f, + S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f); + + IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2); + ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f + && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f, + "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, " + "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n", + out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], + S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f, + S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f); + ID3DXConstantTable_Release(ctable); }