Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 4 +++ dlls/d3d10/tests/effect.c | 59 +++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 34 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 5da8d2065f7..5e65ad3f4be 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -4865,6 +4865,7 @@ static BOOL get_value_as_bool(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_typ { case D3D10_SVT_FLOAT: case D3D10_SVT_INT: + case D3D10_SVT_UINT: case D3D10_SVT_BOOL: if (*(DWORD *)src_data) return -1; @@ -4885,6 +4886,7 @@ static int get_value_as_int(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_type) return (int)(*(float *)src_data);
case D3D10_SVT_INT: + case D3D10_SVT_UINT: return *(int *)src_data;
case D3D10_SVT_BOOL: @@ -4903,6 +4905,7 @@ static float get_value_as_float(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_t return *(float *)src_data;
case D3D10_SVT_INT: + case D3D10_SVT_UINT: return (float)(*(int *)src_data);
case D3D10_SVT_BOOL: @@ -4933,6 +4936,7 @@ static void get_vector_as_type(BYTE *dst_data, D3D_SHADER_VARIABLE_TYPE dst_type break;
case D3D10_SVT_INT: + case D3D10_SVT_UINT: *(int *)dst_data_dword = get_value_as_int(src_data_dword, src_type); break;
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index a8a64a6ed0d..149328301e1 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4843,43 +4843,32 @@ cbuffer cb float f0, f_a[2]; int i0, i_a[2]; bool b0, b_a[2]; + uint i1, i1_a[2]; }; #endif static DWORD fx_test_scalar_variable[] = { - 0x43425844, 0xe4da4aa6, 0x1380ddc5, 0x445edad5, - 0x08581666, 0x00000001, 0x0000020b, 0x00000001, - 0x00000024, 0x30315846, 0x000001df, 0xfeff1001, - 0x00000001, 0x00000006, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x000000d3, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x66006263, - 0x74616f6c, 0x00000700, 0x00000100, 0x00000000, - 0x00000400, 0x00001000, 0x00000400, 0x00090900, - 0x00306600, 0x00000007, 0x00000001, 0x00000002, - 0x00000014, 0x00000010, 0x00000008, 0x00000909, - 0x00615f66, 0x00746e69, 0x0000004c, 0x00000001, - 0x00000000, 0x00000004, 0x00000010, 0x00000004, - 0x00000911, 0x4c003069, 0x01000000, 0x02000000, - 0x14000000, 0x10000000, 0x08000000, 0x11000000, - 0x69000009, 0x6200615f, 0x006c6f6f, 0x0000008f, - 0x00000001, 0x00000000, 0x00000004, 0x00000010, - 0x00000004, 0x00000921, 0x8f003062, 0x01000000, - 0x02000000, 0x14000000, 0x10000000, 0x08000000, - 0x21000000, 0x62000009, 0x0400615f, 0x70000000, - 0x00000000, 0x06000000, 0xff000000, 0x00ffffff, - 0x29000000, 0x0d000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x48000000, - 0x2c000000, 0x00000000, 0x10000000, 0x00000000, - 0x00000000, 0x00000000, 0x6c000000, 0x50000000, - 0x00000000, 0x24000000, 0x00000000, 0x00000000, - 0x00000000, 0x8b000000, 0x6f000000, 0x00000000, - 0x30000000, 0x00000000, 0x00000000, 0x00000000, - 0xb0000000, 0x94000000, 0x00000000, 0x44000000, - 0x00000000, 0x00000000, 0x00000000, 0xcf000000, - 0xb3000000, 0x00000000, 0x50000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, + 0x43425844, 0x7d97f44c, 0x1da4b110, 0xb710407e, 0x26750c1c, 0x00000001, 0x00000288, 0x00000001, + 0x00000024, 0x30315846, 0x0000025c, 0xfeff1001, 0x00000001, 0x00000008, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000118, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66006263, + 0x74616f6c, 0x00000700, 0x00000100, 0x00000000, 0x00000400, 0x00001000, 0x00000400, 0x00090900, + 0x00306600, 0x00000007, 0x00000001, 0x00000002, 0x00000014, 0x00000010, 0x00000008, 0x00000909, + 0x00615f66, 0x00746e69, 0x0000004c, 0x00000001, 0x00000000, 0x00000004, 0x00000010, 0x00000004, + 0x00000911, 0x4c003069, 0x01000000, 0x02000000, 0x14000000, 0x10000000, 0x08000000, 0x11000000, + 0x69000009, 0x6200615f, 0x006c6f6f, 0x0000008f, 0x00000001, 0x00000000, 0x00000004, 0x00000010, + 0x00000004, 0x00000921, 0x8f003062, 0x01000000, 0x02000000, 0x14000000, 0x10000000, 0x08000000, + 0x21000000, 0x62000009, 0x7500615f, 0x00746e69, 0x000000d3, 0x00000001, 0x00000000, 0x00000004, + 0x00000010, 0x00000004, 0x00000919, 0xd3003169, 0x01000000, 0x02000000, 0x14000000, 0x10000000, + 0x08000000, 0x19000000, 0x69000009, 0x00615f31, 0x00000004, 0x00000090, 0x00000000, 0x00000008, + 0xffffffff, 0x00000000, 0x00000029, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000048, 0x0000002c, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000, + 0x0000006c, 0x00000050, 0x00000000, 0x00000024, 0x00000000, 0x00000000, 0x00000000, 0x0000008b, + 0x0000006f, 0x00000000, 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x000000b0, 0x00000094, + 0x00000000, 0x00000044, 0x00000000, 0x00000000, 0x00000000, 0x000000cf, 0x000000b3, 0x00000000, + 0x00000050, 0x00000000, 0x00000000, 0x00000000, 0x000000f4, 0x000000d8, 0x00000000, 0x00000064, + 0x00000000, 0x00000000, 0x00000000, 0x00000113, 0x000000f7, 0x00000000, 0x00000070, 0x00000000, + 0x00000000, 0x00000000, };
static void test_scalar_methods(ID3D10EffectScalarVariable *var, D3D10_SHADER_VARIABLE_TYPE type, @@ -5145,9 +5134,11 @@ static void test_effect_scalar_variable(void) { {"f0", D3D10_SVT_FLOAT}, {"i0", D3D10_SVT_INT}, + {"i1", D3D10_SVT_UINT}, {"b0", D3D10_SVT_BOOL}, {"f_a", D3D10_SVT_FLOAT, TRUE}, {"i_a", D3D10_SVT_INT, TRUE}, + {"i1_a", D3D10_SVT_UINT, TRUE}, {"b_a", D3D10_SVT_BOOL, TRUE}, }; ID3D10EffectScalarVariable *s_v, *s_v2; @@ -5178,7 +5169,7 @@ static void test_effect_scalar_variable(void) effect_desc.ConstantBuffers); ok(effect_desc.SharedConstantBuffers == 0, "Unexpected shared constant buffers count %u.\n", effect_desc.SharedConstantBuffers); - ok(effect_desc.GlobalVariables == 6, "Unexpected global variables count %u.\n", + ok(effect_desc.GlobalVariables == 8, "Unexpected global variables count %u.\n", effect_desc.GlobalVariables); ok(effect_desc.SharedGlobalVariables == 0, "Unexpected shared global variables count %u.\n", effect_desc.SharedGlobalVariables);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 4 + dlls/d3d10/tests/effect.c | 160 +++++++++++++++++++++----------------- 2 files changed, 92 insertions(+), 72 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 5e65ad3f4be..0a6256d7ebd 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1695,6 +1695,10 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, *(void **)out_data = &null_shader_resource_variable; break;
+ case D3D10_SVT_DEPTHSTENCIL: + *(void **)out_data = &null_depth_stencil_variable; + break; + default: FIXME("Unhandled out_type %#x.\n", out_type); return FALSE; diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 149328301e1..87b591e3af8 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4216,13 +4216,17 @@ technique10 tech0 { SetPixelShader( CompileShader(ps_4_0, PS()) ); } + pass pass2 + { + SetDepthStencilState(NULL, 0); + } }; #endif static DWORD fx_test_state_groups[] = { - 0x43425844, 0x61e5a938, 0x1d4228df, 0x536560dd, 0x76c777b2, 0x00000001, 0x000011ce, 0x00000001, - 0x00000024, 0x30315846, 0x000011a2, 0xfeff1001, 0x00000000, 0x00000000, 0x00000029, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x00000922, 0x00000000, 0x00000024, 0x00000001, 0x00000001, + 0x43425844, 0xefc189be, 0xdf31b02d, 0x77de2d1a, 0x7b97922c, 0x00000001, 0x00001218, 0x00000001, + 0x00000024, 0x30315846, 0x000011ec, 0xfeff1001, 0x00000000, 0x00000000, 0x00000029, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000940, 0x00000000, 0x00000024, 0x00000001, 0x00000001, 0x00000001, 0x00000014, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x74736152, 0x7a697265, 0x74537265, 0x00657461, 0x00000004, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x74736172, 0x6174735f, 0x01006574, 0x02000000, 0x02000000, 0x01000000, @@ -4296,73 +4300,75 @@ static DWORD fx_test_state_groups[] = 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07260000, 0x00000000, 0x00300000, 0x00140000, - 0x00000000, 0xffff0000, 0x000affff, 0x000c0000, 0x00000000, 0x00010000, 0x003b0000, 0x000d0000, - 0x00000000, 0x00010000, 0x00470000, 0x000e0000, 0x00000000, 0x00010000, 0x00530000, 0x000f0000, - 0x00000000, 0x00010000, 0x005f0000, 0x00100000, 0x00000000, 0x00010000, 0x006b0000, 0x00110000, - 0x00000000, 0x00010000, 0x00770000, 0x00120000, 0x00000000, 0x00010000, 0x00830000, 0x00130000, - 0x00000000, 0x00010000, 0x008f0000, 0x00140000, 0x00000000, 0x00010000, 0x009b0000, 0x00150000, - 0x00000000, 0x00010000, 0x00a70000, 0x00000000, 0x00e10000, 0x00c50000, 0x00000000, 0xffff0000, - 0x000effff, 0x00160000, 0x00000000, 0x00010000, 0x00ea0000, 0x00170000, 0x00000000, 0x00010000, - 0x00f60000, 0x00180000, 0x00000000, 0x00010000, 0x01020000, 0x00190000, 0x00000000, 0x00010000, - 0x010e0000, 0x001a0000, 0x00000000, 0x00010000, 0x011a0000, 0x001b0000, 0x00000000, 0x00010000, - 0x01260000, 0x001c0000, 0x00000000, 0x00010000, 0x01320000, 0x001d0000, 0x00000000, 0x00010000, - 0x013e0000, 0x001e0000, 0x00000000, 0x00010000, 0x014a0000, 0x001f0000, 0x00000000, 0x00010000, - 0x01560000, 0x00200000, 0x00000000, 0x00010000, 0x01620000, 0x00210000, 0x00000000, 0x00010000, - 0x016e0000, 0x00220000, 0x00000000, 0x00010000, 0x017a0000, 0x00230000, 0x00000000, 0x00010000, - 0x01860000, 0x00000000, 0x01b90000, 0x019d0000, 0x00000000, 0xffff0000, 0x000bffff, 0x00240000, - 0x00000000, 0x00010000, 0x01c50000, 0x00250000, 0x00000000, 0x00010000, 0x01d10000, 0x00250000, - 0x00070000, 0x00010000, 0x01dd0000, 0x00260000, 0x00000000, 0x00010000, 0x01e90000, 0x00270000, - 0x00000000, 0x00010000, 0x01f50000, 0x00280000, 0x00000000, 0x00010000, 0x02010000, 0x00290000, - 0x00000000, 0x00010000, 0x020d0000, 0x002a0000, 0x00000000, 0x00010000, 0x02190000, 0x002b0000, - 0x00000000, 0x00010000, 0x02250000, 0x002c0000, 0x00000000, 0x00010000, 0x02310000, 0x002c0000, - 0x00070000, 0x00010000, 0x023d0000, 0x00000000, 0x02720000, 0x02560000, 0x00000000, 0xffff0000, - 0x000bffff, 0x002d0000, 0x00000000, 0x00010000, 0x027b0000, 0x002e0000, 0x00000000, 0x00010000, - 0x02870000, 0x002f0000, 0x00000000, 0x00010000, 0x02930000, 0x00300000, 0x00000000, 0x00010000, - 0x029f0000, 0x00310000, 0x00000000, 0x00010000, 0x02ab0000, 0x00320000, 0x00000000, 0x00010000, - 0x02b70000, 0x00330000, 0x00000000, 0x00010000, 0x02c30000, 0x00340000, 0x00000000, 0x00010000, - 0x02cf0000, 0x00350000, 0x00000000, 0x00010000, 0x02f30000, 0x00360000, 0x00000000, 0x00010000, - 0x02ff0000, 0x00370000, 0x00000000, 0x00010000, 0x030b0000, 0x00000000, 0x033b0000, 0x031f0000, - 0x00000000, 0xffff0000, 0x0000ffff, 0x03640000, 0x03480000, 0x00000000, 0xffff0000, 0x0000ffff, - 0x03920000, 0x03760000, 0x00000000, 0xffff0000, 0x0000ffff, 0x03bc0000, 0x03a00000, 0x00000000, - 0xffff0000, 0x0000ffff, 0x03ea0000, 0x03ce0000, 0x00000000, 0xffff0000, 0x0000ffff, 0x04160000, - 0x03fa0000, 0x00000000, 0xffff0000, 0x0000ffff, 0x04490000, 0x042d0000, 0x00000000, 0xffff0000, - 0x0000ffff, 0x04760000, 0x045a0000, 0x00000000, 0xffff0000, 0x0000ffff, 0x04a10000, 0x04850000, - 0x00000000, 0xffff0000, 0x0000ffff, 0x04a40000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, - 0x00370000, 0x00000000, 0x00020000, 0x033b0000, 0x00000000, 0x04ad0000, 0x02560000, 0x00000000, - 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00020000, 0x03640000, 0x00000000, 0x04b60000, - 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00020000, 0x03920000, - 0x00000000, 0x04c00000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, - 0x00020000, 0x03bc0000, 0x00000000, 0x04c90000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, - 0x00370000, 0x00000000, 0x00020000, 0x03ea0000, 0x00000000, 0x04d30000, 0x02560000, 0x00000000, - 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00020000, 0x04160000, 0x00000000, 0x04dc0000, - 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00020000, 0x04490000, - 0x00000000, 0x04e60000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, - 0x00020000, 0x04760000, 0x00000000, 0x04ef0000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, - 0x00370000, 0x00000000, 0x00020000, 0x04a10000, 0x00000000, 0x05140000, 0x04f80000, 0x00000000, - 0xffff0000, 0x0000ffff, 0x05350000, 0x05190000, 0x00000000, 0xffff0000, 0x0000ffff, 0x05560000, - 0x053a0000, 0x00000000, 0xffff0000, 0x0000ffff, 0x05780000, 0x055c0000, 0x00000000, 0xffff0000, - 0x0000ffff, 0x05990000, 0x057d0000, 0x00000000, 0xffff0000, 0x0000ffff, 0x05bb0000, 0x059f0000, - 0x00000000, 0xffff0000, 0x0000ffff, 0x05df0000, 0x05c30000, 0x00000000, 0xffff0000, 0x0000ffff, - 0x06040000, 0x05e80000, 0x00000000, 0xffff0000, 0x0000ffff, 0x06250000, 0x06090000, 0x00000000, - 0xffff0000, 0x0000ffff, 0x062a0000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, - 0x00000000, 0x00030000, 0x06330000, 0x00000000, 0x063b0000, 0x02560000, 0x00000000, 0xffff0000, - 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, 0x06440000, 0x00000000, 0x064c0000, 0x02560000, - 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, 0x06550000, 0x00000000, - 0x065d0000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, - 0x06670000, 0x00000000, 0x066f0000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, - 0x00000000, 0x00030000, 0x06790000, 0x00000000, 0x06810000, 0x02560000, 0x00000000, 0xffff0000, - 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, 0x068b0000, 0x00000000, 0x06930000, 0x02560000, - 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, 0x069d0000, 0x00000000, - 0x06a50000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, 0x00000000, 0x00030000, - 0x06af0000, 0x00000000, 0x06b70000, 0x02560000, 0x00000000, 0xffff0000, 0x0001ffff, 0x00370000, - 0x00000000, 0x00030000, 0x06c10000, 0x00000000, 0x06c90000, 0x02560000, 0x00000000, 0xffff0000, - 0x0001ffff, 0x00370000, 0x00000000, 0x00010000, 0x06cc0000, 0x00000000, 0x06d80000, 0x00020000, - 0x00000000, 0x06de0000, 0x00060000, 0x00000000, 0x000a0000, 0x00000000, 0x00010000, 0x06e40000, - 0x000b0000, 0x00000000, 0x00010000, 0x07080000, 0x00020000, 0x00000000, 0x00020000, 0x01b90000, - 0x00090000, 0x00000000, 0x00010000, 0x07140000, 0x00010000, 0x00000000, 0x00020000, 0x00e10000, - 0x00000000, 0x00000000, 0x00020000, 0x00300000, 0x07200000, 0x00010000, 0x00000000, 0x00070000, - 0x00000000, 0x00070000, 0x091a0000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07260000, 0x00000000, 0x61700000, 0x00327373, + 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000000, 0x00000030, 0x00000014, + 0x00000000, 0xffffffff, 0x0000000a, 0x0000000c, 0x00000000, 0x00000001, 0x0000003b, 0x0000000d, + 0x00000000, 0x00000001, 0x00000047, 0x0000000e, 0x00000000, 0x00000001, 0x00000053, 0x0000000f, + 0x00000000, 0x00000001, 0x0000005f, 0x00000010, 0x00000000, 0x00000001, 0x0000006b, 0x00000011, + 0x00000000, 0x00000001, 0x00000077, 0x00000012, 0x00000000, 0x00000001, 0x00000083, 0x00000013, + 0x00000000, 0x00000001, 0x0000008f, 0x00000014, 0x00000000, 0x00000001, 0x0000009b, 0x00000015, + 0x00000000, 0x00000001, 0x000000a7, 0x00000000, 0x000000e1, 0x000000c5, 0x00000000, 0xffffffff, + 0x0000000e, 0x00000016, 0x00000000, 0x00000001, 0x000000ea, 0x00000017, 0x00000000, 0x00000001, + 0x000000f6, 0x00000018, 0x00000000, 0x00000001, 0x00000102, 0x00000019, 0x00000000, 0x00000001, + 0x0000010e, 0x0000001a, 0x00000000, 0x00000001, 0x0000011a, 0x0000001b, 0x00000000, 0x00000001, + 0x00000126, 0x0000001c, 0x00000000, 0x00000001, 0x00000132, 0x0000001d, 0x00000000, 0x00000001, + 0x0000013e, 0x0000001e, 0x00000000, 0x00000001, 0x0000014a, 0x0000001f, 0x00000000, 0x00000001, + 0x00000156, 0x00000020, 0x00000000, 0x00000001, 0x00000162, 0x00000021, 0x00000000, 0x00000001, + 0x0000016e, 0x00000022, 0x00000000, 0x00000001, 0x0000017a, 0x00000023, 0x00000000, 0x00000001, + 0x00000186, 0x00000000, 0x000001b9, 0x0000019d, 0x00000000, 0xffffffff, 0x0000000b, 0x00000024, + 0x00000000, 0x00000001, 0x000001c5, 0x00000025, 0x00000000, 0x00000001, 0x000001d1, 0x00000025, + 0x00000007, 0x00000001, 0x000001dd, 0x00000026, 0x00000000, 0x00000001, 0x000001e9, 0x00000027, + 0x00000000, 0x00000001, 0x000001f5, 0x00000028, 0x00000000, 0x00000001, 0x00000201, 0x00000029, + 0x00000000, 0x00000001, 0x0000020d, 0x0000002a, 0x00000000, 0x00000001, 0x00000219, 0x0000002b, + 0x00000000, 0x00000001, 0x00000225, 0x0000002c, 0x00000000, 0x00000001, 0x00000231, 0x0000002c, + 0x00000007, 0x00000001, 0x0000023d, 0x00000000, 0x00000272, 0x00000256, 0x00000000, 0xffffffff, + 0x0000000b, 0x0000002d, 0x00000000, 0x00000001, 0x0000027b, 0x0000002e, 0x00000000, 0x00000001, + 0x00000287, 0x0000002f, 0x00000000, 0x00000001, 0x00000293, 0x00000030, 0x00000000, 0x00000001, + 0x0000029f, 0x00000031, 0x00000000, 0x00000001, 0x000002ab, 0x00000032, 0x00000000, 0x00000001, + 0x000002b7, 0x00000033, 0x00000000, 0x00000001, 0x000002c3, 0x00000034, 0x00000000, 0x00000001, + 0x000002cf, 0x00000035, 0x00000000, 0x00000001, 0x000002f3, 0x00000036, 0x00000000, 0x00000001, + 0x000002ff, 0x00000037, 0x00000000, 0x00000001, 0x0000030b, 0x00000000, 0x0000033b, 0x0000031f, + 0x00000000, 0xffffffff, 0x00000000, 0x00000364, 0x00000348, 0x00000000, 0xffffffff, 0x00000000, + 0x00000392, 0x00000376, 0x00000000, 0xffffffff, 0x00000000, 0x000003bc, 0x000003a0, 0x00000000, + 0xffffffff, 0x00000000, 0x000003ea, 0x000003ce, 0x00000000, 0xffffffff, 0x00000000, 0x00000416, + 0x000003fa, 0x00000000, 0xffffffff, 0x00000000, 0x00000449, 0x0000042d, 0x00000000, 0xffffffff, + 0x00000000, 0x00000476, 0x0000045a, 0x00000000, 0xffffffff, 0x00000000, 0x000004a1, 0x00000485, + 0x00000000, 0xffffffff, 0x00000000, 0x000004a4, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000002, 0x0000033b, 0x00000000, 0x000004ad, 0x00000256, 0x00000000, + 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000364, 0x00000000, 0x000004b6, + 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000392, + 0x00000000, 0x000004c0, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, + 0x00000002, 0x000003bc, 0x00000000, 0x000004c9, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000002, 0x000003ea, 0x00000000, 0x000004d3, 0x00000256, 0x00000000, + 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000416, 0x00000000, 0x000004dc, + 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000449, + 0x00000000, 0x000004e6, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, + 0x00000002, 0x00000476, 0x00000000, 0x000004ef, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000002, 0x000004a1, 0x00000000, 0x00000514, 0x000004f8, 0x00000000, + 0xffffffff, 0x00000000, 0x00000535, 0x00000519, 0x00000000, 0xffffffff, 0x00000000, 0x00000556, + 0x0000053a, 0x00000000, 0xffffffff, 0x00000000, 0x00000578, 0x0000055c, 0x00000000, 0xffffffff, + 0x00000000, 0x00000599, 0x0000057d, 0x00000000, 0xffffffff, 0x00000000, 0x000005bb, 0x0000059f, + 0x00000000, 0xffffffff, 0x00000000, 0x000005df, 0x000005c3, 0x00000000, 0xffffffff, 0x00000000, + 0x00000604, 0x000005e8, 0x00000000, 0xffffffff, 0x00000000, 0x00000625, 0x00000609, 0x00000000, + 0xffffffff, 0x00000000, 0x0000062a, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000003, 0x00000633, 0x00000000, 0x0000063b, 0x00000256, 0x00000000, 0xffffffff, + 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000644, 0x00000000, 0x0000064c, 0x00000256, + 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000655, 0x00000000, + 0x0000065d, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, + 0x00000667, 0x00000000, 0x0000066f, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000003, 0x00000679, 0x00000000, 0x00000681, 0x00000256, 0x00000000, 0xffffffff, + 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x0000068b, 0x00000000, 0x00000693, 0x00000256, + 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x0000069d, 0x00000000, + 0x000006a5, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, + 0x000006af, 0x00000000, 0x000006b7, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000003, 0x000006c1, 0x00000000, 0x000006c9, 0x00000256, 0x00000000, 0xffffffff, + 0x00000001, 0x00000037, 0x00000000, 0x00000001, 0x000006cc, 0x00000000, 0x000006d8, 0x00000003, + 0x00000000, 0x000006de, 0x00000006, 0x00000000, 0x0000000a, 0x00000000, 0x00000001, 0x000006e4, + 0x0000000b, 0x00000000, 0x00000001, 0x00000708, 0x00000002, 0x00000000, 0x00000002, 0x000001b9, + 0x00000009, 0x00000000, 0x00000001, 0x00000714, 0x00000001, 0x00000000, 0x00000002, 0x000000e1, + 0x00000000, 0x00000000, 0x00000002, 0x00000030, 0x00000720, 0x00000001, 0x00000000, 0x00000007, + 0x00000000, 0x00000007, 0x0000091a, 0x00000922, 0x00000002, 0x00000000, 0x00000009, 0x00000000, + 0x00000001, 0x00000928, 0x00000001, 0x00000000, 0x00000001, 0x00000934, };
static void create_effect_texture_resource(ID3D10Device *device, ID3D10ShaderResourceView **srv, @@ -4391,10 +4397,10 @@ static void create_effect_texture_resource(ID3D10Device *device, ID3D10ShaderRes
static void test_effect_state_groups(void) { + ID3D10DepthStencilState *ds_state, *ds_state2; ID3D10ShaderResourceView *srv0, *srv1; ID3D10EffectDepthStencilVariable *d; ID3D10EffectRasterizerVariable *r; - ID3D10DepthStencilState *ds_state; ID3D10RasterizerState *rast_state; ID3D10EffectTechnique *technique; D3D10_DEPTH_STENCIL_DESC ds_desc; @@ -4620,7 +4626,6 @@ static void test_effect_state_groups(void) rast_desc.AntialiasedLineEnable);
ID3D10RasterizerState_Release(rast_state); - ID3D10DepthStencilState_Release(ds_state); ID3D10BlendState_Release(blend_state);
/* pass 1 - uses SamplerState.Texture = NULL, resource slot is reset. */ @@ -4645,6 +4650,17 @@ static void test_effect_state_groups(void) ID3D10ShaderResourceView_Release(srv0); ID3D10Texture2D_Release(tex0);
+ /* pass 2 - NULL depth stencil state */ + pass = technique->lpVtbl->GetPassByName(technique, "pass2"); + ok(pass->lpVtbl->IsValid(pass), "Failed to get pass.\n"); + + ID3D10Device_OMSetDepthStencilState(device, ds_state, 0); + hr = pass->lpVtbl->Apply(pass, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ID3D10Device_OMGetDepthStencilState(device, &ds_state2, &stencil_ref); + ok(!ds_state2, "Unexpected depth stencil state.\n"); + + ID3D10DepthStencilState_Release(ds_state); effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 4 + dlls/d3d10/tests/effect.c | 154 ++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 73 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 0a6256d7ebd..901f800b623 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -1699,6 +1699,10 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, *(void **)out_data = &null_depth_stencil_variable; break;
+ case D3D10_SVT_BLEND: + *(void **)out_data = &null_blend_variable; + break; + default: FIXME("Unhandled out_type %#x.\n", out_type); return FALSE; diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index 87b591e3af8..a7a712edfb4 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -4219,14 +4219,15 @@ technique10 tech0 pass pass2 { SetDepthStencilState(NULL, 0); + SetBlendState(NULL, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffff); } }; #endif static DWORD fx_test_state_groups[] = { - 0x43425844, 0xefc189be, 0xdf31b02d, 0x77de2d1a, 0x7b97922c, 0x00000001, 0x00001218, 0x00000001, - 0x00000024, 0x30315846, 0x000011ec, 0xfeff1001, 0x00000000, 0x00000000, 0x00000029, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x00000940, 0x00000000, 0x00000024, 0x00000001, 0x00000001, + 0x43425844, 0x0c720f33, 0x6549d569, 0x9e62af53, 0xa210a455, 0x00000001, 0x00001284, 0x00000001, + 0x00000024, 0x30315846, 0x00001258, 0xfeff1001, 0x00000000, 0x00000000, 0x00000029, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x0000097c, 0x00000000, 0x00000024, 0x00000001, 0x00000001, 0x00000001, 0x00000014, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x74736152, 0x7a697265, 0x74537265, 0x00657461, 0x00000004, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x74736172, 0x6174735f, 0x01006574, 0x02000000, 0x02000000, 0x01000000, @@ -4301,74 +4302,78 @@ static DWORD fx_test_state_groups[] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07260000, 0x00000000, 0x61700000, 0x00327373, - 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000000, 0x00000030, 0x00000014, - 0x00000000, 0xffffffff, 0x0000000a, 0x0000000c, 0x00000000, 0x00000001, 0x0000003b, 0x0000000d, - 0x00000000, 0x00000001, 0x00000047, 0x0000000e, 0x00000000, 0x00000001, 0x00000053, 0x0000000f, - 0x00000000, 0x00000001, 0x0000005f, 0x00000010, 0x00000000, 0x00000001, 0x0000006b, 0x00000011, - 0x00000000, 0x00000001, 0x00000077, 0x00000012, 0x00000000, 0x00000001, 0x00000083, 0x00000013, - 0x00000000, 0x00000001, 0x0000008f, 0x00000014, 0x00000000, 0x00000001, 0x0000009b, 0x00000015, - 0x00000000, 0x00000001, 0x000000a7, 0x00000000, 0x000000e1, 0x000000c5, 0x00000000, 0xffffffff, - 0x0000000e, 0x00000016, 0x00000000, 0x00000001, 0x000000ea, 0x00000017, 0x00000000, 0x00000001, - 0x000000f6, 0x00000018, 0x00000000, 0x00000001, 0x00000102, 0x00000019, 0x00000000, 0x00000001, - 0x0000010e, 0x0000001a, 0x00000000, 0x00000001, 0x0000011a, 0x0000001b, 0x00000000, 0x00000001, - 0x00000126, 0x0000001c, 0x00000000, 0x00000001, 0x00000132, 0x0000001d, 0x00000000, 0x00000001, - 0x0000013e, 0x0000001e, 0x00000000, 0x00000001, 0x0000014a, 0x0000001f, 0x00000000, 0x00000001, - 0x00000156, 0x00000020, 0x00000000, 0x00000001, 0x00000162, 0x00000021, 0x00000000, 0x00000001, - 0x0000016e, 0x00000022, 0x00000000, 0x00000001, 0x0000017a, 0x00000023, 0x00000000, 0x00000001, - 0x00000186, 0x00000000, 0x000001b9, 0x0000019d, 0x00000000, 0xffffffff, 0x0000000b, 0x00000024, - 0x00000000, 0x00000001, 0x000001c5, 0x00000025, 0x00000000, 0x00000001, 0x000001d1, 0x00000025, - 0x00000007, 0x00000001, 0x000001dd, 0x00000026, 0x00000000, 0x00000001, 0x000001e9, 0x00000027, - 0x00000000, 0x00000001, 0x000001f5, 0x00000028, 0x00000000, 0x00000001, 0x00000201, 0x00000029, - 0x00000000, 0x00000001, 0x0000020d, 0x0000002a, 0x00000000, 0x00000001, 0x00000219, 0x0000002b, - 0x00000000, 0x00000001, 0x00000225, 0x0000002c, 0x00000000, 0x00000001, 0x00000231, 0x0000002c, - 0x00000007, 0x00000001, 0x0000023d, 0x00000000, 0x00000272, 0x00000256, 0x00000000, 0xffffffff, - 0x0000000b, 0x0000002d, 0x00000000, 0x00000001, 0x0000027b, 0x0000002e, 0x00000000, 0x00000001, - 0x00000287, 0x0000002f, 0x00000000, 0x00000001, 0x00000293, 0x00000030, 0x00000000, 0x00000001, - 0x0000029f, 0x00000031, 0x00000000, 0x00000001, 0x000002ab, 0x00000032, 0x00000000, 0x00000001, - 0x000002b7, 0x00000033, 0x00000000, 0x00000001, 0x000002c3, 0x00000034, 0x00000000, 0x00000001, - 0x000002cf, 0x00000035, 0x00000000, 0x00000001, 0x000002f3, 0x00000036, 0x00000000, 0x00000001, - 0x000002ff, 0x00000037, 0x00000000, 0x00000001, 0x0000030b, 0x00000000, 0x0000033b, 0x0000031f, - 0x00000000, 0xffffffff, 0x00000000, 0x00000364, 0x00000348, 0x00000000, 0xffffffff, 0x00000000, - 0x00000392, 0x00000376, 0x00000000, 0xffffffff, 0x00000000, 0x000003bc, 0x000003a0, 0x00000000, - 0xffffffff, 0x00000000, 0x000003ea, 0x000003ce, 0x00000000, 0xffffffff, 0x00000000, 0x00000416, - 0x000003fa, 0x00000000, 0xffffffff, 0x00000000, 0x00000449, 0x0000042d, 0x00000000, 0xffffffff, - 0x00000000, 0x00000476, 0x0000045a, 0x00000000, 0xffffffff, 0x00000000, 0x000004a1, 0x00000485, - 0x00000000, 0xffffffff, 0x00000000, 0x000004a4, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, - 0x00000037, 0x00000000, 0x00000002, 0x0000033b, 0x00000000, 0x000004ad, 0x00000256, 0x00000000, - 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000364, 0x00000000, 0x000004b6, - 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000392, - 0x00000000, 0x000004c0, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, - 0x00000002, 0x000003bc, 0x00000000, 0x000004c9, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, - 0x00000037, 0x00000000, 0x00000002, 0x000003ea, 0x00000000, 0x000004d3, 0x00000256, 0x00000000, - 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000416, 0x00000000, 0x000004dc, - 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000449, - 0x00000000, 0x000004e6, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, - 0x00000002, 0x00000476, 0x00000000, 0x000004ef, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, - 0x00000037, 0x00000000, 0x00000002, 0x000004a1, 0x00000000, 0x00000514, 0x000004f8, 0x00000000, - 0xffffffff, 0x00000000, 0x00000535, 0x00000519, 0x00000000, 0xffffffff, 0x00000000, 0x00000556, - 0x0000053a, 0x00000000, 0xffffffff, 0x00000000, 0x00000578, 0x0000055c, 0x00000000, 0xffffffff, - 0x00000000, 0x00000599, 0x0000057d, 0x00000000, 0xffffffff, 0x00000000, 0x000005bb, 0x0000059f, - 0x00000000, 0xffffffff, 0x00000000, 0x000005df, 0x000005c3, 0x00000000, 0xffffffff, 0x00000000, - 0x00000604, 0x000005e8, 0x00000000, 0xffffffff, 0x00000000, 0x00000625, 0x00000609, 0x00000000, - 0xffffffff, 0x00000000, 0x0000062a, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, - 0x00000000, 0x00000003, 0x00000633, 0x00000000, 0x0000063b, 0x00000256, 0x00000000, 0xffffffff, - 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000644, 0x00000000, 0x0000064c, 0x00000256, - 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000655, 0x00000000, - 0x0000065d, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, - 0x00000667, 0x00000000, 0x0000066f, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, - 0x00000000, 0x00000003, 0x00000679, 0x00000000, 0x00000681, 0x00000256, 0x00000000, 0xffffffff, - 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x0000068b, 0x00000000, 0x00000693, 0x00000256, - 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x0000069d, 0x00000000, - 0x000006a5, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, - 0x000006af, 0x00000000, 0x000006b7, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, - 0x00000000, 0x00000003, 0x000006c1, 0x00000000, 0x000006c9, 0x00000256, 0x00000000, 0xffffffff, - 0x00000001, 0x00000037, 0x00000000, 0x00000001, 0x000006cc, 0x00000000, 0x000006d8, 0x00000003, - 0x00000000, 0x000006de, 0x00000006, 0x00000000, 0x0000000a, 0x00000000, 0x00000001, 0x000006e4, - 0x0000000b, 0x00000000, 0x00000001, 0x00000708, 0x00000002, 0x00000000, 0x00000002, 0x000001b9, - 0x00000009, 0x00000000, 0x00000001, 0x00000714, 0x00000001, 0x00000000, 0x00000002, 0x000000e1, - 0x00000000, 0x00000000, 0x00000002, 0x00000030, 0x00000720, 0x00000001, 0x00000000, 0x00000007, - 0x00000000, 0x00000007, 0x0000091a, 0x00000922, 0x00000002, 0x00000000, 0x00000009, 0x00000000, - 0x00000001, 0x00000928, 0x00000001, 0x00000000, 0x00000001, 0x00000934, + 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000000, 0x00000004, 0x00000001, + 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, + 0x00000003, 0x0000ffff, 0x00000001, 0x00000002, 0x00000000, 0x00000030, 0x00000014, 0x00000000, + 0xffffffff, 0x0000000a, 0x0000000c, 0x00000000, 0x00000001, 0x0000003b, 0x0000000d, 0x00000000, + 0x00000001, 0x00000047, 0x0000000e, 0x00000000, 0x00000001, 0x00000053, 0x0000000f, 0x00000000, + 0x00000001, 0x0000005f, 0x00000010, 0x00000000, 0x00000001, 0x0000006b, 0x00000011, 0x00000000, + 0x00000001, 0x00000077, 0x00000012, 0x00000000, 0x00000001, 0x00000083, 0x00000013, 0x00000000, + 0x00000001, 0x0000008f, 0x00000014, 0x00000000, 0x00000001, 0x0000009b, 0x00000015, 0x00000000, + 0x00000001, 0x000000a7, 0x00000000, 0x000000e1, 0x000000c5, 0x00000000, 0xffffffff, 0x0000000e, + 0x00000016, 0x00000000, 0x00000001, 0x000000ea, 0x00000017, 0x00000000, 0x00000001, 0x000000f6, + 0x00000018, 0x00000000, 0x00000001, 0x00000102, 0x00000019, 0x00000000, 0x00000001, 0x0000010e, + 0x0000001a, 0x00000000, 0x00000001, 0x0000011a, 0x0000001b, 0x00000000, 0x00000001, 0x00000126, + 0x0000001c, 0x00000000, 0x00000001, 0x00000132, 0x0000001d, 0x00000000, 0x00000001, 0x0000013e, + 0x0000001e, 0x00000000, 0x00000001, 0x0000014a, 0x0000001f, 0x00000000, 0x00000001, 0x00000156, + 0x00000020, 0x00000000, 0x00000001, 0x00000162, 0x00000021, 0x00000000, 0x00000001, 0x0000016e, + 0x00000022, 0x00000000, 0x00000001, 0x0000017a, 0x00000023, 0x00000000, 0x00000001, 0x00000186, + 0x00000000, 0x000001b9, 0x0000019d, 0x00000000, 0xffffffff, 0x0000000b, 0x00000024, 0x00000000, + 0x00000001, 0x000001c5, 0x00000025, 0x00000000, 0x00000001, 0x000001d1, 0x00000025, 0x00000007, + 0x00000001, 0x000001dd, 0x00000026, 0x00000000, 0x00000001, 0x000001e9, 0x00000027, 0x00000000, + 0x00000001, 0x000001f5, 0x00000028, 0x00000000, 0x00000001, 0x00000201, 0x00000029, 0x00000000, + 0x00000001, 0x0000020d, 0x0000002a, 0x00000000, 0x00000001, 0x00000219, 0x0000002b, 0x00000000, + 0x00000001, 0x00000225, 0x0000002c, 0x00000000, 0x00000001, 0x00000231, 0x0000002c, 0x00000007, + 0x00000001, 0x0000023d, 0x00000000, 0x00000272, 0x00000256, 0x00000000, 0xffffffff, 0x0000000b, + 0x0000002d, 0x00000000, 0x00000001, 0x0000027b, 0x0000002e, 0x00000000, 0x00000001, 0x00000287, + 0x0000002f, 0x00000000, 0x00000001, 0x00000293, 0x00000030, 0x00000000, 0x00000001, 0x0000029f, + 0x00000031, 0x00000000, 0x00000001, 0x000002ab, 0x00000032, 0x00000000, 0x00000001, 0x000002b7, + 0x00000033, 0x00000000, 0x00000001, 0x000002c3, 0x00000034, 0x00000000, 0x00000001, 0x000002cf, + 0x00000035, 0x00000000, 0x00000001, 0x000002f3, 0x00000036, 0x00000000, 0x00000001, 0x000002ff, + 0x00000037, 0x00000000, 0x00000001, 0x0000030b, 0x00000000, 0x0000033b, 0x0000031f, 0x00000000, + 0xffffffff, 0x00000000, 0x00000364, 0x00000348, 0x00000000, 0xffffffff, 0x00000000, 0x00000392, + 0x00000376, 0x00000000, 0xffffffff, 0x00000000, 0x000003bc, 0x000003a0, 0x00000000, 0xffffffff, + 0x00000000, 0x000003ea, 0x000003ce, 0x00000000, 0xffffffff, 0x00000000, 0x00000416, 0x000003fa, + 0x00000000, 0xffffffff, 0x00000000, 0x00000449, 0x0000042d, 0x00000000, 0xffffffff, 0x00000000, + 0x00000476, 0x0000045a, 0x00000000, 0xffffffff, 0x00000000, 0x000004a1, 0x00000485, 0x00000000, + 0xffffffff, 0x00000000, 0x000004a4, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000002, 0x0000033b, 0x00000000, 0x000004ad, 0x00000256, 0x00000000, 0xffffffff, + 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000364, 0x00000000, 0x000004b6, 0x00000256, + 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000392, 0x00000000, + 0x000004c0, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, + 0x000003bc, 0x00000000, 0x000004c9, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000002, 0x000003ea, 0x00000000, 0x000004d3, 0x00000256, 0x00000000, 0xffffffff, + 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000416, 0x00000000, 0x000004dc, 0x00000256, + 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, 0x00000449, 0x00000000, + 0x000004e6, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000002, + 0x00000476, 0x00000000, 0x000004ef, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, + 0x00000000, 0x00000002, 0x000004a1, 0x00000000, 0x00000514, 0x000004f8, 0x00000000, 0xffffffff, + 0x00000000, 0x00000535, 0x00000519, 0x00000000, 0xffffffff, 0x00000000, 0x00000556, 0x0000053a, + 0x00000000, 0xffffffff, 0x00000000, 0x00000578, 0x0000055c, 0x00000000, 0xffffffff, 0x00000000, + 0x00000599, 0x0000057d, 0x00000000, 0xffffffff, 0x00000000, 0x000005bb, 0x0000059f, 0x00000000, + 0xffffffff, 0x00000000, 0x000005df, 0x000005c3, 0x00000000, 0xffffffff, 0x00000000, 0x00000604, + 0x000005e8, 0x00000000, 0xffffffff, 0x00000000, 0x00000625, 0x00000609, 0x00000000, 0xffffffff, + 0x00000000, 0x0000062a, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, + 0x00000003, 0x00000633, 0x00000000, 0x0000063b, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000003, 0x00000644, 0x00000000, 0x0000064c, 0x00000256, 0x00000000, + 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000655, 0x00000000, 0x0000065d, + 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x00000667, + 0x00000000, 0x0000066f, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, + 0x00000003, 0x00000679, 0x00000000, 0x00000681, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000003, 0x0000068b, 0x00000000, 0x00000693, 0x00000256, 0x00000000, + 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x0000069d, 0x00000000, 0x000006a5, + 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, 0x00000003, 0x000006af, + 0x00000000, 0x000006b7, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, 0x00000037, 0x00000000, + 0x00000003, 0x000006c1, 0x00000000, 0x000006c9, 0x00000256, 0x00000000, 0xffffffff, 0x00000001, + 0x00000037, 0x00000000, 0x00000001, 0x000006cc, 0x00000000, 0x000006d8, 0x00000003, 0x00000000, + 0x000006de, 0x00000006, 0x00000000, 0x0000000a, 0x00000000, 0x00000001, 0x000006e4, 0x0000000b, + 0x00000000, 0x00000001, 0x00000708, 0x00000002, 0x00000000, 0x00000002, 0x000001b9, 0x00000009, + 0x00000000, 0x00000001, 0x00000714, 0x00000001, 0x00000000, 0x00000002, 0x000000e1, 0x00000000, + 0x00000000, 0x00000002, 0x00000030, 0x00000720, 0x00000001, 0x00000000, 0x00000007, 0x00000000, + 0x00000007, 0x0000091a, 0x00000922, 0x00000005, 0x00000000, 0x00000009, 0x00000000, 0x00000001, + 0x00000928, 0x00000001, 0x00000000, 0x00000001, 0x00000934, 0x0000000a, 0x00000000, 0x00000001, + 0x00000940, 0x0000000b, 0x00000000, 0x00000001, 0x00000964, 0x00000002, 0x00000000, 0x00000001, + 0x00000970, };
static void create_effect_texture_resource(ID3D10Device *device, ID3D10ShaderResourceView **srv, @@ -4398,6 +4403,7 @@ static void create_effect_texture_resource(ID3D10Device *device, ID3D10ShaderRes static void test_effect_state_groups(void) { ID3D10DepthStencilState *ds_state, *ds_state2; + ID3D10BlendState *blend_state, *blend_state2; ID3D10ShaderResourceView *srv0, *srv1; ID3D10EffectDepthStencilVariable *d; ID3D10EffectRasterizerVariable *r; @@ -4408,7 +4414,6 @@ static void test_effect_state_groups(void) D3D10_SAMPLER_DESC sampler_desc; ID3D10EffectSamplerVariable *s; D3D10_EFFECT_DESC effect_desc; - ID3D10BlendState *blend_state; UINT sample_mask, stencil_ref; ID3D10EffectBlendVariable *b; D3D10_BLEND_DESC blend_desc; @@ -4626,7 +4631,6 @@ static void test_effect_state_groups(void) rast_desc.AntialiasedLineEnable);
ID3D10RasterizerState_Release(rast_state); - ID3D10BlendState_Release(blend_state);
/* pass 1 - uses SamplerState.Texture = NULL, resource slot is reset. */ pass = technique->lpVtbl->GetPassByName(technique, "pass1"); @@ -4655,12 +4659,16 @@ static void test_effect_state_groups(void) ok(pass->lpVtbl->IsValid(pass), "Failed to get pass.\n");
ID3D10Device_OMSetDepthStencilState(device, ds_state, 0); + ID3D10Device_OMSetBlendState(device, blend_state, NULL, 0); hr = pass->lpVtbl->Apply(pass, 0); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ID3D10Device_OMGetDepthStencilState(device, &ds_state2, &stencil_ref); ok(!ds_state2, "Unexpected depth stencil state.\n"); + ID3D10Device_OMGetBlendState(device, &blend_state2, blend_factor, &sample_mask); + ok(!blend_state2, "Unexpected blend state.\n");
ID3D10DepthStencilState_Release(ds_state); + ID3D10BlendState_Release(blend_state); effect->lpVtbl->Release(effect);
refcount = ID3D10Device_Release(device);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 173 ++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 80 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 901f800b623..a9014b55bae 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -386,6 +386,85 @@ static const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t
#undef WINE_D3D10_TO_STR
+static BOOL read_float_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type, + float *out_data, unsigned int out_idx) +{ + switch (in_type) + { + case D3D10_SVT_FLOAT: + out_data[out_idx] = *(float *)&value; + return TRUE; + + case D3D10_SVT_INT: + out_data[out_idx] = (INT)value; + return TRUE; + + case D3D10_SVT_UINT: + out_data[out_idx] = value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL read_int32_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type, + int *out_data, unsigned int out_idx) +{ + switch (in_type) + { + case D3D10_SVT_FLOAT: + out_data[out_idx] = *(float *)&value; + return TRUE; + + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + case D3D10_SVT_BOOL: + out_data[out_idx] = value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL read_int8_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type, + INT8 *out_data, unsigned int out_idx) +{ + switch (in_type) + { + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + out_data[out_idx] = value; + return TRUE; + + default: + FIXME("Unhandled in_type %#x.\n", in_type); + return FALSE; + } +} + +static BOOL d3d10_effect_read_numeric_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type, + D3D_SHADER_VARIABLE_TYPE out_type, void *out_data, unsigned int out_idx) +{ + switch (out_type) + { + case D3D10_SVT_FLOAT: + return read_float_value(value, in_type, out_data, out_idx); + case D3D10_SVT_INT: + case D3D10_SVT_UINT: + case D3D10_SVT_BOOL: + return read_int32_value(value, in_type, out_data, out_idx); + case D3D10_SVT_UINT8: + return read_int8_value(value, in_type, out_data, out_idx); + default: + FIXME("Unsupported property type %u.\n", out_type); + return FALSE; + } +} + static BOOL d3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) { SIZE_T max_capacity, new_capacity; @@ -917,7 +996,8 @@ static D3D10_SHADER_VARIABLE_CLASS d3d10_variable_class(DWORD c, BOOL is_column_ } }
-static D3D10_SHADER_VARIABLE_TYPE d3d10_variable_type(DWORD t, BOOL is_object, DWORD *flags) +static D3D10_SHADER_VARIABLE_TYPE d3d10_variable_type(DWORD t, BOOL is_object, + unsigned int *flags) { *flags = 0;
@@ -1567,70 +1647,14 @@ static const struct d3d10_effect_state_storage_info *get_storage_info(D3D_SHADER return NULL; }
-static BOOL read_float_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, float *out_data, UINT idx) -{ - switch (in_type) - { - case D3D10_SVT_FLOAT: - out_data[idx] = *(float *)&value; - return TRUE; - - case D3D10_SVT_INT: - out_data[idx] = (INT)value; - return TRUE; - - case D3D10_SVT_UINT: - out_data[idx] = value; - return TRUE; - - default: - FIXME("Unhandled in_type %#x.\n", in_type); - return FALSE; - } -} - -static BOOL read_int32_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT *out_data, UINT idx) -{ - switch (in_type) - { - case D3D10_SVT_FLOAT: - out_data[idx] = *(float *)&value; - return TRUE; - - case D3D10_SVT_INT: - case D3D10_SVT_UINT: - case D3D10_SVT_BOOL: - out_data[idx] = value; - return TRUE; - - default: - FIXME("Unhandled in_type %#x.\n", in_type); - return FALSE; - } -} - -static BOOL read_int8_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT8 *out_data, UINT idx) -{ - switch (in_type) - { - case D3D10_SVT_INT: - case D3D10_SVT_UINT: - out_data[idx] = value; - return TRUE; - - default: - FIXME("Unhandled in_type %#x.\n", in_type); - return FALSE; - } -} - -static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, - D3D_SHADER_VARIABLE_TYPE out_type, UINT out_base, UINT out_size, void *out_data) +static BOOL read_value_list(const char *data, size_t data_size, uint32_t offset, + D3D_SHADER_VARIABLE_TYPE out_type, unsigned int out_base, unsigned int out_size, + void *out_data) { D3D_SHADER_VARIABLE_TYPE in_type; - DWORD t, value, type_flags; + unsigned int i, type_flags; + uint32_t t, value, count; const char *ptr; - DWORD count, i;
if (offset >= data_size || !require_space(offset, 1, sizeof(count), data_size)) { @@ -1652,7 +1676,7 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, TRACE("%u values:\n", count); for (i = 0; i < count; ++i) { - UINT out_idx = out_base * out_size + i; + unsigned int out_idx = out_base * out_size + i;
read_dword(&ptr, &t); read_dword(&ptr, &value); @@ -1663,20 +1687,12 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset, switch (out_type) { case D3D10_SVT_FLOAT: - if (!read_float_value(value, in_type, out_data, out_idx)) - return FALSE; - break; - case D3D10_SVT_INT: case D3D10_SVT_UINT: - case D3D10_SVT_BOOL: - if (!read_int32_value(value, in_type, out_data, out_idx)) - return FALSE; - break; - case D3D10_SVT_UINT8: - if (!read_int8_value(value, in_type, out_data, out_idx)) - return FALSE; + case D3D10_SVT_BOOL: + if (!d3d10_effect_read_numeric_value(value, in_type, out_type, out_data, out_idx)) + return FALSE; break;
case D3D10_SVT_VERTEXSHADER: @@ -1757,17 +1773,14 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size const char **ptr, enum d3d10_effect_container_type container_type, struct d3d10_effect *effect, void *container) { + uint32_t id, idx, variable_idx, operation, value_offset, sodecl_offset; const struct d3d10_effect_state_property_info *property_info; - UINT value_offset, sodecl_offset, operation; struct d3d10_effect_variable *variable; - unsigned int variable_idx, *dst_index; - const char *data_ptr; - const char *name; + const char *data_ptr, *name; + unsigned int *dst_index; size_t name_len; HRESULT hr; void *dst; - UINT idx; - UINT id;
read_dword(ptr, &id); read_dword(ptr, &idx);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index a9014b55bae..383d27998b9 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -386,6 +386,31 @@ static const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t
#undef WINE_D3D10_TO_STR
+static HRESULT d3d10_effect_variable_get_raw_value(struct d3d10_effect_variable *v, + void *data, unsigned int offset, unsigned int count) +{ + BOOL is_buffer; + + is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER; + + if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer) + { + WARN("Not supported on object variables of type %s.\n", + debug_d3d10_shader_variable_type(v->type->basetype)); + return D3DERR_INVALIDCALL; + } + + if (!is_buffer) + { + offset += v->buffer_offset; + v = v->buffer; + } + + memcpy(data, v->u.buffer.local_buffer + offset, count); + + return S_OK; +} + static BOOL read_float_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type, float *out_data, unsigned int out_idx) { @@ -4563,7 +4588,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV void *data, UINT offset, UINT count) { struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(iface); - BOOL is_buffer;
TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count);
@@ -4573,24 +4597,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV return E_FAIL; }
- is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER; - - if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer) - { - WARN("Not supported on object variables of type %s.\n", - debug_d3d10_shader_variable_type(v->type->basetype)); - return D3DERR_INVALIDCALL; - } - - if (!is_buffer) - { - offset += v->buffer_offset; - v = v->buffer; - } - - memcpy(data, v->u.buffer.local_buffer + offset, count); - - return S_OK; + return d3d10_effect_variable_get_raw_value(v, data, offset, count); }
static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl =
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/d3d10_private.h | 9 +++ dlls/d3d10/effect.c | 137 ++++++++++++++++++++++++++++++---- dlls/d3d10/tests/effect.c | 149 +++++++++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+), 15 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 75d00371ba6..7f83fb1182a 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -96,6 +96,13 @@ struct d3d10_effect_shader_variable unsigned int isinline : 1; };
+struct d3d10_effect_prop_dependencies +{ + struct d3d10_effect_prop_dependency *entries; + SIZE_T count; + SIZE_T capacity; +}; + struct d3d10_effect_sampler_desc { D3D10_SAMPLER_DESC desc; @@ -119,6 +126,7 @@ struct d3d10_effect_state_object_variable ID3D10SamplerState *sampler; IUnknown *object; } object; + struct d3d10_effect_prop_dependencies dependencies; };
struct d3d10_effect_resource_variable @@ -218,6 +226,7 @@ struct d3d10_effect_pass char *name; struct d3d10_effect_annotations annotations;
+ struct d3d10_effect_prop_dependencies dependencies; struct d3d10_effect_pass_shader_desc vs; struct d3d10_effect_pass_shader_desc ps; struct d3d10_effect_pass_shader_desc gs; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 383d27998b9..78a3d0c386a 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -180,6 +180,27 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct d3d10_effect_prop_dependency +{ + unsigned int id; + unsigned int idx; + unsigned int operation; + union + { + struct + { + struct d3d10_effect_variable *v; + unsigned int offset; + } var; + } u; +}; + +static void d3d10_effect_clear_prop_dependencies(struct d3d10_effect_prop_dependencies *d) +{ + heap_free(d->entries); + memset(d, 0, sizeof(*d)); +} + struct d3d10_effect_state_property_info { UINT id; @@ -490,6 +511,47 @@ static BOOL d3d10_effect_read_numeric_value(uint32_t value, D3D_SHADER_VARIABLE_ } }
+static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_dependencies *deps, + void *container) +{ + const struct d3d10_effect_state_property_info *property_info; + struct d3d10_effect_prop_dependency *d; + struct d3d10_effect_variable *v; + unsigned int i, j, count; + uint32_t value; + void *dst; + + for (i = 0; i < deps->count; ++i) + { + d = &deps->entries[i]; + + property_info = &property_infos[d->id]; + + dst = (char *)container + property_info->offset; + + switch (d->operation) + { + case D3D10_EOO_VAR: + case D3D10_EOO_CONST_INDEX: + + v = d->u.var.v; + + count = v->type->type_class == D3D10_SVC_VECTOR ? 4 : 1; + + for (j = 0; j < count; ++j) + { + d3d10_effect_variable_get_raw_value(v, &value, d->u.var.offset + j * sizeof(value), sizeof(value)); + d3d10_effect_read_numeric_value(value, v->type->basetype, property_info->type, dst, j); + } + + break; + + default: + FIXME("Unsupported property update for %u.\n", d->operation); + } + } +} + static BOOL d3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) { SIZE_T max_capacity, new_capacity; @@ -1794,12 +1856,24 @@ static BOOL is_object_property_type_matching(const struct d3d10_effect_state_pro } }
+static HRESULT d3d10_effect_add_prop_dependency(struct d3d10_effect_prop_dependencies *d, + const struct d3d10_effect_prop_dependency *dep) +{ + if (!d3d_array_reserve((void **)&d->entries, &d->capacity, d->count + 1, sizeof(*d->entries))) + return E_OUTOFMEMORY; + + d->entries[d->count++] = *dep; + + return S_OK; +} + static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size, const char **ptr, enum d3d10_effect_container_type container_type, - struct d3d10_effect *effect, void *container) + struct d3d10_effect *effect, void *container, struct d3d10_effect_prop_dependencies *d) { uint32_t id, idx, variable_idx, operation, value_offset, sodecl_offset; const struct d3d10_effect_state_property_info *property_info; + struct d3d10_effect_prop_dependency dep; struct d3d10_effect_variable *variable; const char *data_ptr, *name; unsigned int *dst_index; @@ -1890,8 +1964,20 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size } else { - FIXME("Assigning variables to numeric fields is not supported.\n"); - return E_FAIL; + if (property_info->size * sizeof(float) > variable->type->size_unpacked) + { + WARN("Mismatching variable size %u, property size %u.\n", + variable->type->size_unpacked, property_info->size); + return E_FAIL; + } + + dep.id = id; + dep.idx = idx; + dep.operation = operation; + dep.u.var.v = variable; + dep.u.var.offset = 0; + + return d3d10_effect_add_prop_dependency(d, &dep); }
break; @@ -1914,7 +2000,8 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size return E_FAIL; }
- TRACE("Variable name %s[%u].\n", debugstr_a(name), variable_idx); + TRACE("Variable name %s[%s%u].\n", debugstr_a(name), is_object_property(property_info) ? + "" : "offset ", variable_idx);
if (!(variable = d3d10_effect_get_variable_by_name(effect, name))) { @@ -1922,15 +2009,14 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size return E_FAIL; }
- /* Has to be an array */ - if (!variable->type->element_count || variable_idx >= variable->type->element_count) - { - WARN("Invalid array size %u.\n", variable->type->element_count); - return E_FAIL; - } - if (is_object_property(property_info)) { + if (!variable->type->element_count || variable_idx >= variable->type->element_count) + { + WARN("Invalid array size %u.\n", variable->type->element_count); + return E_FAIL; + } + if (!is_object_property_type_matching(property_info, variable)) { WARN("Object type mismatch. Variable type %#x, property type %#x.\n", @@ -1953,8 +2039,22 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size } else { - FIXME("Assigning indexed variables to numeric fields is not supported.\n"); - return E_FAIL; + unsigned int offset = variable_idx * sizeof(float); + + if (offset >= variable->type->size_unpacked || + variable->type->size_unpacked - offset < property_info->size * sizeof(float)) + { + WARN("Invalid numeric variable data offset %u.\n", variable_idx); + return E_FAIL; + } + + dep.id = id; + dep.idx = idx; + dep.operation = operation; + dep.u.var.v = variable; + dep.u.var.offset = offset; + + return d3d10_effect_add_prop_dependency(d, &dep); }
break; @@ -2062,7 +2162,7 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size, for (i = 0; i < object_count; ++i) { if (FAILED(hr = parse_fx10_property_assignment(data, data_size, ptr, - D3D10_C_PASS, p->technique->effect, p))) + D3D10_C_PASS, p->technique->effect, p, &p->dependencies))) { WARN("Failed to parse pass assignment %u, hr %#x.\n", i, hr); return hr; @@ -2431,7 +2531,8 @@ static HRESULT parse_fx10_object_variable(const char *data, size_t data_size, for (j = 0; j < prop_count; ++j) { if (FAILED(hr = parse_fx10_property_assignment(data, data_size, ptr, - get_var_container_type(var), var->effect, &var->u.state.desc))) + get_var_container_type(var), var->effect, &var->u.state.desc, + &var->u.state.dependencies))) { ERR("Failed to read property list.\n"); return hr; @@ -3101,6 +3202,7 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) case D3D10_SVT_SAMPLER: if (v->u.state.object.object) IUnknown_Release(v->u.state.object.object); + d3d10_effect_clear_prop_dependencies(&v->u.state.dependencies); break;
case D3D10_SVT_TEXTURE1D: @@ -3144,6 +3246,7 @@ static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p)
heap_free(p->name); d3d10_effect_annotations_destroy(&p->annotations); + d3d10_effect_clear_prop_dependencies(&p->dependencies); }
static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t) @@ -3858,6 +3961,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa return E_INVALIDARG; }
+ d3d10_effect_update_dependent_props(&pass->dependencies, pass); + vs = d3d10_array_get_element(pass->vs.shader, pass->vs.index); input_signature = vs->u.shader.input_signature;
@@ -4143,6 +4248,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface
if (flags) FIXME("Ignoring flags (%#x)\n", flags);
+ d3d10_effect_update_dependent_props(&pass->dependencies, pass); + if (pass->vs.shader != &null_shader_variable) d3d10_effect_pass_set_shader(pass, &pass->vs); if (pass->gs.shader != &null_shader_variable) diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index a7a712edfb4..da644d8d9db 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7653,6 +7653,154 @@ static void test_effect_raw_value(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+#if 0 +uint i1; +uint i1_a[2]; +float4 fv1 = {0.5f, 0.6f, 0.7f, 0.8f}; +float4 fv1_a[2] = { { 1.0f, 1.1f, 1.2f, 1.3f }, {0.1f, 0.2f, 0.3f, 0.4f} }; +int i2 = 0x123; +int i2_a[2] = { 0x1, 0x2 }; +float f1 = 0.3f; + +technique10 tech +{ + pass P0 + { + SetBlendState(NULL, fv1, i2); + SetDepthStencilState(NULL, i1); + } + pass P1 + { + SetBlendState(NULL, fv1_a[1], i2_a[1]); + SetDepthStencilState(NULL, i1_a[1]); + } +} +#endif +static DWORD fx_test_effect_dynamic_numeric_field[] = +{ + 0x43425844, 0xc53c7634, 0x9d90c190, 0x5a0b43ea, 0x77aab553, 0x00000001, 0x000003af, 0x00000001, + 0x00000024, 0x30315846, 0x00000383, 0xfeff1001, 0x00000001, 0x00000007, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000197, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6f6c4724, + 0x736c6162, 0x6e697500, 0x000d0074, 0x00010000, 0x00000000, 0x00040000, 0x00100000, 0x00040000, + 0x09190000, 0x31690000, 0x00000d00, 0x00000100, 0x00000200, 0x00001400, 0x00001000, 0x00000800, + 0x00091900, 0x5f316900, 0x6c660061, 0x3474616f, 0x00005200, 0x00000100, 0x00000000, 0x00001000, + 0x00001000, 0x00001000, 0x00210a00, 0x31766600, 0x00000000, 0x19999a3f, 0x3333333f, 0x4ccccd3f, + 0x0000523f, 0x00000100, 0x00000200, 0x00002000, 0x00001000, 0x00002000, 0x00210a00, 0x31766600, + 0x0000615f, 0xcd3f8000, 0x9a3f8ccc, 0x663f9999, 0xcd3fa666, 0xcd3dcccc, 0x9a3e4ccc, 0xcd3e9999, + 0x693ecccc, 0xcb00746e, 0x01000000, 0x00000000, 0x04000000, 0x10000000, 0x04000000, 0x11000000, + 0x69000009, 0x01230032, 0x00cb0000, 0x00010000, 0x00020000, 0x00140000, 0x00100000, 0x00080000, + 0x09110000, 0x32690000, 0x0100615f, 0x02000000, 0x66000000, 0x74616f6c, 0x00011b00, 0x00000100, + 0x00000000, 0x00000400, 0x00001000, 0x00000400, 0x00090900, 0x00316600, 0x3e99999a, 0x68636574, + 0x00305000, 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000000, 0xa5003150, + 0x04000000, 0x0e000000, 0x04000001, 0x01000000, 0x02000000, 0x00000000, 0x4d000000, 0x04000000, + 0x01000000, 0x02000000, 0x00000000, 0x04000000, 0x90000000, 0x00000000, 0x07000000, 0xff000000, + 0x00ffffff, 0x2e000000, 0x12000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4d000000, 0x31000000, 0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x75000000, + 0x59000000, 0x00000000, 0x30000000, 0x79000000, 0x00000000, 0x00000000, 0xa5000000, 0x89000000, + 0x00000000, 0x40000000, 0xab000000, 0x00000000, 0x00000000, 0xeb000000, 0xcf000000, 0x00000000, + 0x60000000, 0xee000000, 0x00000000, 0x00000000, 0x0e000000, 0xf2000001, 0x00000000, 0x70000000, + 0x13000000, 0x00000001, 0x00000000, 0x3d000000, 0x21000001, 0x00000001, 0x84000000, 0x40000000, + 0x00000001, 0x00000000, 0x44000000, 0x02000001, 0x00000000, 0x49000000, 0x05000001, 0x00000000, + 0x0a000000, 0x00000000, 0x02000000, 0x75000000, 0x0b000000, 0x00000000, 0x02000000, 0xeb000000, + 0x02000000, 0x00000000, 0x01000000, 0x4c000000, 0x09000001, 0x00000000, 0x02000000, 0x2e000000, + 0x01000000, 0x00000000, 0x01000000, 0x58000000, 0x64000001, 0x05000001, 0x00000000, 0x0a000000, + 0x00000000, 0x03000000, 0x67000000, 0x0b000001, 0x00000000, 0x03000000, 0x6f000000, 0x02000001, + 0x00000000, 0x01000000, 0x77000000, 0x09000001, 0x00000000, 0x03000000, 0x83000000, 0x01000001, + 0x00000000, 0x01000000, 0x8b000000, 0x00000001, +}; + +static void test_effect_dynamic_numeric_field(void) +{ + ID3D10EffectScalarVariable *scalar; + ID3D10DepthStencilState *ds_state; + ID3D10BlendState *blend_state; + UINT stencil_ref, sample_mask; + ID3D10EffectTechnique *tech; + D3D10_PASS_DESC pass_desc; + ID3D10EffectVariable *v; + ID3D10EffectPass *pass; + float blend_factor[4]; + ID3D10Effect *effect; + ID3D10Device *device; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_effect_dynamic_numeric_field, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "Failed to create an effect, hr %#x.\n", hr); + + tech = effect->lpVtbl->GetTechniqueByIndex(effect, 0); + ok(tech->lpVtbl->IsValid(tech), "Expected valid technique.\n"); + + /* Pass fields */ + pass = tech->lpVtbl->GetPassByName(tech, "P0"); + + ID3D10Device_OMSetDepthStencilState(device, NULL, 0x1); + memset(blend_factor, 0, sizeof(blend_factor)); + ID3D10Device_OMSetBlendState(device, NULL, blend_factor, 0); + hr = pass->lpVtbl->Apply(pass, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref); + ok(!stencil_ref, "Unexpected stencil ref value %#x.\n", stencil_ref); + ID3D10Device_OMGetBlendState(device, &blend_state, blend_factor, &sample_mask); + ok(blend_factor[0] == 0.5f, "Got unexpected blend_factor[0] %.8e.\n", blend_factor[0]); + ok(blend_factor[1] == 0.6f, "Got unexpected blend_factor[1] %.8e.\n", blend_factor[1]); + ok(blend_factor[2] == 0.7f, "Got unexpected blend_factor[2] %.8e.\n", blend_factor[2]); + ok(blend_factor[3] == 0.8f, "Got unexpected blend_factor[3] %.8e.\n", blend_factor[3]); + ok(sample_mask == 0x123, "Unexpected sample mask %#x.\n", sample_mask); + + v = effect->lpVtbl->GetVariableByName(effect, "i1"); + scalar = v->lpVtbl->AsScalar(v); + hr = scalar->lpVtbl->SetInt(scalar, 2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = pass->lpVtbl->Apply(pass, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref); + ok(stencil_ref == 0x2, "Unexpected stencil ref value %#x.\n", stencil_ref); + + hr = scalar->lpVtbl->SetInt(scalar, 3); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = pass->lpVtbl->GetDesc(pass, &pass_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(pass_desc.StencilRef == 0x3, "Unexpected stencil ref value %#x.\n", stencil_ref); + ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref); + ok(stencil_ref == 0x2, "Unexpected stencil ref value %#x.\n", stencil_ref); + + pass = tech->lpVtbl->GetPassByName(tech, "P1"); + + v = effect->lpVtbl->GetVariableByName(effect, "i1_a"); + v = v->lpVtbl->GetElement(v, 1); + scalar = v->lpVtbl->AsScalar(v); + hr = scalar->lpVtbl->SetInt(scalar, 4); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + ID3D10Device_OMSetDepthStencilState(device, NULL, 0x1); + memset(blend_factor, 0, sizeof(blend_factor)); + ID3D10Device_OMSetBlendState(device, NULL, blend_factor, 0); + hr = pass->lpVtbl->Apply(pass, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref); + ok(stencil_ref == 0x4, "Unexpected stencil ref value %#x.\n", stencil_ref); + ID3D10Device_OMGetBlendState(device, &blend_state, blend_factor, &sample_mask); + ok(blend_factor[0] == 0.1f, "Got unexpected blend_factor[0] %.8e.\n", blend_factor[0]); + ok(blend_factor[1] == 0.2f, "Got unexpected blend_factor[1] %.8e.\n", blend_factor[1]); + ok(blend_factor[2] == 0.3f, "Got unexpected blend_factor[2] %.8e.\n", blend_factor[2]); + ok(blend_factor[3] == 0.4f, "Got unexpected blend_factor[3] %.8e.\n", blend_factor[3]); + ok(sample_mask == 0x2, "Unexpected sample mask %#x.\n", sample_mask); + + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(effect) { test_effect_constant_buffer_type(); @@ -7676,4 +7824,5 @@ START_TEST(effect) test_effect_pool(); test_effect_default_variable_value(); test_effect_raw_value(); + test_effect_dynamic_numeric_field(); }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d10/effect.c | 556 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 114 ++++++++ 2 files changed, 669 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3ae2ad4f481 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -30,6 +30,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC MAKE_TAG('F', 'X', 'L', 'C') +#define TAG_CLI4 MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB MAKE_TAG('C', 'T', 'A', 'B')
#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 #define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) @@ -180,6 +183,89 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct preshader_instr +{ + unsigned int comp_count : 16; + unsigned int reserved : 4; + unsigned int opcode : 11; + unsigned int scalar : 1; +}; + +typedef float (*pres_op_func)(float **args, unsigned int n); + +static float pres_ftou(float **args, unsigned int n) +{ + unsigned int u = *args[0]; + return *(float *)&u; +} + +static float pres_add(float **args, unsigned int n) +{ + return *args[0] + *args[1]; +} + +enum preshader_op +{ + D3D10_PRESHADER_OP_FTOU = 0, + D3D10_PRESHADER_OP_ADD, + D3D10_PRESHADER_OP_LAST_OP, +}; + +struct preshader_op_info +{ + unsigned short idx; + unsigned short opcode; + char name[8]; + pres_op_func func; +}; + +static const struct preshader_op_info preshader_ops[] = +{ + { D3D10_PRESHADER_OP_FTOU, 0x133, "ftou", pres_ftou }, + { D3D10_PRESHADER_OP_ADD, 0x204, "add", pres_add }, +}; + +struct d3d10_ctab_var +{ + struct d3d10_effect_variable *v; + unsigned int offset; + unsigned int length; +}; + +struct d3d10_reg_table +{ + union + { + float *f; + DWORD *dword; + } u; + unsigned int count; +}; + +enum d3d10_reg_table_type +{ + D3D10_REG_TABLE_CONSTANTS = 1, + D3D10_REG_TABLE_CB = 2, + D3D10_REG_TABLE_RESULT = 4, + D3D10_REG_TABLE_TEMP = 7, + D3D10_REG_TABLE_LAST, +}; + +struct d3d10_effect_preshader +{ + struct d3d10_reg_table reg_tables[D3D10_REG_TABLE_LAST]; + ID3D10Blob *code; + + struct d3d10_ctab_var *vars; + unsigned int vars_count; +}; + +struct d3d10_preshader_parse_context +{ + struct d3d10_effect_preshader *preshader; + struct d3d10_effect *effect; +}; + struct d3d10_effect_prop_dependency { unsigned int id; @@ -192,11 +278,117 @@ struct d3d10_effect_prop_dependency struct d3d10_effect_variable *v; unsigned int offset; } var; + struct + { + struct d3d10_effect_variable *v; + struct d3d10_effect_preshader index; + } index_expr; } u; };
+static HRESULT d3d10_reg_table_allocate(struct d3d10_reg_table *table, unsigned int count) +{ + if (!(table->u.f = heap_calloc(count, sizeof(*table->u.f)))) + return E_OUTOFMEMORY; + table->count = count; + return S_OK; +} + +static void d3d10_effect_preshader_clear(struct d3d10_effect_preshader *p) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(p->reg_tables); ++i) + heap_free(&p->reg_tables[i].u.f); + if (p->code) + ID3D10Blob_Release(p->code); + heap_free(p->vars); + memset(p, 0, sizeof(*p)); +} + +static float * d3d10_effect_preshader_get_reg_ptr(const struct d3d10_effect_preshader *p, + enum d3d10_reg_table_type regt, unsigned int offset) +{ + switch (regt) + { + case D3D10_REG_TABLE_CONSTANTS: + case D3D10_REG_TABLE_CB: + case D3D10_REG_TABLE_RESULT: + case D3D10_REG_TABLE_TEMP: + return p->reg_tables[regt].u.f + offset; + default: + return NULL; + } +} + +static HRESULT d3d10_effect_preshader_eval(struct d3d10_effect_preshader *p) +{ + unsigned int i, j, regt, offset, instr_count, input_count; + const DWORD *ip = ID3D10Blob_GetBufferPointer(p->code); + float *dst, *args[4], *retval; + struct preshader_instr ins; + + dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_RESULT, 0); + memset(dst, 0, sizeof(float) * p->reg_tables[D3D10_REG_TABLE_RESULT].count); + + /* Update constant buffer */ + dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_CB, 0); + for (i = 0; i < p->vars_count; ++i) + { + struct d3d10_ctab_var *v = &p->vars[i]; + memcpy(dst + v->offset, v->v->buffer->u.buffer.local_buffer, v->length * sizeof(*dst)); + } + + instr_count = *ip++; + + for (i = 0; i < instr_count; ++i) + { + *(DWORD *)&ins = *ip++; + input_count = *ip++; + + if (input_count > ARRAY_SIZE(args)) + { + FIXME("Unexpected argument count %u.\n", input_count); + return E_FAIL; + } + + /* Arguments */ + for (j = 0; j < input_count; ++j) + { + ip++; /* TODO: currently ignored field */ + regt = *ip++; + offset = *ip++; + + args[j] = d3d10_effect_preshader_get_reg_ptr(p, regt, offset); + } + + ip++; /* TODO: currently ignored field */ + regt = *ip++; + offset = *ip++; + retval = d3d10_effect_preshader_get_reg_ptr(p, regt, offset); + + *retval = preshader_ops[ins.opcode].func(args, input_count); + } + + return S_OK; +} + static void d3d10_effect_clear_prop_dependencies(struct d3d10_effect_prop_dependencies *d) { + unsigned int i; + + for (i = 0; i < d->count; ++i) + { + struct d3d10_effect_prop_dependency *dep = &d->entries[i]; + switch (dep->operation) + { + case D3D10_EOO_INDEX_EXPRESSION: + d3d10_effect_preshader_clear(&dep->u.index_expr.index); + break; + default: + ; + } + } heap_free(d->entries); memset(d, 0, sizeof(*d)); } @@ -516,9 +708,11 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende { const struct d3d10_effect_state_property_info *property_info; struct d3d10_effect_prop_dependency *d; + unsigned int i, j, count, variable_idx; struct d3d10_effect_variable *v; - unsigned int i, j, count; + unsigned int *dst_index; uint32_t value; + HRESULT hr; void *dst;
for (i = 0; i < deps->count; ++i) @@ -528,6 +722,7 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende property_info = &property_infos[d->id];
dst = (char *)container + property_info->offset; + dst_index = (unsigned int *)((char *)container + property_info->index_offset);
switch (d->operation) { @@ -546,6 +741,38 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende
break;
+ case D3D10_EOO_INDEX_EXPRESSION: + + v = d->u.index_expr.v; + + if (FAILED(hr = d3d10_effect_preshader_eval(&d->u.index_expr.index))) + { + WARN("Failed to evaluate index expression, hr %#x.\n", hr); + return; + } + + variable_idx = *d->u.index_expr.index.reg_tables[D3D10_REG_TABLE_RESULT].u.dword; + + if (variable_idx >= v->type->element_count) + { + WARN("Expression evaluated to invalid index value %u, array %s of size %u.\n", + variable_idx, debugstr_a(v->name), v->type->element_count); + return; + } + + switch (property_info->type) + { + case D3D10_SVT_VERTEXSHADER: + case D3D10_SVT_PIXELSHADER: + case D3D10_SVT_GEOMETRYSHADER: + ((void **)dst)[d->idx] = v; + *dst_index = variable_idx; + break; + default: + ((void **)dst)[d->idx] = &v->elements[variable_idx]; + } + break; + default: FIXME("Unsupported property update for %u.\n", d->operation); } @@ -1856,6 +2083,271 @@ static BOOL is_object_property_type_matching(const struct d3d10_effect_state_pro } }
+static HRESULT parse_fx10_preshader_instr(struct d3d10_effect_preshader *p, const char **ptr) +{ + SIZE_T data_size = ID3D10Blob_GetBufferSize(p->code); + struct preshader_instr *ins; + uint32_t skip, input_count; + unsigned int i, opcode; + + if (data_size < 2 * sizeof(DWORD)) + { + WARN("Byte code buffer ends unexpectedly.\n"); + return E_FAIL; + } + + ins = (struct preshader_instr *)*ptr; + read_dword(ptr, &skip); + read_dword(ptr, &input_count); + + opcode = ins->opcode; + ins->opcode = D3D10_PRESHADER_OP_LAST_OP; + + TRACE("Opcode %#x, input count %u.\n", opcode, input_count); + + /* Patch original opcode with sequential index. */ + + /* TODO: use better search */ + for (i = 0; i < ARRAY_SIZE(preshader_ops); ++i) + { + if (opcode == preshader_ops[i].opcode) + { + ins->opcode = preshader_ops[i].idx; + break; + } + } + + if (ins->opcode == D3D10_PRESHADER_OP_LAST_OP) + { + FIXME("Unrecognized opcode %#x.\n", opcode); + return E_FAIL; + } + + /* Inputs + 1 output */ + for (i = 0; i < input_count + 1; ++i) + { + uint32_t unknown, regt, offset; + struct d3d10_reg_table *t; + + read_dword(ptr, &unknown); + if (unknown) + { + FIXME("Unexpected argument field %#x.\n", unknown); + return E_UNEXPECTED; + } + + read_dword(ptr, ®t); + read_dword(ptr, &offset); + + switch (regt) + { + case D3D10_REG_TABLE_RESULT: + case D3D10_REG_TABLE_TEMP: + t = &p->reg_tables[regt]; + t->count = max(t->count, offset + 1); + break; + default: + break; + } + } + + return S_OK; +} + +static HRESULT parse_fx10_fxlc(void *ctx, const char *data, unsigned int data_size) +{ + struct d3d10_preshader_parse_context *context = ctx; + struct d3d10_effect_preshader *p = context->preshader; + uint32_t ins_count; + const char *ptr; + unsigned int i; + HRESULT hr; + + if (data_size % sizeof(DWORD)) + { + WARN("FXLC size misaligned %u.\n", data_size); + return E_FAIL; + } + + /* Parse through bytecode copy, so we can patch opcodes. */ + if (FAILED(hr = D3DCreateBlob(data_size, &p->code))) + return hr; + memcpy(ID3D10Blob_GetBufferPointer(p->code), data, data_size); + + ptr = ID3D10Blob_GetBufferPointer(p->code); + read_dword(&ptr, &ins_count); + TRACE("%u instructions.\n", ins_count); + + for (i = 0; i < ins_count; ++i) + { + if (FAILED(hr = parse_fx10_preshader_instr(p, &ptr))) + { + WARN("Failed to parse instruction %u.\n", i); + return hr; + } + } + + if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_RESULT], + p->reg_tables[D3D10_REG_TABLE_RESULT].count))) return hr; + if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_TEMP], + p->reg_tables[D3D10_REG_TABLE_TEMP].count))) return hr; + + return S_OK; +} + +static HRESULT parse_fx10_cli4(void *ctx, const char *data, unsigned int data_size) +{ + struct d3d10_preshader_parse_context *context = ctx; + struct d3d10_effect_preshader *p = context->preshader; + struct d3d10_reg_table *table = &p->reg_tables[D3D10_REG_TABLE_CONSTANTS]; + const char *ptr = data; + HRESULT hr; + + if (data_size < sizeof(DWORD)) + { + WARN("Invalid CLI4 chunk size %u.\n", data_size); + return E_FAIL; + } + + read_dword(&ptr, &table->count); + + TRACE("%u literal constants.\n", table->count); + + if (!require_space(4, table->count, sizeof(DWORD), data_size)) + { + WARN("Invalid constant table size %u.\n", data_size); + return E_FAIL; + } + + if (FAILED(hr = d3d10_reg_table_allocate(table, table->count))) + return hr; + + memcpy(table->u.f, ptr, table->count * sizeof(*table->u.f)); + + return S_OK; +} + +static HRESULT parse_fx10_ctab(void *ctx, const char *data, unsigned int data_size) +{ + struct d3d10_preshader_parse_context *context = ctx; + struct d3d10_effect_preshader *p = context->preshader; + struct ctab_header + { + DWORD size; + DWORD creator; + DWORD version; + DWORD constants; + DWORD constantinfo; + DWORD flags; + DWORD target; + } header; + struct ctab_const_info + { + DWORD name; + WORD register_set; + WORD register_index; + WORD register_count; + WORD reserved; + DWORD typeinfo; + DWORD default_value; + } *info; + unsigned int i, cb_reg_count = 0; + const char *ptr = data; + const char *name; + size_t name_len; + HRESULT hr; + + if (data_size < sizeof(header)) + { + WARN("Invalid constant table size %u.\n", data_size); + return E_FAIL; + } + + read_dword(&ptr, &header.size); + read_dword(&ptr, &header.creator); + read_dword(&ptr, &header.version); + read_dword(&ptr, &header.constants); + read_dword(&ptr, &header.constantinfo); + read_dword(&ptr, &header.flags); + read_dword(&ptr, &header.target); + + if (!require_space(header.constantinfo, header.constants, sizeof(*info) / sizeof(DWORD), + data_size)) + { + WARN("Invalid constant info section offset %#x.\n", header.constantinfo); + return E_FAIL; + } + + p->vars_count = header.constants; + + TRACE("Variable count %u.\n", p->vars_count); + + if (!(p->vars = heap_calloc(p->vars_count, sizeof(*p->vars)))) + return E_OUTOFMEMORY; + + /* Collect variables used in expression. */ + info = (struct ctab_const_info *)(data + header.constantinfo); + for (i = 0; i < p->vars_count; ++i, ++info) + { + if (!fx10_get_string(data, data_size, info->name, &name, &name_len)) + return E_FAIL; + + if (!(p->vars[i].v = d3d10_effect_get_variable_by_name(context->effect, name))) + { + WARN("Couldn't find variable %s.\n", debugstr_a(name)); + return E_FAIL; + } + + /* 4 components per register */ + p->vars[i].offset = info->register_index * 4; + p->vars[i].length = info->register_count * 4; + + cb_reg_count = max(cb_reg_count, info->register_index + info->register_count); + } + + /* Allocate contiguous "constant buffer" for all referenced variables. */ + if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_CB], cb_reg_count * 4))) + { + WARN("Failed to allocate variables buffer.\n"); + return hr; + } + + return S_OK; +} + +static HRESULT fxlvm_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + TRACE("Chunk tag: %s, size: %u.\n", debugstr_an((const char *)&tag, 4), data_size); + + switch (tag) + { + case TAG_FXLC: + return parse_fx10_fxlc(ctx, data, data_size); + + case TAG_CLI4: + return parse_fx10_cli4(ctx, data, data_size); + + case TAG_CTAB: + return parse_fx10_ctab(ctx, data, data_size); + + default: + FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4)); + return S_OK; + } +} + +static HRESULT parse_fx10_preshader(const char *data, size_t data_size, + struct d3d10_effect *effect, struct d3d10_effect_preshader *preshader) +{ + struct d3d10_preshader_parse_context context; + + memset(preshader, 0, sizeof(*preshader)); + context.preshader = preshader; + context.effect = effect; + + return parse_dxbc(data, data_size, fxlvm_chunk_handler, &context); +} + static HRESULT d3d10_effect_add_prop_dependency(struct d3d10_effect_prop_dependencies *d, const struct d3d10_effect_prop_dependency *dep) { @@ -1875,6 +2367,7 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size const struct d3d10_effect_state_property_info *property_info; struct d3d10_effect_prop_dependency dep; struct d3d10_effect_variable *variable; + uint32_t code_offset, blob_size; const char *data_ptr, *name; unsigned int *dst_index; size_t name_len; @@ -2059,6 +2552,61 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
break;
+ case D3D10_EOO_INDEX_EXPRESSION: + + /* Variable, and an expression for its index. */ + if (value_offset >= data_size || !require_space(value_offset, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", value_offset, (long)data_size); + return E_FAIL; + } + + data_ptr = data + value_offset; + read_dword(&data_ptr, &value_offset); + read_dword(&data_ptr, &code_offset); + + if (!fx10_get_string(data, data_size, value_offset, &name, &name_len)) + { + WARN("Failed to get variable name.\n"); + return E_FAIL; + } + + TRACE("Variable name %s[<expr>].\n", debugstr_a(name)); + + if (!(variable = d3d10_effect_get_variable_by_name(effect, name))) + { + WARN("Couldn't find variable %s.\n", debugstr_a(name)); + return E_FAIL; + } + + /* Has to be an array */ + if (!variable->type->element_count) + { + WARN("Expected array variable.\n"); + return E_FAIL; + } + + if (code_offset >= data_size || !require_space(code_offset, 1, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", value_offset, (long)data_size); + return E_FAIL; + } + + data_ptr = data + code_offset; + read_dword(&data_ptr, &blob_size); + + dep.id = id; + dep.idx = idx; + dep.operation = operation; + dep.u.index_expr.v = variable; + if (FAILED(hr = parse_fx10_preshader(data_ptr, blob_size, effect, &dep.u.index_expr.index))) + { + WARN("Failed to parse preshader, hr %#x.\n", hr); + return hr; + } + + return d3d10_effect_add_prop_dependency(d, &dep); + case D3D10_EOO_ANONYMOUS_SHADER:
/* Anonymous shader */ @@ -4004,6 +4552,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10Eff return E_INVALIDARG; }
+ d3d10_effect_update_dependent_props(&pass->dependencies, pass); + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->vs.shader->ID3D10EffectVariable_iface; desc->ShaderIndex = pass->vs.index;
@@ -4029,6 +4579,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetGeometryShaderDesc(ID3D10E return E_INVALIDARG; }
+ d3d10_effect_update_dependent_props(&pass->dependencies, pass); + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->gs.shader->ID3D10EffectVariable_iface; desc->ShaderIndex = pass->gs.index;
@@ -4054,6 +4606,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetPixelShaderDesc(ID3D10Effe return E_INVALIDARG; }
+ d3d10_effect_update_dependent_props(&pass->dependencies, pass); + desc->pShaderVariable = (ID3D10EffectShaderVariable *)&pass->ps.shader->ID3D10EffectVariable_iface; desc->ShaderIndex = pass->ps.index;
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index da644d8d9db..c2ed9c6071e 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7801,6 +7801,119 @@ static void test_effect_dynamic_numeric_field(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+#if 0 +float4 g_var; +PixelShader ps_array[2]; +VertexShader vs_array[2]; +technique10 tech +{ + pass p0 + { + SetPixelShader( ps_array[g_var.z] ); + SetVertexShader( vs_array[g_var.x + 0.1f] ); + } +} +#endif +static DWORD fx_test_index_expression[] = +{ + 0x43425844, 0x83787296, 0xf866b7a9, 0x7b56930c, 0xdc9d061a, 0x00000001, 0x000003e9, 0x00000001, + 0x00000024, 0x30315846, 0x000003bd, 0xfeff1001, 0x00000001, 0x00000001, 0x00000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x000002cd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x6f6c4724, + 0x736c6162, 0x6f6c6600, 0x00347461, 0x0000000d, 0x00000001, 0x00000000, 0x00000010, 0x00000010, + 0x00000010, 0x0000210a, 0x61765f67, 0x69500072, 0x536c6578, 0x65646168, 0x00360072, 0x00020000, + 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00050000, 0x73700000, 0x7272615f, 0x56007961, + 0x65747265, 0x61685378, 0x00726564, 0x00000067, 0x00000002, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000006, 0x615f7376, 0x79617272, 0x63657400, 0x30700068, 0x0000ec00, 0x42584400, + 0x990a9743, 0xd17834e6, 0x40de477e, 0xf476a79f, 0x00000101, 0x0000ec00, 0x00000300, 0x00002c00, + 0x0000a800, 0x0000b400, 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146, + 0x00001c00, 0x00010000, 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000, + 0x765f6700, 0xab007261, 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d, + 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, + 0x00312e30, 0x494c43ab, 0x00000434, 0x00000000, 0x4c584600, 0x00003043, 0x00000100, 0x30000100, + 0x00000113, 0x00000000, 0x00000200, 0x00000200, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000, + 0x0f0f0ff0, 0x00ffff0f, 0x00005e00, 0x0000a100, 0x00012800, 0x42584400, 0x78de2e43, 0x31414e7a, + 0xf69158cd, 0x416c97b6, 0x00000192, 0x00012800, 0x00000300, 0x00002c00, 0x0000a800, 0x0000c400, + 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146, 0x00001c00, 0x00010000, + 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000, 0x765f6700, 0xab007261, + 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d, 0x666f736f, 0x52282074, + 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x00312e30, 0x494c43ab, + 0x00001434, 0x00000400, 0xcccccd00, 0x0000003d, 0x00000000, 0x00000000, 0x4c584600, 0x00005c43, + 0x00000200, 0x40000100, 0x00000220, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000100, + 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x30000100, 0x00000113, 0x00000000, 0x00000700, + 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000, 0x0f0f0ff0, 0x00ffff0f, 0x00009000, + 0x00019900, 0x00000400, 0x00001000, 0x00000000, 0x00000100, 0xffffff00, 0x000000ff, 0x00003000, + 0x00001400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00005e00, 0x00004200, + 0x00000000, 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009000, 0x00007400, 0x00000000, + 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009900, 0x00000100, 0x00000000, 0x00009e00, + 0x00000200, 0x00000000, 0x00000700, 0x00000000, 0x00000500, 0x00019100, 0x00000600, 0x00000000, + 0x00000500, 0x0002c500, 0x00000000, +}; + +static void test_effect_index_expression(void) +{ + ID3D10EffectTechnique *tech; + ID3D10EffectPass *pass; + ID3D10Effect *effect; + ID3D10Device *device; + ULONG refcount; + HRESULT hr; + D3D10_PASS_SHADER_DESC shader_desc; + ID3D10EffectVectorVariable *vector; + ID3D10EffectVariable *v; + float val[4]; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = create_effect(fx_test_index_expression, 0, device, NULL, &effect); + ok(SUCCEEDED(hr), "Failed to create an effect, hr %#x.\n", hr); + + /* Initial index */ + tech = effect->lpVtbl->GetTechniqueByIndex(effect, 0); + pass = tech->lpVtbl->GetPassByIndex(tech, 0); + hr = pass->lpVtbl->GetPixelShaderDesc(pass, &shader_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!shader_desc.ShaderIndex, "Unexpected shader index.\n"); + + v = effect->lpVtbl->GetVariableByName(effect, "g_var"); + vector = v->lpVtbl->AsVector(v); + + val[0] = 0.0f; + val[1] = 0.0f; + val[2] = 1.0f; + val[3] = 0.0f; + hr = vector->lpVtbl->SetFloatVector(vector, val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = pass->lpVtbl->GetPixelShaderDesc(pass, &shader_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(shader_desc.ShaderIndex == 1, "Unexpected shader index %#x.\n", shader_desc.ShaderIndex); + + hr = pass->lpVtbl->GetVertexShaderDesc(pass, &shader_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!shader_desc.ShaderIndex, "Unexpected shader index %#x.\n", shader_desc.ShaderIndex); + + val[0] = 0.9f; + val[1] = 0.0f; + val[2] = 1.0f; + val[3] = 0.0f; + hr = vector->lpVtbl->SetFloatVector(vector, val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = pass->lpVtbl->GetVertexShaderDesc(pass, &shader_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(shader_desc.ShaderIndex == 1, "Unexpected shader index %#x.\n", shader_desc.ShaderIndex); + + effect->lpVtbl->Release(effect); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(effect) { test_effect_constant_buffer_type(); @@ -7825,4 +7938,5 @@ START_TEST(effect) test_effect_default_variable_value(); test_effect_raw_value(); test_effect_dynamic_numeric_field(); + test_effect_index_expression(); }
On Mon, Nov 1, 2021 at 11:52 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/effect.c | 556 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 114 ++++++++ 2 files changed, 669 insertions(+), 1 deletion(-)
Still looking into this one. For the time being I have a single nitpick, probably not worth acting on it just yet:
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3ae2ad4f481 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -30,6 +30,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC MAKE_TAG('F', 'X', 'L', 'C') +#define TAG_CLI4 MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB MAKE_TAG('C', 'T', 'A', 'B')
#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 #define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) @@ -180,6 +183,89 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct preshader_instr +{
- unsigned int comp_count : 16;
- unsigned int reserved : 4;
- unsigned int opcode : 11;
- unsigned int scalar : 1;
+};
+typedef float (*pres_op_func)(float **args, unsigned int n);
+static float pres_ftou(float **args, unsigned int n) +{
- unsigned int u = *args[0];
- return *(float *)&u;
+}
+static float pres_add(float **args, unsigned int n) +{
- return *args[0] + *args[1];
+}
+enum preshader_op +{
- D3D10_PRESHADER_OP_FTOU = 0,
- D3D10_PRESHADER_OP_ADD,
- D3D10_PRESHADER_OP_LAST_OP,
+};
+struct preshader_op_info +{
- unsigned short idx;
- unsigned short opcode;
- char name[8];
- pres_op_func func;
+};
idx is an enum preshader_op, right? Any reason you're not using that type? The field name seems to have room for improvement too (although I realize the trouble with "opcode" also there).
On 11/2/21 11:47 PM, Matteo Bruni wrote:
On Mon, Nov 1, 2021 at 11:52 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/effect.c | 556 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 114 ++++++++ 2 files changed, 669 insertions(+), 1 deletion(-)
Still looking into this one. For the time being I have a single nitpick, probably not worth acting on it just yet:
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3ae2ad4f481 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -30,6 +30,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC MAKE_TAG('F', 'X', 'L', 'C') +#define TAG_CLI4 MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB MAKE_TAG('C', 'T', 'A', 'B')
#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 #define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) @@ -180,6 +183,89 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct preshader_instr +{
- unsigned int comp_count : 16;
- unsigned int reserved : 4;
- unsigned int opcode : 11;
- unsigned int scalar : 1;
+};
+typedef float (*pres_op_func)(float **args, unsigned int n);
+static float pres_ftou(float **args, unsigned int n) +{
- unsigned int u = *args[0];
- return *(float *)&u;
+}
+static float pres_add(float **args, unsigned int n) +{
- return *args[0] + *args[1];
+}
+enum preshader_op +{
- D3D10_PRESHADER_OP_FTOU = 0,
- D3D10_PRESHADER_OP_ADD,
- D3D10_PRESHADER_OP_LAST_OP,
+};
+struct preshader_op_info +{
- unsigned short idx;
- unsigned short opcode;
- char name[8];
- pres_op_func func;
+};
idx is an enum preshader_op, right? Any reason you're not using that type? The field name seems to have room for improvement too (although I realize the trouble with "opcode" also there).
Correct, it's that enum. Strictly speaking I don't need that field at all, for static array like that I can always use pointer value to get the index.
On Mon, Nov 1, 2021 at 11:52 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/effect.c | 556 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 114 ++++++++ 2 files changed, 669 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3ae2ad4f481 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -30,6 +30,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC MAKE_TAG('F', 'X', 'L', 'C') +#define TAG_CLI4 MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB MAKE_TAG('C', 'T', 'A', 'B')
#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 #define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) @@ -180,6 +183,89 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct preshader_instr +{
- unsigned int comp_count : 16;
- unsigned int reserved : 4;
- unsigned int opcode : 11;
- unsigned int scalar : 1;
+};
I see now what's going on with this i.e. this is used to represent instructions as encoded in the bytecode but also after changing "their" opcode with "ours". Is that just to speed up execution?
I find this kind of setup a bit ugly. I do wonder what it would look like if this went all the way e.g. what about using this structure only for parsing and a separate "unpacked" struct preshader_instr for execution? Probably a fixed-size one, including the operands (and operands count) right in the same structure. It would be slightly more tricky at parse time (e.g. you won't know how much memory you'll need before parsing the whole preshader) while making the execution slightly more straightforward. Thinking about it, what I'm suggesting is probably not a good tradeoff and I'd be hard pressed to ask you to make this type of change anyway. I guess I'm mostly curious if you tried something like that (or otherwise something different) before settling on the current solution.
+enum preshader_op +{
- D3D10_PRESHADER_OP_FTOU = 0,
- D3D10_PRESHADER_OP_ADD,
- D3D10_PRESHADER_OP_LAST_OP,
D3D10_PRESHADER_OP_COUNT maybe? Also not great... Maybe just get rid of it and use ~0u or something for the sentinel value?
+};
+struct preshader_op_info +{
- unsigned short idx;
- unsigned short opcode;
- char name[8];
- pres_op_func func;
+};
I already mentioned that this is a bit confusing: idx is "our" opcode, while opcode is "dxbc"'s opcode. Just getting rid of idx, as you wrote in your previous reply, works for me.
+enum d3d10_reg_table_type +{
- D3D10_REG_TABLE_CONSTANTS = 1,
- D3D10_REG_TABLE_CB = 2,
- D3D10_REG_TABLE_RESULT = 4,
- D3D10_REG_TABLE_TEMP = 7,
- D3D10_REG_TABLE_LAST,
For this one D3D10_REG_TABLE_COUNT works.
+};
+struct d3d10_effect_preshader +{
- struct d3d10_reg_table reg_tables[D3D10_REG_TABLE_LAST];
- ID3D10Blob *code;
- struct d3d10_ctab_var *vars;
- unsigned int vars_count;
+};
+struct d3d10_preshader_parse_context +{
- struct d3d10_effect_preshader *preshader;
- struct d3d10_effect *effect;
+};
struct d3d10_effect_prop_dependency { unsigned int id; @@ -192,11 +278,117 @@ struct d3d10_effect_prop_dependency struct d3d10_effect_variable *v; unsigned int offset; } var;
struct
{
struct d3d10_effect_variable *v;
struct d3d10_effect_preshader index;
} u;} index_expr;
};
I still think that we can get rid of the "u" name for the union. It doesn't need to happen in this patch though.
+static HRESULT d3d10_effect_preshader_eval(struct d3d10_effect_preshader *p) +{
- unsigned int i, j, regt, offset, instr_count, input_count;
- const DWORD *ip = ID3D10Blob_GetBufferPointer(p->code);
- float *dst, *args[4], *retval;
- struct preshader_instr ins;
- dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_RESULT, 0);
- memset(dst, 0, sizeof(float) * p->reg_tables[D3D10_REG_TABLE_RESULT].count);
- /* Update constant buffer */
- dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_CB, 0);
- for (i = 0; i < p->vars_count; ++i)
- {
struct d3d10_ctab_var *v = &p->vars[i];
memcpy(dst + v->offset, v->v->buffer->u.buffer.local_buffer, v->length * sizeof(*dst))
- }
- instr_count = *ip++;
- for (i = 0; i < instr_count; ++i)
- {
*(DWORD *)&ins = *ip++;
input_count = *ip++;
if (input_count > ARRAY_SIZE(args))
{
FIXME("Unexpected argument count %u.\n", input_count);
return E_FAIL;
}
/* Arguments */
for (j = 0; j < input_count; ++j)
{
ip++; /* TODO: currently ignored field */
regt = *ip++;
offset = *ip++;
args[j] = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
}
ip++; /* TODO: currently ignored field */
regt = *ip++;
offset = *ip++;
retval = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
*retval = preshader_ops[ins.opcode].func(args, input_count);
- }
- return S_OK;
+}
Maybe add to the TODO comments an indication of what the ignored field is? If it makes sense.
static void d3d10_effect_clear_prop_dependencies(struct d3d10_effect_prop_dependencies *d) {
- unsigned int i;
- for (i = 0; i < d->count; ++i)
- {
struct d3d10_effect_prop_dependency *dep = &d->entries[i];
switch (dep->operation)
{
case D3D10_EOO_INDEX_EXPRESSION:
d3d10_effect_preshader_clear(&dep->u.index_expr.index);
break;
default:
;
}
- } heap_free(d->entries); memset(d, 0, sizeof(*d));
}
I think you can drop the default: entirely without triggering warnings.
@@ -546,6 +741,38 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende
break;
case D3D10_EOO_INDEX_EXPRESSION:
v = d->u.index_expr.v;
if (FAILED(hr = d3d10_effect_preshader_eval(&d->u.index_expr.index)))
{
WARN("Failed to evaluate index expression, hr %#x.\n", hr);
return;
}
variable_idx = *d->u.index_expr.index.reg_tables[D3D10_REG_TABLE_RESULT].u.dword;
if (variable_idx >= v->type->element_count)
{
WARN("Expression evaluated to invalid index value %u, array %s of size %u.\n",
variable_idx, debugstr_a(v->name), v->type->element_count);
return;
}
switch (property_info->type)
{
case D3D10_SVT_VERTEXSHADER:
case D3D10_SVT_PIXELSHADER:
case D3D10_SVT_GEOMETRYSHADER:
((void **)dst)[d->idx] = v;
*dst_index = variable_idx;
break;
default:
((void **)dst)[d->idx] = &v->elements[variable_idx];
}
break;
default: FIXME("Unsupported property update for %u.\n", d->operation); }
Again mostly wondering: does D3D10_EOO_INDEX_EXPRESSION apply to other object types, like textures? Similarly, have you seen any case where d->idx is not 0 for shaders? What does it even mean a non-zero idx in that case?
+static HRESULT parse_fx10_fxlc(void *ctx, const char *data, unsigned int data_size) +{
- struct d3d10_preshader_parse_context *context = ctx;
- struct d3d10_effect_preshader *p = context->preshader;
- uint32_t ins_count;
- const char *ptr;
- unsigned int i;
- HRESULT hr;
- if (data_size % sizeof(DWORD))
- {
WARN("FXLC size misaligned %u.\n", data_size);
return E_FAIL;
- }
- /* Parse through bytecode copy, so we can patch opcodes. */
- if (FAILED(hr = D3DCreateBlob(data_size, &p->code)))
return hr;
- memcpy(ID3D10Blob_GetBufferPointer(p->code), data, data_size);
- ptr = ID3D10Blob_GetBufferPointer(p->code);
Not a big deal, but you could move up this assignment to avoid duplicating the GetBufferPointer() call.
- read_dword(&ptr, &ins_count);
- TRACE("%u instructions.\n", ins_count);
- for (i = 0; i < ins_count; ++i)
- {
if (FAILED(hr = parse_fx10_preshader_instr(p, &ptr)))
{
WARN("Failed to parse instruction %u.\n", i);
return hr;
}
- }
- if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_RESULT],
p->reg_tables[D3D10_REG_TABLE_RESULT].count))) return hr;
- if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_TEMP],
p->reg_tables[D3D10_REG_TABLE_TEMP].count))) return hr;
All the calls to d3d10_reg_table_allocate() but one pass table->count as count value, which is then initialized again with the same value by the function. That works but it doesn't look particularly nice.
+static HRESULT parse_fx10_ctab(void *ctx, const char *data, unsigned int data_size) +{
- struct d3d10_preshader_parse_context *context = ctx;
- struct d3d10_effect_preshader *p = context->preshader;
- struct ctab_header
- {
DWORD size;
DWORD creator;
DWORD version;
DWORD constants;
DWORD constantinfo;
DWORD flags;
DWORD target;
- } header;
- struct ctab_const_info
- {
DWORD name;
WORD register_set;
WORD register_index;
WORD register_count;
WORD reserved;
DWORD typeinfo;
DWORD default_value;
- } *info;
- unsigned int i, cb_reg_count = 0;
- const char *ptr = data;
- const char *name;
- size_t name_len;
- HRESULT hr;
- if (data_size < sizeof(header))
- {
WARN("Invalid constant table size %u.\n", data_size);
return E_FAIL;
- }
- read_dword(&ptr, &header.size);
- read_dword(&ptr, &header.creator);
- read_dword(&ptr, &header.version);
- read_dword(&ptr, &header.constants);
- read_dword(&ptr, &header.constantinfo);
- read_dword(&ptr, &header.flags);
- read_dword(&ptr, &header.target);
- if (!require_space(header.constantinfo, header.constants, sizeof(*info) / sizeof(DWORD),
data_size))
I think you want plain sizeof(*info) there, without any division.
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index da644d8d9db..c2ed9c6071e 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7801,6 +7801,119 @@ static void test_effect_dynamic_numeric_field(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+#if 0 +float4 g_var; +PixelShader ps_array[2]; +VertexShader vs_array[2]; +technique10 tech +{
- pass p0
- {
SetPixelShader( ps_array[g_var.z] );
SetVertexShader( vs_array[g_var.x + 0.1f] );
- }
+} +#endif +static DWORD fx_test_index_expression[] = +{
- 0x43425844, 0x83787296, 0xf866b7a9, 0x7b56930c, 0xdc9d061a, 0x00000001, 0x000003e9, 0x00000001,
- 0x00000024, 0x30315846, 0x000003bd, 0xfeff1001, 0x00000001, 0x00000001, 0x00000002, 0x00000000,
- 0x00000000, 0x00000000, 0x00000001, 0x000002cd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x6f6c4724,
- 0x736c6162, 0x6f6c6600, 0x00347461, 0x0000000d, 0x00000001, 0x00000000, 0x00000010, 0x00000010,
- 0x00000010, 0x0000210a, 0x61765f67, 0x69500072, 0x536c6578, 0x65646168, 0x00360072, 0x00020000,
- 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00050000, 0x73700000, 0x7272615f, 0x56007961,
- 0x65747265, 0x61685378, 0x00726564, 0x00000067, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
- 0x00000000, 0x00000006, 0x615f7376, 0x79617272, 0x63657400, 0x30700068, 0x0000ec00, 0x42584400,
- 0x990a9743, 0xd17834e6, 0x40de477e, 0xf476a79f, 0x00000101, 0x0000ec00, 0x00000300, 0x00002c00,
- 0x0000a800, 0x0000b400, 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146,
- 0x00001c00, 0x00010000, 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000,
- 0x765f6700, 0xab007261, 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d,
- 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265,
- 0x00312e30, 0x494c43ab, 0x00000434, 0x00000000, 0x4c584600, 0x00003043, 0x00000100, 0x30000100,
- 0x00000113, 0x00000000, 0x00000200, 0x00000200, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000,
- 0x0f0f0ff0, 0x00ffff0f, 0x00005e00, 0x0000a100, 0x00012800, 0x42584400, 0x78de2e43, 0x31414e7a,
- 0xf69158cd, 0x416c97b6, 0x00000192, 0x00012800, 0x00000300, 0x00002c00, 0x0000a800, 0x0000c400,
- 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146, 0x00001c00, 0x00010000,
- 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000, 0x765f6700, 0xab007261,
- 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d, 0x666f736f, 0x52282074,
- 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x00312e30, 0x494c43ab,
- 0x00001434, 0x00000400, 0xcccccd00, 0x0000003d, 0x00000000, 0x00000000, 0x4c584600, 0x00005c43,
- 0x00000200, 0x40000100, 0x00000220, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000100,
- 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x30000100, 0x00000113, 0x00000000, 0x00000700,
- 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000, 0x0f0f0ff0, 0x00ffff0f, 0x00009000,
- 0x00019900, 0x00000400, 0x00001000, 0x00000000, 0x00000100, 0xffffff00, 0x000000ff, 0x00003000,
- 0x00001400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00005e00, 0x00004200,
- 0x00000000, 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009000, 0x00007400, 0x00000000,
- 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009900, 0x00000100, 0x00000000, 0x00009e00,
- 0x00000200, 0x00000000, 0x00000700, 0x00000000, 0x00000500, 0x00019100, 0x00000600, 0x00000000,
- 0x00000500, 0x0002c500, 0x00000000,
+};
+static void test_effect_index_expression(void) +{
- ID3D10EffectTechnique *tech;
- ID3D10EffectPass *pass;
- ID3D10Effect *effect;
- ID3D10Device *device;
- ULONG refcount;
- HRESULT hr;
- D3D10_PASS_SHADER_DESC shader_desc;
- ID3D10EffectVectorVariable *vector;
- ID3D10EffectVariable *v;
- float val[4];
Nitpick, order of the declarations. Nice test otherwise.
On 11/5/21 7:32 PM, Matteo Bruni wrote:
On Mon, Nov 1, 2021 at 11:52 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/effect.c | 556 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 114 ++++++++ 2 files changed, 669 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3ae2ad4f481 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -30,6 +30,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC MAKE_TAG('F', 'X', 'L', 'C') +#define TAG_CLI4 MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB MAKE_TAG('C', 'T', 'A', 'B')
#define D3D10_FX10_TYPE_COLUMN_SHIFT 11 #define D3D10_FX10_TYPE_COLUMN_MASK (0x7 << D3D10_FX10_TYPE_COLUMN_SHIFT) @@ -180,6 +183,89 @@ static enum d3d10_effect_container_type get_var_container_type(const struct d3d1 } }
+struct preshader_instr +{
- unsigned int comp_count : 16;
- unsigned int reserved : 4;
- unsigned int opcode : 11;
- unsigned int scalar : 1;
+};
I see now what's going on with this i.e. this is used to represent instructions as encoded in the bytecode but also after changing "their" opcode with "ours". Is that just to speed up execution?
The only reason is to be able to use index access, and not to look up by opcode value.
For practical purposes, it's definitely fine to keep it even more simple for initial version, and not patch original field. The only real world use of this that I saw so far was a single "ftou(var)" call.
I'd prefer smaller initial version to something too complex to matter in practice.
I find this kind of setup a bit ugly. I do wonder what it would look like if this went all the way e.g. what about using this structure only for parsing and a separate "unpacked" struct preshader_instr for execution? Probably a fixed-size one, including the operands (and operands count) right in the same structure. It would be slightly more tricky at parse time (e.g. you won't know how much memory you'll need before parsing the whole preshader) while making the execution slightly more straightforward. Thinking about it, what I'm suggesting is probably not a good tradeoff and I'd be hard pressed to ask you to make this type of change anyway. I guess I'm mostly curious if you tried something like that (or otherwise something different) before settling on the current solution.
I haven't tried, but I looked at d3dx9 variant, and that does some unnecessary work I think, by that kind of repacking of original blob to some internal structures. We can do it either way, but I don't see a point of inventing different structure, that doesn't offer anything comparing to raw blob.
+enum preshader_op +{
- D3D10_PRESHADER_OP_FTOU = 0,
- D3D10_PRESHADER_OP_ADD,
- D3D10_PRESHADER_OP_LAST_OP,
D3D10_PRESHADER_OP_COUNT maybe? Also not great... Maybe just get rid of it and use ~0u or something for the sentinel value?
Commented above, we could get rid of this entirely for now and bsearch (or not, because there is only 2 ops for now, and even ADD was added for testing purposes).
+};
+struct preshader_op_info +{
- unsigned short idx;
- unsigned short opcode;
- char name[8];
- pres_op_func func;
+};
I already mentioned that this is a bit confusing: idx is "our" opcode, while opcode is "dxbc"'s opcode. Just getting rid of idx, as you wrote in your previous reply, works for me.
Ok.
+enum d3d10_reg_table_type +{
- D3D10_REG_TABLE_CONSTANTS = 1,
- D3D10_REG_TABLE_CB = 2,
- D3D10_REG_TABLE_RESULT = 4,
- D3D10_REG_TABLE_TEMP = 7,
- D3D10_REG_TABLE_LAST,
For this one D3D10_REG_TABLE_COUNT works.
+};
+struct d3d10_effect_preshader +{
- struct d3d10_reg_table reg_tables[D3D10_REG_TABLE_LAST];
- ID3D10Blob *code;
- struct d3d10_ctab_var *vars;
- unsigned int vars_count;
+};
+struct d3d10_preshader_parse_context +{
- struct d3d10_effect_preshader *preshader;
- struct d3d10_effect *effect;
+};
struct d3d10_effect_prop_dependency { unsigned int id; @@ -192,11 +278,117 @@ struct d3d10_effect_prop_dependency struct d3d10_effect_variable *v; unsigned int offset; } var;
struct
{
struct d3d10_effect_variable *v;
struct d3d10_effect_preshader index;
} u;} index_expr;
};
I still think that we can get rid of the "u" name for the union. It doesn't need to happen in this patch though.
Will do.
+static HRESULT d3d10_effect_preshader_eval(struct d3d10_effect_preshader *p) +{
- unsigned int i, j, regt, offset, instr_count, input_count;
- const DWORD *ip = ID3D10Blob_GetBufferPointer(p->code);
- float *dst, *args[4], *retval;
- struct preshader_instr ins;
- dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_RESULT, 0);
- memset(dst, 0, sizeof(float) * p->reg_tables[D3D10_REG_TABLE_RESULT].count);
- /* Update constant buffer */
- dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_CB, 0);
- for (i = 0; i < p->vars_count; ++i)
- {
struct d3d10_ctab_var *v = &p->vars[i];
memcpy(dst + v->offset, v->v->buffer->u.buffer.local_buffer, v->length * sizeof(*dst))
- }
- instr_count = *ip++;
- for (i = 0; i < instr_count; ++i)
- {
*(DWORD *)&ins = *ip++;
input_count = *ip++;
if (input_count > ARRAY_SIZE(args))
{
FIXME("Unexpected argument count %u.\n", input_count);
return E_FAIL;
}
/* Arguments */
for (j = 0; j < input_count; ++j)
{
ip++; /* TODO: currently ignored field */
regt = *ip++;
offset = *ip++;
args[j] = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
}
ip++; /* TODO: currently ignored field */
regt = *ip++;
offset = *ip++;
retval = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
*retval = preshader_ops[ins.opcode].func(args, input_count);
- }
- return S_OK;
+}
Maybe add to the TODO comments an indication of what the ignored field is? If it makes sense.
Sure, it means the same thing as in d3dx9 - indexed access.
static void d3d10_effect_clear_prop_dependencies(struct d3d10_effect_prop_dependencies *d) {
- unsigned int i;
- for (i = 0; i < d->count; ++i)
- {
struct d3d10_effect_prop_dependency *dep = &d->entries[i];
switch (dep->operation)
{
case D3D10_EOO_INDEX_EXPRESSION:
d3d10_effect_preshader_clear(&dep->u.index_expr.index);
break;
default:
;
}
- } heap_free(d->entries); memset(d, 0, sizeof(*d));
}
I think you can drop the default: entirely without triggering warnings.
@@ -546,6 +741,38 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende
break;
case D3D10_EOO_INDEX_EXPRESSION:
v = d->u.index_expr.v;
if (FAILED(hr = d3d10_effect_preshader_eval(&d->u.index_expr.index)))
{
WARN("Failed to evaluate index expression, hr %#x.\n", hr);
return;
}
variable_idx = *d->u.index_expr.index.reg_tables[D3D10_REG_TABLE_RESULT].u.dword;
if (variable_idx >= v->type->element_count)
{
WARN("Expression evaluated to invalid index value %u, array %s of size %u.\n",
variable_idx, debugstr_a(v->name), v->type->element_count);
return;
}
switch (property_info->type)
{
case D3D10_SVT_VERTEXSHADER:
case D3D10_SVT_PIXELSHADER:
case D3D10_SVT_GEOMETRYSHADER:
((void **)dst)[d->idx] = v;
*dst_index = variable_idx;
break;
default:
((void **)dst)[d->idx] = &v->elements[variable_idx];
}
break;
default: FIXME("Unsupported property update for %u.\n", d->operation); }
Again mostly wondering: does D3D10_EOO_INDEX_EXPRESSION apply to other object types, like textures? Similarly, have you seen any case where d->idx is not 0 for shaders? What does it even mean a non-zero idx in that case?
That's a good question. I copied this from other similar places, but you might be right, and it's meaningless here, because it's always 0.
There are no object-typed properties that are arrays, and indexed expression I believe is used only for arrays of objects, e.g. d->idx (== 2) would matter for cases like this
BlendState blend_state { RenderTargetWriteMask[2] = <expression> };
But that would compile to another type of operation - value expression, you can't use buffer numeric variable array as right hand value here, like
RenderTargetWriteMask[2] = value[idx_var + 1];
it would be expanded to full expression returning result and not to value[<expression>], with expression returning index.
I have to test that again, but most likely it's possible to get rid of d->idx there.
+static HRESULT parse_fx10_fxlc(void *ctx, const char *data, unsigned int data_size) +{
- struct d3d10_preshader_parse_context *context = ctx;
- struct d3d10_effect_preshader *p = context->preshader;
- uint32_t ins_count;
- const char *ptr;
- unsigned int i;
- HRESULT hr;
- if (data_size % sizeof(DWORD))
- {
WARN("FXLC size misaligned %u.\n", data_size);
return E_FAIL;
- }
- /* Parse through bytecode copy, so we can patch opcodes. */
- if (FAILED(hr = D3DCreateBlob(data_size, &p->code)))
return hr;
- memcpy(ID3D10Blob_GetBufferPointer(p->code), data, data_size);
- ptr = ID3D10Blob_GetBufferPointer(p->code);
Not a big deal, but you could move up this assignment to avoid duplicating the GetBufferPointer() call.
- read_dword(&ptr, &ins_count);
- TRACE("%u instructions.\n", ins_count);
- for (i = 0; i < ins_count; ++i)
- {
if (FAILED(hr = parse_fx10_preshader_instr(p, &ptr)))
{
WARN("Failed to parse instruction %u.\n", i);
return hr;
}
- }
- if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_RESULT],
p->reg_tables[D3D10_REG_TABLE_RESULT].count))) return hr;
- if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_TEMP],
p->reg_tables[D3D10_REG_TABLE_TEMP].count))) return hr;
All the calls to d3d10_reg_table_allocate() but one pass table->count as count value, which is then initialized again with the same value by the function. That works but it doesn't look particularly nice.
+static HRESULT parse_fx10_ctab(void *ctx, const char *data, unsigned int data_size) +{
- struct d3d10_preshader_parse_context *context = ctx;
- struct d3d10_effect_preshader *p = context->preshader;
- struct ctab_header
- {
DWORD size;
DWORD creator;
DWORD version;
DWORD constants;
DWORD constantinfo;
DWORD flags;
DWORD target;
- } header;
- struct ctab_const_info
- {
DWORD name;
WORD register_set;
WORD register_index;
WORD register_count;
WORD reserved;
DWORD typeinfo;
DWORD default_value;
- } *info;
- unsigned int i, cb_reg_count = 0;
- const char *ptr = data;
- const char *name;
- size_t name_len;
- HRESULT hr;
- if (data_size < sizeof(header))
- {
WARN("Invalid constant table size %u.\n", data_size);
return E_FAIL;
- }
- read_dword(&ptr, &header.size);
- read_dword(&ptr, &header.creator);
- read_dword(&ptr, &header.version);
- read_dword(&ptr, &header.constants);
- read_dword(&ptr, &header.constantinfo);
- read_dword(&ptr, &header.flags);
- read_dword(&ptr, &header.target);
- if (!require_space(header.constantinfo, header.constants, sizeof(*info) / sizeof(DWORD),
data_size))
I think you want plain sizeof(*info) there, without any division.
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c index da644d8d9db..c2ed9c6071e 100644 --- a/dlls/d3d10/tests/effect.c +++ b/dlls/d3d10/tests/effect.c @@ -7801,6 +7801,119 @@ static void test_effect_dynamic_numeric_field(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+#if 0 +float4 g_var; +PixelShader ps_array[2]; +VertexShader vs_array[2]; +technique10 tech +{
- pass p0
- {
SetPixelShader( ps_array[g_var.z] );
SetVertexShader( vs_array[g_var.x + 0.1f] );
- }
+} +#endif +static DWORD fx_test_index_expression[] = +{
- 0x43425844, 0x83787296, 0xf866b7a9, 0x7b56930c, 0xdc9d061a, 0x00000001, 0x000003e9, 0x00000001,
- 0x00000024, 0x30315846, 0x000003bd, 0xfeff1001, 0x00000001, 0x00000001, 0x00000002, 0x00000000,
- 0x00000000, 0x00000000, 0x00000001, 0x000002cd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x6f6c4724,
- 0x736c6162, 0x6f6c6600, 0x00347461, 0x0000000d, 0x00000001, 0x00000000, 0x00000010, 0x00000010,
- 0x00000010, 0x0000210a, 0x61765f67, 0x69500072, 0x536c6578, 0x65646168, 0x00360072, 0x00020000,
- 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00050000, 0x73700000, 0x7272615f, 0x56007961,
- 0x65747265, 0x61685378, 0x00726564, 0x00000067, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
- 0x00000000, 0x00000006, 0x615f7376, 0x79617272, 0x63657400, 0x30700068, 0x0000ec00, 0x42584400,
- 0x990a9743, 0xd17834e6, 0x40de477e, 0xf476a79f, 0x00000101, 0x0000ec00, 0x00000300, 0x00002c00,
- 0x0000a800, 0x0000b400, 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146,
- 0x00001c00, 0x00010000, 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000,
- 0x765f6700, 0xab007261, 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d,
- 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265,
- 0x00312e30, 0x494c43ab, 0x00000434, 0x00000000, 0x4c584600, 0x00003043, 0x00000100, 0x30000100,
- 0x00000113, 0x00000000, 0x00000200, 0x00000200, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000,
- 0x0f0f0ff0, 0x00ffff0f, 0x00005e00, 0x0000a100, 0x00012800, 0x42584400, 0x78de2e43, 0x31414e7a,
- 0xf69158cd, 0x416c97b6, 0x00000192, 0x00012800, 0x00000300, 0x00002c00, 0x0000a800, 0x0000c400,
- 0x41544300, 0x00007442, 0x00001c00, 0x00004b00, 0x58040000, 0x00000146, 0x00001c00, 0x00010000,
- 0x00004800, 0x00003000, 0x00000200, 0x00000100, 0x00003800, 0x00000000, 0x765f6700, 0xab007261,
- 0x030001ab, 0x04000100, 0x00000100, 0x00000000, 0x00787400, 0x7263694d, 0x666f736f, 0x52282074,
- 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265, 0x00312e30, 0x494c43ab,
- 0x00001434, 0x00000400, 0xcccccd00, 0x0000003d, 0x00000000, 0x00000000, 0x4c584600, 0x00005c43,
- 0x00000200, 0x40000100, 0x00000220, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000100,
- 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x30000100, 0x00000113, 0x00000000, 0x00000700,
- 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0xf0f0f000, 0x0f0f0ff0, 0x00ffff0f, 0x00009000,
- 0x00019900, 0x00000400, 0x00001000, 0x00000000, 0x00000100, 0xffffff00, 0x000000ff, 0x00003000,
- 0x00001400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00005e00, 0x00004200,
- 0x00000000, 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009000, 0x00007400, 0x00000000,
- 0xffffff00, 0x000000ff, 0x00000000, 0x00000000, 0x00009900, 0x00000100, 0x00000000, 0x00009e00,
- 0x00000200, 0x00000000, 0x00000700, 0x00000000, 0x00000500, 0x00019100, 0x00000600, 0x00000000,
- 0x00000500, 0x0002c500, 0x00000000,
+};
+static void test_effect_index_expression(void) +{
- ID3D10EffectTechnique *tech;
- ID3D10EffectPass *pass;
- ID3D10Effect *effect;
- ID3D10Device *device;
- ULONG refcount;
- HRESULT hr;
- D3D10_PASS_SHADER_DESC shader_desc;
- ID3D10EffectVectorVariable *vector;
- ID3D10EffectVariable *v;
- float val[4];
Nitpick, order of the declarations. Nice test otherwise.