This patch series implements `ID3DXEffect::SetRawValue()` for the simplest cases, which are vec4s and matrix 4x4s.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/effect.c | 377 +++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+)
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index c55019f0f7a..73d90f1a77e 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -8890,6 +8890,380 @@ static void test_effect_parameter_block(void) DestroyWindow(window); }
+#if D3DX_SDK_VERSION >= 27 +#if 0 +bool b; +bool b_2[2]; +bool2 b2; +bool2 b2_2[2]; +bool4 b4; +bool4 b4_2[2]; +bool2x2 b22; +bool2x2 b22_2[2]; +bool4x4 b44; +bool4x4 b44_2[2]; + +int i; +int i_2[2]; +int2 i2; +int2 i2_2[2]; +int4 i4; +int4 i4_2[2]; +int2x2 i22; +int2x2 i22_2[2]; +int4x4 i44; +int4x4 i44_2[2]; + +float f; +float f_2[2]; +float2 f2; +float2 f2_2[2]; +float4 f4; +float4 f4_2[2]; +float2x2 f22; +float2x2 f22_2[2]; +float4x4 f44; +float4x4 f44_2[2]; + +technique t { pass p { } }; +#endif +static const DWORD test_set_raw_value_blob[] = +{ + 0xfeff0901, 0x00000848, 0x00000000, 0x00000001, 0x00000000, 0x00000024, 0x00000000, 0x00000000, + 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000062, 0x00000001, 0x00000000, 0x00000050, + 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00325f62, + 0x00000001, 0x00000001, 0x0000007c, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000000, + 0x00000000, 0x00000003, 0x00003262, 0x00000001, 0x00000001, 0x000000b0, 0x00000000, 0x00000002, + 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3262, + 0x00000000, 0x00000001, 0x00000001, 0x000000e8, 0x00000000, 0x00000000, 0x00000004, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003462, 0x00000001, 0x00000001, + 0x0000012c, 0x00000000, 0x00000002, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3462, 0x00000000, + 0x00000001, 0x00000002, 0x00000164, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00323262, 0x00000001, 0x00000002, 0x000001a8, + 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x5f323262, 0x00000032, 0x00000001, + 0x00000002, 0x00000210, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00343462, + 0x00000001, 0x00000002, 0x000002b4, 0x00000000, 0x00000002, 0x00000004, 0x00000004, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, + 0x5f343462, 0x00000032, 0x00000002, 0x00000000, 0x000002e0, 0x00000000, 0x00000000, 0x00000001, + 0x00000001, 0x00000000, 0x00000002, 0x00000069, 0x00000002, 0x00000000, 0x0000030c, 0x00000000, + 0x00000002, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00325f69, 0x00000002, + 0x00000001, 0x00000338, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, + 0x00000003, 0x00003269, 0x00000002, 0x00000001, 0x0000036c, 0x00000000, 0x00000002, 0x00000002, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3269, 0x00000000, + 0x00000002, 0x00000001, 0x000003a4, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003469, 0x00000002, 0x00000001, 0x000003e8, + 0x00000000, 0x00000002, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3469, 0x00000000, 0x00000002, + 0x00000002, 0x00000420, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00323269, 0x00000002, 0x00000002, 0x00000464, 0x00000000, + 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x5f323269, 0x00000032, 0x00000002, 0x00000002, + 0x000004cc, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00343469, 0x00000002, + 0x00000002, 0x00000570, 0x00000000, 0x00000002, 0x00000004, 0x00000004, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x5f343469, + 0x00000032, 0x00000003, 0x00000000, 0x0000059c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x00000000, 0x00000002, 0x00000066, 0x00000003, 0x00000000, 0x000005c8, 0x00000000, 0x00000002, + 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00325f66, 0x00000003, 0x00000001, + 0x000005f4, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000003, + 0x00003266, 0x00000003, 0x00000001, 0x00000628, 0x00000000, 0x00000002, 0x00000002, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3266, 0x00000000, 0x00000003, + 0x00000001, 0x00000660, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000003, 0x00003466, 0x00000003, 0x00000001, 0x000006a4, 0x00000000, + 0x00000002, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x325f3466, 0x00000000, 0x00000003, 0x00000002, + 0x000006dc, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000004, 0x00323266, 0x00000003, 0x00000002, 0x00000720, 0x00000000, 0x00000002, + 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000006, 0x5f323266, 0x00000032, 0x00000003, 0x00000002, 0x00000788, + 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00343466, 0x00000003, 0x00000002, + 0x0000082c, 0x00000000, 0x00000002, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x5f343466, 0x00000032, + 0x00000002, 0x00000070, 0x00000002, 0x00000074, 0x0000001e, 0x00000001, 0x00000001, 0x00000001, + 0x00000004, 0x00000020, 0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000, 0x00000000, + 0x00000058, 0x00000074, 0x00000000, 0x00000000, 0x00000084, 0x000000a0, 0x00000000, 0x00000000, + 0x000000bc, 0x000000d8, 0x00000000, 0x00000000, 0x000000f0, 0x0000010c, 0x00000000, 0x00000000, + 0x00000138, 0x00000154, 0x00000000, 0x00000000, 0x0000016c, 0x00000188, 0x00000000, 0x00000000, + 0x000001b4, 0x000001d0, 0x00000000, 0x00000000, 0x00000218, 0x00000234, 0x00000000, 0x00000000, + 0x000002c0, 0x000002dc, 0x00000000, 0x00000000, 0x000002e8, 0x00000304, 0x00000000, 0x00000000, + 0x00000314, 0x00000330, 0x00000000, 0x00000000, 0x00000340, 0x0000035c, 0x00000000, 0x00000000, + 0x00000378, 0x00000394, 0x00000000, 0x00000000, 0x000003ac, 0x000003c8, 0x00000000, 0x00000000, + 0x000003f4, 0x00000410, 0x00000000, 0x00000000, 0x00000428, 0x00000444, 0x00000000, 0x00000000, + 0x00000470, 0x0000048c, 0x00000000, 0x00000000, 0x000004d4, 0x000004f0, 0x00000000, 0x00000000, + 0x0000057c, 0x00000598, 0x00000000, 0x00000000, 0x000005a4, 0x000005c0, 0x00000000, 0x00000000, + 0x000005d0, 0x000005ec, 0x00000000, 0x00000000, 0x000005fc, 0x00000618, 0x00000000, 0x00000000, + 0x00000634, 0x00000650, 0x00000000, 0x00000000, 0x00000668, 0x00000684, 0x00000000, 0x00000000, + 0x000006b0, 0x000006cc, 0x00000000, 0x00000000, 0x000006e4, 0x00000700, 0x00000000, 0x00000000, + 0x0000072c, 0x00000748, 0x00000000, 0x00000000, 0x00000790, 0x000007ac, 0x00000000, 0x00000000, + 0x00000840, 0x00000000, 0x00000001, 0x00000838, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static void test_effect_set_raw_value(IDirect3DDevice9 *device) +{ + static const char *param_type_str[] = { "b", "i", "f" }; + static const struct + { + const char *suffix; + UINT value_offset; + UINT value_bytes; + union + { + float f[32]; + DWORD dword[32]; + } value; + union + { + float f[32]; + DWORD dword[32]; + } expected_value; + BOOL todo_hr; + } raw_value_tests[] = + { + { NULL, 0, 4, + { .f = { 1.0f } }, + { .f = { 1.0f } }, + .todo_hr = TRUE + }, + { "_2", 0, 8, + { .f = { 1.0f, 2.0f } }, + { .f = { 1.0f, 0.0f } }, + .todo_hr = TRUE + }, + /* Offset of 4, nothing gets set. */ + { "_2", 4, 4, + { .f = { 1.0f } }, + { .f = { 0.0f, 0.0f } }, + .todo_hr = TRUE + }, + /* + * To set the second value in the array, we need to start at an offset + * of 16. + */ + { "_2", 16, 4, + { .f = { 2.0f } }, + { .f = { 0.0f, 2.0f } }, + .todo_hr = TRUE + }, + { "2", 0, 8, + { .f = { 0.0f, 1.0f } }, + { .f = { 0.0f, 1.0f } }, + .todo_hr = TRUE + }, + /* 5. */ + { "2_2", 0, 16, + { .f = { 0.0f, 1.0f, 0.0f, 2.0f } }, + { .f = { 0.0f, 1.0f, 0.0f, 0.0f } }, + .todo_hr = TRUE + }, + { "2_2", 0, 24, + { .f = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 0.0f } }, + { .f = { 0.0f, 1.0f, 4.0f, 0.0f } }, + .todo_hr = TRUE + }, + { "4", 0, 16, + { .f = { 1.0f, 2.0f, 0.0f, 3.0f } }, + { .f = { 1.0f, 2.0f, 0.0f, 3.0f } }, + .todo_hr = TRUE + }, + { "4_2", 0, 32, + { .f = { 2.0f, 0.0f, 0.0f, 8.0f, 3.0f, 4.0f, 0.0f, 5.0f } }, + { .f = { 2.0f, 0.0f, 0.0f, 8.0f, 3.0f, 4.0f, 0.0f, 5.0f } }, + .todo_hr = TRUE + }, + { "22", 0, 64, + { .f = { 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 0.0f, + 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 0.0f } + }, + { .f = { 1.0f, 5.0f, 2.0f, 6.0f } }, + .todo_hr = TRUE + }, + /* 10. */ + { "22_2", 0, 128, + { .f = { 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 0.0f, + 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 0.0f, + /* Matrix 2. */ + 15.0f, 16.0f, 17.0f, 18.0f, + 19.0f, 20.0f, 21.0f, 22.0f, + 23.0f, 24.0f, 25.0f, 26.0f, + 27.0f, 28.0f, 29.0f, 30.0f } + }, + { .f = { 1.0f, 5.0f, 2.0f, 6.0f, 15.0f, 19.0f, 16.0f, 20.0f } }, + .todo_hr = TRUE + }, + { "44", 0, 64, + { .f = { 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 0.0f, + 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 0.0f } + }, + { .f = { 1.0f, 5.0f, 8.0f, 12.0f, + 2.0f, 6.0f, 9.0f, 13.0f, + 3.0f, 7.0f, 10.0f, 14.0f, + 4.0f, 0.0f, 11.0f, 0.0f } + }, + .todo_hr = TRUE + }, + { "44_2", 0, 128, + { .f = { 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 0.0f, + 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 0.0f, + /* Matrix 2. */ + 15.0f, 16.0f, 17.0f, 18.0f, + 19.0f, 20.0f, 21.0f, 22.0f, + 23.0f, 24.0f, 25.0f, 26.0f, + 27.0f, 28.0f, 29.0f, 30.0f } + }, + { .f = { 1.0f, 5.0f, 8.0f, 12.0f, + 2.0f, 6.0f, 9.0f, 13.0f, + 3.0f, 7.0f, 10.0f, 14.0f, + 4.0f, 0.0f, 11.0f, 0.0f, + /* Matrix 2. */ + 15.0f, 19.0f, 23.0f, 27.0f, + 16.0f, 20.0f, 24.0f, 28.0f, + 17.0f, 21.0f, 25.0f, 29.0f, + 18.0f, 22.0f, 26.0f, 30.0f } + }, + .todo_hr = TRUE + }, + /* Set second element. */ + { "44_2", 64, 64, + { .f = { 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 0.0f, + 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 0.0f } + }, + { .f = { 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, + /* Matrix 2. */ + 1.0f, 5.0f, 8.0f, 12.0f, + 2.0f, 6.0f, 9.0f, 13.0f, + 3.0f, 7.0f, 10.0f, 14.0f, + 4.0f, 0.0f, 11.0f, 0.0f } + }, + .todo_hr = TRUE + }, + }; + static const DWORD test_int_val[] = { 1, 2, 3, 4 }; + D3DXPARAMETER_DESC param_desc; + D3DXHANDLE param, param2; + unsigned int i, j, k; + char param_name[64]; + ID3DXEffect *effect; + ULONG refcount; + DWORD tmp[32]; + HRESULT hr; + + hr = D3DXCreateEffect(device, test_set_raw_value_blob, + sizeof(test_set_raw_value_blob), NULL, NULL, 0, NULL, &effect, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(raw_value_tests); ++i) + { + for (j = 0; j < ARRAY_SIZE(param_type_str); ++j) + { + strcpy(param_name, param_type_str[j]); + if (raw_value_tests[i].suffix) + strcat(param_name, raw_value_tests[i].suffix); + + winetest_push_context("Test %u (param %s)", i, param_name); + param = effect->lpVtbl->GetParameterByName(effect, NULL, param_name); + + hr = effect->lpVtbl->GetParameterDesc(effect, param, ¶m_desc); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* Clear our values first. */ + memset(tmp, 0, sizeof(tmp)); + hr = effect->lpVtbl->SetValue(effect, param, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = effect->lpVtbl->SetRawValue(effect, param, raw_value_tests[i].value.dword, raw_value_tests[i].value_offset, + raw_value_tests[i].value_bytes); + todo_wine_if(raw_value_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + unsigned int unexpected_values = 0; + + hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + for (k = 0; k < (param_desc.Bytes / 4); ++k) + { + const DWORD *expected_val = &raw_value_tests[i].expected_value.dword[k]; + DWORD *ret_val = &tmp[k]; + + if (param_desc.Type == D3DXPT_BOOL && (!!(*expected_val) != (*ret_val))) + unexpected_values++; + else if (param_desc.Type != D3DXPT_BOOL && memcmp(ret_val, expected_val, sizeof(*ret_val))) + unexpected_values++; + } + + todo_wine_if(param_desc.Type == D3DXPT_BOOL) ok(!unexpected_values, + "Got %u unexpected values.\n", unexpected_values); + } + winetest_pop_context(); + } + } + + param = effect->lpVtbl->GetParameterByName(effect, NULL, "i4"); + param2 = effect->lpVtbl->GetParameterByName(effect, NULL, "i44"); + + /* Test setting with a size of 0. */ + hr = effect->lpVtbl->SetRawValue(effect, param, tmp, 0, 0); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = effect->lpVtbl->SetRawValue(effect, param2, tmp, 0, 0); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + param = effect->lpVtbl->GetParameterByName(effect, NULL, "i4"); + param2 = effect->lpVtbl->GetParameterByName(effect, NULL, "i4_2"); + + /* Test setting adjacent variables. */ + memset(tmp, 0, sizeof(tmp)); + hr = effect->lpVtbl->SetValue(effect, param, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = effect->lpVtbl->SetValue(effect, param2, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* An offset of 16 bytes on variable i4 sets adjacent variable i4_2. */ + hr = effect->lpVtbl->SetRawValue(effect, param, test_int_val, 16, sizeof(test_int_val)); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + ok(!tmp[0], "Unexpected value.\n"); + + hr = effect->lpVtbl->GetValue(effect, param2, tmp, sizeof(tmp)); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!memcmp(tmp, test_int_val, sizeof(test_int_val)), "Got unexpected values.\n"); + + refcount = effect->lpVtbl->Release(effect); + ok(!refcount, "Unexpected refcount %lu.\n", refcount); +} +#endif /* D3DX_SDK_VERSION >= 27 */ + START_TEST(effect) { IDirect3DDevice9 *device; @@ -8918,6 +9292,9 @@ START_TEST(effect) test_effect_large_address_aware_flag(device); test_effect_get_pass_desc(device); test_effect_skip_constants(device); +#if D3DX_SDK_VERSION >= 27 + test_effect_set_raw_value(device); +#endif
refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %lu references left.\n", refcount);
From: Connor McAdams cmcadams@codeweavers.com
Add support for setting vec4 effect parameters.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/effect.c | 42 +++++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/effect.c | 4 +--- 2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 628d8ebc3eb..67eaf2b5d63 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -4431,10 +4431,46 @@ static HRESULT WINAPI d3dx_effect_CloneEffect(ID3DXEffect *iface, IDirect3DDevic static HRESULT WINAPI d3dx_effect_SetRawValue(ID3DXEffect *iface, D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes) { - FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n", - iface, parameter, data, byte_offset, bytes); + struct d3dx_effect *effect = impl_from_ID3DXEffect(iface); + struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
- return E_NOTIMPL; + TRACE("iface %p, parameter %p, data %p, byte_offset %u, bytes %u.\n", iface, parameter, data, byte_offset, bytes); + + if (!param) + { + WARN("Invalid parameter %p specified.\n", parameter); + return D3DERR_INVALIDCALL; + } + + switch (param->class) + { + case D3DXPC_VECTOR: + { + uint8_t *dst_data; + + if (param->columns != 4) + { + FIXME("Vec%u parameters are currently unsupported.\n", param->columns); + return E_NOTIMPL; + } + + if ((byte_offset + bytes) > param->bytes) + { + FIXME("Writing adjacent parameters is currently unsupported.\n"); + return E_NOTIMPL; + } + + dst_data = param_get_data_and_dirtify(effect, param, !byte_offset ? bytes : param->bytes, TRUE); + memcpy(dst_data + byte_offset, data, bytes); + break; + } + + default: + FIXME("Unhandled parameter class %s.\n", debug_d3dxparameter_class(param->class)); + return E_NOTIMPL; + } + + return D3D_OK; } #endif
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 73d90f1a77e..9063e3160ca 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -9079,12 +9079,10 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) { "4", 0, 16, { .f = { 1.0f, 2.0f, 0.0f, 3.0f } }, { .f = { 1.0f, 2.0f, 0.0f, 3.0f } }, - .todo_hr = TRUE }, { "4_2", 0, 32, { .f = { 2.0f, 0.0f, 0.0f, 8.0f, 3.0f, 4.0f, 0.0f, 5.0f } }, { .f = { 2.0f, 0.0f, 0.0f, 8.0f, 3.0f, 4.0f, 0.0f, 5.0f } }, - .todo_hr = TRUE }, { "22", 0, 64, { .f = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -9232,7 +9230,7 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device)
/* Test setting with a size of 0. */ hr = effect->lpVtbl->SetRawValue(effect, param, tmp, 0, 0); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = effect->lpVtbl->SetRawValue(effect, param2, tmp, 0, 0); todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/effect.c | 31 +++++++++++++++++++++++++++++++ dlls/d3dx9_36/tests/effect.c | 5 +---- 2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 67eaf2b5d63..75ce872e2c4 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -4465,6 +4465,37 @@ static HRESULT WINAPI d3dx_effect_SetRawValue(ID3DXEffect *iface, D3DXHANDLE par break; }
+ case D3DXPC_MATRIX_ROWS: + { + D3DXMATRIX *dst_elem; + uint8_t *dst_data; + unsigned int i; + + if (param->columns != 4 || param->rows != 4) + { + FIXME("%ux%u matrix parameters are currently unsupported.\n", param->rows, param->columns); + return E_NOTIMPL; + } + + if (byte_offset & 0x3f || bytes & 0x3f) + { + FIXME("Partial matrix updates are currently unsupported.\n"); + return E_NOTIMPL; + } + + if ((byte_offset + bytes) > param->bytes) + { + FIXME("Writing adjacent parameters is currently unsupported.\n"); + return E_NOTIMPL; + } + + dst_data = param_get_data_and_dirtify(effect, param, !byte_offset ? bytes : param->bytes, TRUE); + dst_elem = (D3DXMATRIX *)(dst_data + byte_offset); + for (i = 0; i < (bytes / sizeof(D3DXMATRIX)); ++i) + D3DXMatrixTranspose(&dst_elem[i], &((const D3DXMATRIX *)data)[i]); + break; + } + default: FIXME("Unhandled parameter class %s.\n", debug_d3dxparameter_class(param->class)); return E_NOTIMPL; diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 9063e3160ca..b1434744a15 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -9119,7 +9119,6 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) 3.0f, 7.0f, 10.0f, 14.0f, 4.0f, 0.0f, 11.0f, 0.0f } }, - .todo_hr = TRUE }, { "44_2", 0, 128, { .f = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -9142,7 +9141,6 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) 17.0f, 21.0f, 25.0f, 29.0f, 18.0f, 22.0f, 26.0f, 30.0f } }, - .todo_hr = TRUE }, /* Set second element. */ { "44_2", 64, 64, @@ -9161,7 +9159,6 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) 3.0f, 7.0f, 10.0f, 14.0f, 4.0f, 0.0f, 11.0f, 0.0f } }, - .todo_hr = TRUE }, }; static const DWORD test_int_val[] = { 1, 2, 3, 4 }; @@ -9233,7 +9230,7 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = effect->lpVtbl->SetRawValue(effect, param2, tmp, 0, 0); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
param = effect->lpVtbl->GetParameterByName(effect, NULL, "i4"); param2 = effect->lpVtbl->GetParameterByName(effect, NULL, "i4_2");
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/effect.c | 17 ++++++++++++----- dlls/d3dx9_36/tests/effect.c | 3 +-- 2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 75ce872e2c4..d5442777afd 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -2453,6 +2453,7 @@ static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parame { struct d3dx_effect *effect = impl_from_ID3DXEffect(iface); struct d3dx_parameter *param = get_valid_parameter(effect, parameter); + unsigned int i;
TRACE("iface %p, parameter %p, data %p, bytes %u.\n", iface, parameter, data, bytes);
@@ -2474,12 +2475,22 @@ static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parame switch (param->type) { case D3DXPT_VOID: - case D3DXPT_BOOL: case D3DXPT_INT: case D3DXPT_FLOAT: case D3DXPT_STRING: break;
+ case D3DXPT_BOOL: + { + BOOL *src = (BOOL *)param->data; + BOOL *dst = (BOOL *)data; + + for (i = 0; i < (param->bytes / sizeof(*src)); ++i) + dst[i] = !!src[i]; + + return D3D_OK; + } + case D3DXPT_VERTEXSHADER: case D3DXPT_PIXELSHADER: case D3DXPT_TEXTURE: @@ -2487,9 +2498,6 @@ static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parame case D3DXPT_TEXTURE2D: case D3DXPT_TEXTURE3D: case D3DXPT_TEXTURECUBE: - { - unsigned int i; - for (i = 0; i < (param->element_count ? param->element_count : 1); ++i) { IUnknown *unk = ((IUnknown **)param->data)[i]; @@ -2497,7 +2505,6 @@ static HRESULT WINAPI d3dx_effect_GetValue(ID3DXEffect *iface, D3DXHANDLE parame IUnknown_AddRef(unk); } break; - }
default: FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(param->type)); diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index b1434744a15..482704e9643 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -9215,8 +9215,7 @@ static void test_effect_set_raw_value(IDirect3DDevice9 *device) unexpected_values++; }
- todo_wine_if(param_desc.Type == D3DXPT_BOOL) ok(!unexpected_values, - "Got %u unexpected values.\n", unexpected_values); + ok(!unexpected_values, "Got %u unexpected values.\n", unexpected_values); } winetest_pop_context(); }
Nikolay Sivov (@nsivov) commented about dlls/d3dx9_36/tests/effect.c:
+int4x4 i44_2[2];
+float f; +float f_2[2]; +float2 f2; +float2 f2_2[2]; +float4 f4; +float4 f4_2[2]; +float2x2 f22; +float2x2 f22_2[2]; +float4x4 f44; +float4x4 f44_2[2];
+technique t { pass p { } }; +#endif +static const DWORD test_set_raw_value_blob[] =
We potentially don't need this, this test effect should compile with current vkd3d-shader/d3dcompiler in wine tree. I haven't tried to see if it compiles correctly.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/effect.c:
- {
const char *suffix;
UINT value_offset;
UINT value_bytes;
union
{
float f[32];
DWORD dword[32];
} value;
union
{
float f[32];
DWORD dword[32];
} expected_value;
BOOL todo_hr;
- } raw_value_tests[] =
Just curious: why the explicit name here? Were there multiple `tests` arrays at some point?
On Wed Mar 5 18:16:17 2025 +0000, Nikolay Sivov wrote:
We potentially don't need this, this test effect should compile with current vkd3d-shader/d3dcompiler in wine tree. I haven't tried to see if it compiles correctly.
Probably worth a try :slight_smile:
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/effect.c:
float f[32];
DWORD dword[32];
} expected_value;
BOOL todo_hr;
- } raw_value_tests[] =
- {
{ NULL, 0, 4,
{ .f = { 1.0f } },
{ .f = { 1.0f } },
.todo_hr = TRUE
},
{ "_2", 0, 8,
{ .f = { 1.0f, 2.0f } },
{ .f = { 1.0f, 0.0f } },
.todo_hr = TRUE
},
FWIW, I added one more test here before reading further (test 6 basically covers the same): ```suggestion:-4+0 { "_2", 0, 8, { .f = { 1.0f, 2.0f } }, { .f = { 1.0f, 0.0f } }, .todo_hr = TRUE }, { "_2", 0, 20, { .f = { 1.0f, 2.0f, 0.0f, 0.0f, 3.0f } }, { .f = { 1.0f, 3.0f, 0.0f, 0.0f, 0.0f } }, .todo_hr = TRUE }, ``` I also changed the code below to have the `memcmp()` go for `param_desc.Rows * 4 * param_desc.Elements` DWORDs and cleared `tmp` before each iteration.
I don't think adding this test is particularly necessary, or even a good idea. Same WRT changing the inner `for` loop end condition. I'll come back to the other change below.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/effect.c:
hr = effect->lpVtbl->GetParameterDesc(effect, param, ¶m_desc);
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
/* Clear our values first. */
memset(tmp, 0, sizeof(tmp));
hr = effect->lpVtbl->SetValue(effect, param, tmp, sizeof(tmp));
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = effect->lpVtbl->SetRawValue(effect, param, raw_value_tests[i].value.dword, raw_value_tests[i].value_offset,
raw_value_tests[i].value_bytes);
todo_wine_if(raw_value_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
if (SUCCEEDED(hr))
{
unsigned int unexpected_values = 0;
hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp));
Maybe it's worth considering something like: ```suggestion:-0+0 memset(tmp, 0xff, sizeof(tmp)); hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp)); ``` And then checking after the `for` loop, see below.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/effect.c:
{
unsigned int unexpected_values = 0;
hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp));
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
for (k = 0; k < (param_desc.Bytes / 4); ++k)
{
const DWORD *expected_val = &raw_value_tests[i].expected_value.dword[k];
DWORD *ret_val = &tmp[k];
if (param_desc.Type == D3DXPT_BOOL && (!!(*expected_val) != (*ret_val)))
unexpected_values++;
else if (param_desc.Type != D3DXPT_BOOL && memcmp(ret_val, expected_val, sizeof(*ret_val)))
unexpected_values++;
}
```suggestion:-0+0 } for (; k < ARRAY_SIZE(tmp); ++k) { if (tmp[k] != 0xffffffffu) unexpected_values++; } ``` I haven't checked if we already have a similar test for `GetValue()` though.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/effect.c:
static HRESULT WINAPI d3dx_effect_SetRawValue(ID3DXEffect *iface, D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes) {
- FIXME("iface %p, parameter %p, data %p, byte_offset %u, bytes %u stub!\n",
iface, parameter, data, byte_offset, bytes);
- struct d3dx_effect *effect = impl_from_ID3DXEffect(iface);
- struct d3dx_parameter *param = get_valid_parameter(effect, parameter);
- return E_NOTIMPL;
- TRACE("iface %p, parameter %p, data %p, byte_offset %u, bytes %u.\n", iface, parameter, data, byte_offset, bytes);
- if (!param)
- {
WARN("Invalid parameter %p specified.\n", parameter);
return D3DERR_INVALIDCALL;
- }
Not that I expect any surprises here, but currently we don't seem to have a test for this.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/effect.c:
/* Clear our values first. */
memset(tmp, 0, sizeof(tmp));
hr = effect->lpVtbl->SetValue(effect, param, tmp, sizeof(tmp));
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = effect->lpVtbl->SetRawValue(effect, param, raw_value_tests[i].value.dword, raw_value_tests[i].value_offset,
raw_value_tests[i].value_bytes);
todo_wine_if(raw_value_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
if (SUCCEEDED(hr))
{
unsigned int unexpected_values = 0;
hr = effect->lpVtbl->GetValue(effect, param, tmp, sizeof(tmp));
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
for (k = 0; k < (param_desc.Bytes / 4); ++k)
```suggestion:-0+0 for (k = 0; k < (param_desc.Bytes / sizeof(*tmp)); ++k) ``` or something along those lines.
I've only got a few minor comments, largely looks good.
I think Elizabeth mentioned on IRC that the old staging patch had a `Wine-Bug:` tag that could be brought over here.
On Sun Mar 9 11:18:04 2025 +0000, Matteo Bruni wrote:
I've only got a few minor comments, largely looks good. I think Elizabeth mentioned on IRC that the old staging patch had a `Wine-Bug:` tag that could be brought over here.
For reference here are the bug reports mentioning `SetRawValue()`: https://bugs.winehq.org/show_bug.cgi?id=46012 https://bugs.winehq.org/show_bug.cgi?id=44795