d3dx9/tests: Add tests for ID3DXConstantTable::SetDefaults.
[wine] / dlls / d3dx9_36 / tests / shader.c
1 /*
2  * Copyright 2008 Luis Busquets
3  * Copyright 2011 Travis Athougies
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "wine/test.h"
21 #include "d3dx9.h"
22
23 static const DWORD simple_vs[] = {
24     0xfffe0101,                                                             /* vs_1_1                       */
25     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position0 v0             */
26     0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000,                         /* dp4 oPos.x, v0, c0           */
27     0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001,                         /* dp4 oPos.y, v0, c1           */
28     0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002,                         /* dp4 oPos.z, v0, c2           */
29     0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003,                         /* dp4 oPos.w, v0, c3           */
30     0x0000ffff};                                                            /* END                          */
31
32 static const DWORD simple_ps[] = {
33     0xffff0101,                                                             /* ps_1_1                       */
34     0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0  */
35     0x00000042, 0xb00f0000,                                                 /* tex t0                       */
36     0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000,                         /* dp3 r0, c1, c0               */
37     0x00000005, 0x800f0000, 0x90e40000, 0x80e40000,                         /* mul r0, v0, r0               */
38     0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000,                         /* mul r0, t0, r0               */
39     0x0000ffff};                                                            /* END                          */
40
41 #define FCC_TEXT MAKEFOURCC('T','E','X','T')
42 #define FCC_CTAB MAKEFOURCC('C','T','A','B')
43
44 static const DWORD shader_with_ctab[] = {
45     0xfffe0300,                                                             /* vs_3_0                       */
46     0x0002fffe, FCC_TEXT,   0x00000000,                                     /* TEXT comment                 */
47     0x0008fffe, FCC_CTAB,   0x0000001c, 0x00000010, 0xfffe0300, 0x00000000, /* CTAB comment                 */
48                 0x00000000, 0x00000000, 0x00000000,
49     0x0004fffe, FCC_TEXT,   0x00000000, 0x00000000, 0x00000000,             /* TEXT comment                 */
50     0x0000ffff};                                                            /* END                          */
51
52 static const DWORD shader_with_invalid_ctab[] = {
53     0xfffe0300,                                                             /* vs_3_0                       */
54     0x0005fffe, FCC_CTAB,                                                   /* CTAB comment                 */
55                 0x0000001c, 0x000000a9, 0xfffe0300,
56                 0x00000000, 0x00000000,
57     0x0000ffff};                                                            /* END                          */
58
59 static const DWORD shader_with_ctab_constants[] = {
60     0xfffe0300,                                                             /* vs_3_0                       */
61     0x002efffe, FCC_CTAB,                                                   /* CTAB comment                 */
62     0x0000001c, 0x000000a4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header                       */
63     0x0000009c,
64     0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000,             /* Constant 1 desc              */
65     0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000,             /* Constant 2 desc              */
66     0x00000090, 0x00040002, 0x00000003, 0x00000080, 0x00000000,             /* Constant 3 desc              */
67     0x736e6f43, 0x746e6174, 0xabab0031,                                     /* Constant 1 name string       */
68     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc         */
69     0x736e6f43, 0x746e6174, 0xabab0032,                                     /* Constant 2 name string       */
70     0x00030003, 0x00040004, 0x00000001, 0x00000000,                         /* Constant 2 & 3 type desc     */
71     0x736e6f43, 0x746e6174, 0xabab0033,                                     /* Constant 3 name string       */
72     0x335f7376, 0xab00305f,                                                 /* Target name string           */
73     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string          */
74     0x0000ffff};                                                            /* END                          */
75
76 static const DWORD ctab_basic[] = {
77     0xfffe0300,                                                             /* vs_3_0                       */
78     0x0040fffe, FCC_CTAB,                                                   /* CTAB comment                 */
79     0x0000001c, 0x000000ec, 0xfffe0300, 0x00000005, 0x0000001c, 0x20008100, /* Header                       */
80     0x000000e4,
81     0x00000080, 0x00060002, 0x00000001, 0x00000084, 0x00000000,             /* Constant 1 desc (f)          */
82     0x00000094, 0x00070002, 0x00000001, 0x00000098, 0x00000000,             /* Constant 2 desc (f4)         */
83     0x000000A8, 0x00040002, 0x00000001, 0x000000AC, 0x00000000,             /* Constant 3 desc (i)          */
84     0x000000BC, 0x00050002, 0x00000001, 0x000000C0, 0x00000000,             /* Constant 4 desc (i4)         */
85     0x000000D0, 0x00000002, 0x00000004, 0x000000D4, 0x00000000,             /* Constant 5 desc (mvp)        */
86     0xabab0066, 0x00030000, 0x00010001, 0x00000001, 0x00000000,             /* Constant 1 name/type desc    */
87     0xab003466, 0x00030001, 0x00040001, 0x00000001, 0x00000000,             /* Constant 2 name/type desc    */
88     0xabab0069, 0x00020000, 0x00010001, 0x00000001, 0x00000000,             /* Constant 3 name/type desc    */
89     0xab003469, 0x00020001, 0x00040001, 0x00000001, 0x00000000,             /* Constant 4 name/type desc    */
90     0x0070766d, 0x00030003, 0x00040004, 0x00000001, 0x00000000,             /* Constant 5 name/type desc    */
91     0x335f7376, 0xab00305f,                                                 /* Target name string           */
92     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string          */
93     0x0000ffff};                                                            /* END                          */
94
95 static const D3DXCONSTANT_DESC ctab_basic_expected[] = {
96     {"mvp", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL},
97     {"i",   D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR,         D3DXPT_INT,   1, 1, 1, 0,  4, NULL},
98     {"i4",  D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR,         D3DXPT_INT,   1, 4, 1, 0, 16, NULL},
99     {"f",   D3DXRS_FLOAT4, 6, 1, D3DXPC_SCALAR,         D3DXPT_FLOAT, 1, 1, 1, 0,  4, NULL},
100     {"f4",  D3DXRS_FLOAT4, 7, 1, D3DXPC_VECTOR,         D3DXPT_FLOAT, 1, 4, 1, 0, 16, NULL}};
101
102 static const DWORD ctab_matrices[] = {
103     0xfffe0300,                                                             /* vs_3_0                       */
104     0x0032fffe, FCC_CTAB,                                                   /* CTAB comment                 */
105     0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header                       */
106     0x000000ac,
107     0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000,             /* Constant 1 desc (fmatrix3x1) */
108     0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000,             /* Constant 2 desc (fmatrix4x4) */
109     0x00000090, 0x00040002, 0x00000003, 0x0000009c, 0x00000000,             /* Constant 3 desc (imatrix2x3) */
110     0x74616D66, 0x33786972, 0xab003178,                                     /* Constant 1 name              */
111     0x00030003, 0x00010003, 0x00000001, 0x00000000,                         /* Constant 1 type desc         */
112     0x74616D66, 0x34786972, 0xab003478,                                     /* Constant 2 name              */
113     0x00030003, 0x00040004, 0x00000001, 0x00000000,                         /* Constant 2 type desc         */
114     0x74616D69, 0x32786972, 0xab003378,                                     /* Constant 3 name              */
115     0x00020002, 0x00030002, 0x00000001, 0x00000000,                         /* Constant 3 type desc         */
116     0x335f7376, 0xab00305f,                                                 /* Target name string           */
117     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string          */
118     0x0000ffff};                                                            /* END                          */
119
120 static const D3DXCONSTANT_DESC ctab_matrices_expected[] = {
121     {"fmatrix4x4", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL},
122     {"imatrix2x3", D3DXRS_FLOAT4, 4, 3, D3DXPC_MATRIX_ROWS,    D3DXPT_INT,   2, 3, 1, 0, 24, NULL},
123     {"fmatrix3x1", D3DXRS_FLOAT4, 7, 1, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}};
124
125 static const DWORD ctab_arrays[] = {
126     0xfffe0300,                                                             /* vs_3_0                       */
127     0x0052fffe, FCC_CTAB,                                                   /* CTAB comment                 */
128     0x0000001c, 0x0000013c, 0xfffe0300, 0x00000006, 0x0000001c, 0x20008100, /* Header                       */
129     0x00000134,
130     0x00000094, 0x000E0002, 0x00000002, 0x0000009c, 0x00000000,             /* Constant 1 desc (barray)     */
131     0x000000ac, 0x00100002, 0x00000002, 0x000000b8, 0x00000000,             /* Constant 2 desc (bvecarray)  */
132     0x000000c8, 0x00080002, 0x00000004, 0x000000d0, 0x00000000,             /* Constant 3 desc (farray)     */
133     0x000000e0, 0x00000002, 0x00000008, 0x000000ec, 0x00000000,             /* Constant 4 desc (fmtxarray)  */
134     0x000000fc, 0x000C0002, 0x00000002, 0x00000108, 0x00000000,             /* Constant 5 desc (fvecarray)  */
135     0x00000118, 0x00120002, 0x00000001, 0x00000124, 0x00000000,             /* Constant 6 desc (ivecarray)  */
136     0x72726162, 0xab007961,                                                 /* Constant 1 name              */
137     0x00010000, 0x00010001, 0x00000002, 0x00000000,                         /* Constant 1 type desc         */
138     0x63657662, 0x61727261, 0xabab0079,                                     /* Constant 2 name              */
139     0x00010001, 0x00030001, 0x00000003, 0x00000000,                         /* Constant 2 type desc         */
140     0x72726166, 0xab007961,                                                 /* Constant 3 name              */
141     0x00030000, 0x00010001, 0x00000004, 0x00000000,                         /* constant 3 type desc         */
142     0x78746d66, 0x61727261, 0xabab0079,                                     /* Constant 4 name              */
143     0x00030002, 0x00040004, 0x00000002, 0x00000000,                         /* Constant 4 type desc         */
144     0x63657666, 0x61727261, 0xabab0079,                                     /* Constant 5 name              */
145     0x00030001, 0x00040001, 0x00000002, 0x00000000,                         /* Constant 5 type desc         */
146     0x63657669, 0x61727261, 0xabab0079,                                     /* Constant 6 name              */
147     0x00020001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 6 type desc         */
148     0x335f7376, 0xab00305f,                                                 /* Target name string           */
149     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string          */
150     0x0000ffff};                                                            /* END                          */
151
152 static const D3DXCONSTANT_DESC ctab_arrays_expected[] = {
153     {"fmtxarray", D3DXRS_FLOAT4,  0, 8, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 2, 0, 128, NULL},
154     {"farray",    D3DXRS_FLOAT4,  8, 4, D3DXPC_SCALAR,      D3DXPT_FLOAT, 1, 1, 4, 0,  16, NULL},
155     {"fvecarray", D3DXRS_FLOAT4, 12, 2, D3DXPC_VECTOR,      D3DXPT_FLOAT, 1, 4, 2, 0,  32, NULL},
156     {"barray",    D3DXRS_FLOAT4, 14, 2, D3DXPC_SCALAR,      D3DXPT_BOOL,  1, 1, 2, 0,   8, NULL},
157     {"bvecarray", D3DXRS_FLOAT4, 16, 2, D3DXPC_VECTOR,      D3DXPT_BOOL,  1, 3, 3, 0,  36, NULL},
158     {"ivecarray", D3DXRS_FLOAT4, 18, 1, D3DXPC_VECTOR,      D3DXPT_INT,   1, 4, 1, 0,  16, NULL}};
159
160 static const DWORD ctab_with_default_values[] = {
161     0xfffe0200,                                                 /* vs_2_0 */
162     0x007bfffe, FCC_CTAB,                                       /* CTAB comment */
163     0x0000001c, 0x000001b7, 0xfffe0200, 0x00000005, 0x0000001c, /* header */
164     0x00000100, 0x000001b0,
165     0x00000080, 0x00080002, 0x00000003, 0x00000084, 0x00000094, /* constant 1 desc (arr) */
166     0x000000c4, 0x000c0002, 0x00000001, 0x000000c8, 0x000000d8, /* constant 2 desc (flt) */
167     0x000000e8, 0x00040002, 0x00000004, 0x000000f0, 0x00000100, /* constant 3 desc (mat3) */
168     0x00000140, 0x00000002, 0x00000004, 0x000000f0, 0x00000148, /* constant 4 desc (mat4) */
169     0x00000188, 0x000b0002, 0x00000001, 0x00000190, 0x000001a0, /* constant 5 desc (vec4) */
170     0x00727261,                                                 /* constant 1 name */
171     0x00030000, 0x00010001, 0x00000003, 0x00000000,             /* constant 1 type desc */
172     0x42c80000, 0x00000000, 0x00000000, 0x00000000,             /* constant 1 default value */
173     0x43480000, 0x00000000, 0x00000000, 0x00000000,
174     0x43960000, 0x00000000, 0x00000000, 0x00000000,
175     0x00746c66,                                                 /* constant 2 name */
176     0x00030000, 0x00010001, 0x00000001, 0x00000000,             /* constant 2 type desc */
177     0x411fd70a, 0x00000000, 0x00000000, 0x00000000,             /* constant 2 default value */
178     0x3374616d,                                                 /* constant 3 name */
179     0xababab00,
180     0x00030003, 0x00040004, 0x00000001, 0x00000000,             /* constant 3 & 4 type desc */
181     0x41300000, 0x425c0000, 0x42c60000, 0x44a42000,             /* constat 3 default value */
182     0x41b00000, 0x42840000, 0x447c8000, 0x44b0c000,
183     0x42040000, 0x429a0000, 0x448ae000, 0x44bd6000,
184     0x42300000, 0x42b00000, 0x44978000, 0x44ca0000,
185     0x3474616d,                                                 /* constant 4 name */
186     0xababab00,
187     0x3f800000, 0x40a00000, 0x41100000, 0x41500000,             /* constant 4 default value */
188     0x40000000, 0x40c00000, 0x41200000, 0x41600000,
189     0x40400000, 0x40e00000, 0x41300000, 0x41700000,
190     0x40800000, 0x41000000, 0x41400000, 0x41800000,
191     0x34636576,                                                 /* constant 5 name */
192     0xababab00,
193     0x00030001, 0x00040001, 0x00000001, 0x00000000,             /* constant 5 type desc */
194     0x41200000, 0x41a00000, 0x41f00000, 0x42200000,             /* constant 5 default value */
195     0x325f7376, 0x4d004141, 0x41414141, 0x00000000,             /* target & creator string */
196     0x0000ffff};                                                /* END */
197
198 static const float mat4_default_value[] = {1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16};
199 static const float mat3_default_value[] = {11, 55, 99, 1313, 22, 66, 1010, 1414, 33, 77, 1111, 1515, 44, 88, 1212, 1616};
200 static const float arr_default_value[] = {100, 0, 0, 0, 200, 0, 0, 0, 300, 0, 0, 0};
201 static const float vec4_default_value[] = {10, 20, 30, 40};
202 static const float flt_default_value[] = {9.99, 0, 0, 0};
203
204 static const D3DXCONSTANT_DESC ctab_with_default_values_expected[] = {
205     {"mat4", D3DXRS_FLOAT4,  0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat4_default_value},
206     {"mat3", D3DXRS_FLOAT4,  4, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat3_default_value},
207     {"arr",  D3DXRS_FLOAT4,  8, 3, D3DXPC_SCALAR,         D3DXPT_FLOAT, 1, 1, 3, 0, 12, arr_default_value},
208     {"vec4", D3DXRS_FLOAT4, 11, 1, D3DXPC_VECTOR,         D3DXPT_FLOAT, 1, 4, 1, 0, 16, vec4_default_value},
209     {"flt",  D3DXRS_FLOAT4, 12, 1, D3DXPC_SCALAR,         D3DXPT_FLOAT, 1, 1, 1, 0,  4, flt_default_value}};
210
211 static const DWORD ctab_samplers[] = {
212     0xfffe0300,                                                             /* vs_3_0                        */
213     0x0032fffe, FCC_CTAB,                                                   /* CTAB comment                  */
214     0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header                        */
215     0x000000ac,
216     0x00000058, 0x00020002, 0x00000001, 0x00000064, 0x00000000,             /* Constant 1 desc (notsampler)  */
217     0x00000074, 0x00000003, 0x00000001, 0x00000080, 0x00000000,             /* Constant 2 desc (sampler1)    */
218     0x00000090, 0x00030003, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 3 desc (sampler2)    */
219     0x73746f6e, 0x6c706d61, 0xab007265,                                     /* Constant 1 name               */
220     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
221     0x706d6173, 0x3172656c, 0xababab00,                                     /* Constant 2 name               */
222     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
223     0x706d6173, 0x3272656c, 0xababab00,                                     /* Constant 3 name               */
224     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
225     0x335f7376, 0xab00305f,                                                 /* Target name string            */
226     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string           */
227     0x0000ffff};                                                            /* END                           */
228
229 static const D3DXCONSTANT_DESC ctab_samplers_expected[] = {
230     {"sampler1",   D3DXRS_SAMPLER, 0, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER2D, 1, 1, 1, 0, 4,  NULL},
231     {"sampler2",   D3DXRS_SAMPLER, 3, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER3D, 1, 1, 1, 0, 4,  NULL},
232     {"notsampler", D3DXRS_FLOAT4,  2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT,     1, 4, 1, 0, 16, NULL}};
233
234 static void test_get_shader_size(void)
235 {
236     UINT shader_size, expected;
237
238     shader_size = D3DXGetShaderSize(simple_vs);
239     expected = sizeof(simple_vs);
240     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
241
242     shader_size = D3DXGetShaderSize(simple_ps);
243     expected = sizeof(simple_ps);
244     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
245
246     shader_size = D3DXGetShaderSize(NULL);
247     ok(shader_size == 0, "Got shader size %u, expected 0\n", shader_size);
248 }
249
250 static void test_get_shader_version(void)
251 {
252     DWORD shader_version;
253
254     shader_version = D3DXGetShaderVersion(simple_vs);
255     ok(shader_version == D3DVS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
256             shader_version, D3DVS_VERSION(1, 1));
257
258     shader_version = D3DXGetShaderVersion(simple_ps);
259     ok(shader_version == D3DPS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
260             shader_version, D3DPS_VERSION(1, 1));
261
262     shader_version = D3DXGetShaderVersion(NULL);
263     ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version);
264 }
265
266 static void test_find_shader_comment(void)
267 {
268     HRESULT hr;
269     LPCVOID data = (LPVOID)0xdeadbeef;
270     UINT size = 100;
271
272     hr = D3DXFindShaderComment(NULL, MAKEFOURCC('C','T','A','B'), &data, &size);
273     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
274     ok(!data, "Got %p, expected NULL\n", data);
275     ok(!size, "Got %u, expected 0\n", size);
276
277     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), NULL, &size);
278     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
279     ok(size == 28, "Got %u, expected 28\n", size);
280
281     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, NULL);
282     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
283     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
284
285     hr = D3DXFindShaderComment(shader_with_ctab, 0, &data, &size);
286     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
287     ok(!data, "Got %p, expected NULL\n", data);
288     ok(!size, "Got %u, expected 0\n", size);
289
290     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('X','X','X','X'), &data, &size);
291     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
292     ok(!data, "Got %p, expected NULL\n", data);
293     ok(!size, "Got %u, expected 0\n", size);
294
295     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, &size);
296     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
297     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
298     ok(size == 28, "Got result %d, expected 28\n", size);
299 }
300
301 static void test_get_shader_constant_table_ex(void)
302 {
303     LPD3DXCONSTANTTABLE constant_table = NULL;
304     HRESULT hr;
305     LPVOID data;
306     DWORD size;
307     D3DXCONSTANTTABLE_DESC desc;
308
309     hr = D3DXGetShaderConstantTableEx(NULL, 0, &constant_table);
310     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
311
312     /* No CTAB data */
313     hr = D3DXGetShaderConstantTableEx(simple_ps, 0, &constant_table);
314     ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
315
316     /* With invalid CTAB data */
317     hr = D3DXGetShaderConstantTableEx(shader_with_invalid_ctab, 0, &constant_table);
318     ok(hr == D3DXERR_INVALIDDATA || broken(hr == D3D_OK), /* winxp 64-bit, w2k3 64-bit */
319        "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
320     if (constant_table) ID3DXConstantTable_Release(constant_table);
321
322     hr = D3DXGetShaderConstantTableEx(shader_with_ctab, 0, &constant_table);
323     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
324
325     if (constant_table)
326     {
327         size = ID3DXConstantTable_GetBufferSize(constant_table);
328         ok(size == 28, "Got result %x, expected 28\n", size);
329
330         data = ID3DXConstantTable_GetBufferPointer(constant_table);
331         ok(!memcmp(data, shader_with_ctab + 6, size), "Retrieved wrong CTAB data\n");
332
333         hr = ID3DXConstantTable_GetDesc(constant_table, NULL);
334         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
335
336         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
337         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
338         ok(desc.Creator == (LPCSTR)data + 0x10, "Got result %p, expected %p\n", desc.Creator, (LPCSTR)data + 0x10);
339         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
340         ok(desc.Constants == 0, "Got result %x, expected 0\n", desc.Constants);
341
342         ID3DXConstantTable_Release(constant_table);
343     }
344
345     hr = D3DXGetShaderConstantTableEx(shader_with_ctab_constants, 0, &constant_table);
346     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
347
348     if (SUCCEEDED(hr))
349     {
350         D3DXHANDLE constant;
351         D3DXCONSTANT_DESC constant_desc;
352         D3DXCONSTANT_DESC constant_desc_save;
353         UINT nb;
354
355         /* Test GetDesc */
356         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
357         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
358         ok(!strcmp(desc.Creator, "Wine project"), "Got result '%s', expected 'Wine project'\n", desc.Creator);
359         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
360         ok(desc.Constants == 3, "Got result %x, expected 3\n", desc.Constants);
361
362         /* Test GetConstant */
363         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
364         ok(constant != NULL, "No constant found\n");
365         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
366         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
367         ok(!strcmp(constant_desc.Name, "Constant1"), "Got result '%s', expected 'Constant1'\n",
368             constant_desc.Name);
369         ok(constant_desc.Class == D3DXPC_VECTOR, "Got result %x, expected %u (D3DXPC_VECTOR)\n",
370             constant_desc.Class, D3DXPC_VECTOR);
371         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
372             constant_desc.Type, D3DXPT_FLOAT);
373         ok(constant_desc.Rows == 1, "Got result %x, expected 1\n", constant_desc.Rows);
374         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
375
376         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 1);
377         ok(constant != NULL, "No constant found\n");
378         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
379         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
380         ok(!strcmp(constant_desc.Name, "Constant2"), "Got result '%s', expected 'Constant2'\n",
381             constant_desc.Name);
382         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
383             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
384         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
385             constant_desc.Type, D3DXPT_FLOAT);
386         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
387         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
388
389         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 2);
390         ok(constant != NULL, "No constant found\n");
391         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
392         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
393         ok(!strcmp(constant_desc.Name, "Constant3"), "Got result '%s', expected 'Constant3'\n",
394             constant_desc.Name);
395         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
396             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
397         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
398             constant_desc.Type, D3DXPT_FLOAT);
399         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
400         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
401         constant_desc_save = constant_desc; /* For GetConstantDesc test */
402
403         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 3);
404         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
405
406         /* Test GetConstantByName */
407         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant unknown");
408         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
409         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant3");
410         ok(constant != NULL, "No constant found\n");
411         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
412         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
413         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
414
415         /* Test GetConstantDesc */
416         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
417         ok(constant != NULL, "No constant found\n");
418         hr = ID3DXConstantTable_GetConstantDesc(constant_table, NULL, &constant_desc, &nb);
419         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
420         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, NULL, &nb);
421         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
422         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, NULL);
423         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
424         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant unknow", &constant_desc, &nb);
425         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
426         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant3", &constant_desc, &nb);
427         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
428         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
429
430         ID3DXConstantTable_Release(constant_table);
431     }
432 }
433
434 static void test_constant_table(const char *test_name, const DWORD *ctable_fn,
435         const D3DXCONSTANT_DESC *expecteds, UINT count)
436 {
437     UINT i;
438     ID3DXConstantTable *ctable;
439
440     HRESULT res;
441
442     /* Get the constant table from the shader itself */
443     res = D3DXGetShaderConstantTable(ctable_fn, &ctable);
444     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on %s: got %08x\n", test_name, res);
445
446     for (i = 0; i < count; i++)
447     {
448         const D3DXCONSTANT_DESC *expected = &expecteds[i];
449         D3DXHANDLE const_handle;
450         D3DXCONSTANT_DESC actual;
451         UINT pCount = 1;
452
453         const_handle = ID3DXConstantTable_GetConstantByName(ctable, NULL, expected->Name);
454
455         res = ID3DXConstantTable_GetConstantDesc(ctable, const_handle, &actual, &pCount);
456         ok(SUCCEEDED(res), "%s in %s: ID3DXConstantTable_GetConstantDesc returned %08x\n", expected->Name,
457                 test_name, res);
458         ok(pCount == 1, "%s in %s: Got more or less descriptions: %d\n", expected->Name, test_name, pCount);
459
460         ok(strcmp(actual.Name, expected->Name) == 0,
461            "%s in %s: Got different names: Got %s, expected %s\n", expected->Name,
462            test_name, actual.Name, expected->Name);
463         ok(actual.RegisterSet == expected->RegisterSet,
464            "%s in %s: Got different register sets: Got %d, expected %d\n",
465            expected->Name, test_name, actual.RegisterSet, expected->RegisterSet);
466         ok(actual.RegisterIndex == expected->RegisterIndex,
467            "%s in %s: Got different register indices: Got %d, expected %d\n",
468            expected->Name, test_name, actual.RegisterIndex, expected->RegisterIndex);
469         ok(actual.RegisterCount == expected->RegisterCount,
470            "%s in %s: Got different register counts: Got %d, expected %d\n",
471            expected->Name, test_name, actual.RegisterCount, expected->RegisterCount);
472         ok(actual.Class == expected->Class,
473            "%s in %s: Got different classes: Got %d, expected %d\n", expected->Name,
474            test_name, actual.Class, expected->Class);
475         ok(actual.Type == expected->Type,
476            "%s in %s: Got different types: Got %d, expected %d\n", expected->Name,
477            test_name, actual.Type, expected->Type);
478         ok(actual.Rows == expected->Rows && actual.Columns == expected->Columns,
479            "%s in %s: Got different dimensions: Got (%d, %d), expected (%d, %d)\n",
480            expected->Name, test_name, actual.Rows, actual.Columns, expected->Rows,
481            expected->Columns);
482         ok(actual.Elements == expected->Elements,
483            "%s in %s: Got different element count: Got %d, expected %d\n",
484            expected->Name, test_name, actual.Elements, expected->Elements);
485         ok(actual.StructMembers == expected->StructMembers,
486            "%s in %s: Got different struct member count: Got %d, expected %d\n",
487            expected->Name, test_name, actual.StructMembers, expected->StructMembers);
488         ok(actual.Bytes == expected->Bytes,
489            "%s in %s: Got different byte count: Got %d, expected %d\n",
490            expected->Name, test_name, actual.Bytes, expected->Bytes);
491
492         if (!expected->DefaultValue)
493         {
494             ok(actual.DefaultValue == NULL,
495                 "%s in %s: Got different default value: expected NULL\n",
496                 expected->Name, test_name);
497         }
498         else
499         {
500             ok(actual.DefaultValue != NULL,
501                 "%s in %s: Got different default value: expected non-NULL\n",
502                 expected->Name, test_name);
503             ok(memcmp(actual.DefaultValue, expected->DefaultValue, expected->Bytes) == 0,
504                 "%s in %s: Got different default value\n", expected->Name, test_name);
505         }
506     }
507
508     /* Finally, release the constant table */
509     ID3DXConstantTable_Release(ctable);
510 }
511
512 static void test_constant_tables(void)
513 {
514     test_constant_table("test_basic", ctab_basic, ctab_basic_expected,
515             sizeof(ctab_basic_expected)/sizeof(*ctab_basic_expected));
516     test_constant_table("test_matrices", ctab_matrices, ctab_matrices_expected,
517             sizeof(ctab_matrices_expected)/sizeof(*ctab_matrices_expected));
518     test_constant_table("test_arrays", ctab_arrays, ctab_arrays_expected,
519             sizeof(ctab_arrays_expected)/sizeof(*ctab_arrays_expected));
520     test_constant_table("test_default_values", ctab_with_default_values, ctab_with_default_values_expected,
521             sizeof(ctab_with_default_values_expected)/sizeof(*ctab_with_default_values_expected));
522     test_constant_table("test_samplers", ctab_samplers, ctab_samplers_expected,
523             sizeof(ctab_samplers_expected)/sizeof(*ctab_samplers_expected));
524 }
525
526 static void test_setting_basic_table(IDirect3DDevice9 *device)
527 {
528     static const D3DXMATRIX mvp = {{{
529         0.514f, 0.626f, 0.804f, 0.786f,
530         0.238f, 0.956f, 0.374f, 0.483f,
531         0.109f, 0.586f, 0.900f, 0.255f,
532         0.898f, 0.411f, 0.932f, 0.275f}}};
533     static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f};
534     static const float f = 0.12543f;
535     static const int i = 321;
536
537     ID3DXConstantTable *ctable;
538
539     HRESULT res;
540     float out[16];
541     ULONG refcnt;
542
543     /* Get the constant table from the shader itself */
544     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
545     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
546
547     /* Set constants */
548     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
549     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res);
550
551     res = ID3DXConstantTable_SetInt(ctable, device, "i", i + 1);
552     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
553
554     /* Check that setting i again will overwrite the previous value */
555     res = ID3DXConstantTable_SetInt(ctable, device, "i", i);
556     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
557
558     res = ID3DXConstantTable_SetFloat(ctable, device, "f", f);
559     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res);
560
561     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
562     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res);
563
564     /* Get constants back and validate */
565     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
566     ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14,
567             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
568             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
569     ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24,
570             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
571             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
572     ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34,
573             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
574             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
575     ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44,
576             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
577             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
578
579     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1);
580     ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
581             "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n",
582             out[0], out[1], out[2], out[3], i);
583
584     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
585     ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
586             "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n",
587             out[0], out[1], out[2], out[3], f);
588
589     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
590     ok(memcmp(out, (void*)&f4, sizeof(f4)) == 0,
591             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
592             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
593
594     /* Finally test using a set* function for one type to set a variable of another type (should succeed) */
595     res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4);
596     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
597
598     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
599     ok(out[0] == f4.x, "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n",
600             out[0], f4.x);
601
602     refcnt = ID3DXConstantTable_Release(ctable);
603     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
604 }
605
606 static void test_setting_arrays_table(IDirect3DDevice9 *device)
607 {
608     static const float farray[8] = {
609         0.005f, 0.745f, 0.973f, 0.264f,
610         0.010f, 0.020f, 0.030f, 0.040f};
611     static const D3DXMATRIX fmtxarray[2] = {
612         {{{0.001f, 0.002f, 0.003f, 0.004f,
613            0.005f, 0.006f, 0.007f, 0.008f,
614            0.009f, 0.010f, 0.011f, 0.012f,
615            0.013f, 0.014f, 0.015f, 0.016f}}},
616         {{{0.010f, 0.020f, 0.030f, 0.040f,
617            0.050f, 0.060f, 0.070f, 0.080f,
618            0.090f, 0.100f, 0.110f, 0.120f,
619            0.130f, 0.140f, 0.150f, 0.160f}}}};
620     static const int iarray[4] = {1, 2, 3, 4};
621     static const D3DXVECTOR4 fvecarray[2] = {
622         {0.745f, 0.997f, 0.353f, 0.237f},
623         {0.060f, 0.455f, 0.333f, 0.983f}};
624
625     ID3DXConstantTable *ctable;
626
627     HRESULT res;
628     float out[32];
629     ULONG refcnt;
630
631     /* Get the constant table from the shader */
632     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
633     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
634
635     /* Set constants */
636
637     /* Make sure that we cannot set registers that do not belong to this constant */
638     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8);
639     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res);
640
641     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8);
642     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
643             "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
644             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
645     ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f,
646             "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n",
647             out[16], out[20], out[24], out[28]);
648
649     /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */
650     res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]);
651     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res);
652
653     IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4);
654     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
655        "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]);
656
657     /* Try setting an integer array to an array declared as a float array */
658     res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4);
659     ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res);
660
661     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
662     ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3],
663            "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n",
664             out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]);
665
666     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4);
667     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res);
668
669     res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2);
670     ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res);
671
672     res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2);
673     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res);
674
675     /* Read back constants */
676     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
677     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
678             "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
679             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
680
681     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
682     ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w &&
683             out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w,
684             "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be "
685             "{{%f, %f, %f, %f}, {%f, %f, %f, %f}}\n", out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
686             fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y,
687             fvecarray[1].z, fvecarray[1].w);
688
689     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8);
690     /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */
691     ok(out[0] == S(U(fmtxarray[0]))._11 && out[1] == S(U(fmtxarray[0]))._12 && out[2] == S(U(fmtxarray[0]))._13 && out[3] == S(U(fmtxarray[0]))._14,
692            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
693            out[0], out[1], out[2], out[3], S(U(fmtxarray[0]))._11, S(U(fmtxarray[0]))._12, S(U(fmtxarray[0]))._13, S(U(fmtxarray[0]))._14);
694     ok(out[16] == S(U(fmtxarray[1]))._11 && out[17] == S(U(fmtxarray[1]))._12 && out[18] == S(U(fmtxarray[1]))._13 && out[19] == S(U(fmtxarray[1]))._14,
695            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
696            out[16], out[17], out[18], out[19], S(U(fmtxarray[1]))._11, S(U(fmtxarray[1]))._12, S(U(fmtxarray[1]))._13, S(U(fmtxarray[1]))._14);
697
698     refcnt = ID3DXConstantTable_Release(ctable);
699     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
700 }
701
702 static void test_SetDefaults(IDirect3DDevice9 *device)
703 {
704     static const D3DXMATRIX mvp = {{{
705         0.51f, 0.62f, 0.80f, 0.78f,
706         0.23f, 0.95f, 0.37f, 0.48f,
707         0.10f, 0.58f, 0.90f, 0.25f,
708         0.89f, 0.41f, 0.93f, 0.27f}}};
709     static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
710
711     float out[16];
712
713     HRESULT res;
714     ID3DXConstantTable *ctable;
715
716     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
717     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
718
719     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
720     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed: got %08x\n", res);
721
722     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
723     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got %08x\n", res);
724
725     res = ID3DXConstantTable_SetDefaults(ctable, device);
726     ok(res == D3D_OK, "ID3dXConstantTable_SetDefaults failed: got %08x\n", res);
727
728     /* SetDefaults doesn't change constants without default values */
729     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
730     ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14,
731             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
732             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
733     ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24,
734             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
735             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
736     ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34,
737             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
738             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
739     ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44,
740             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
741             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
742
743     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
744     ok(memcmp(out, &f4, sizeof(f4)) == 0,
745             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
746             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
747
748     ID3DXConstantTable_Release(ctable);
749
750     res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
751     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
752
753     res = ID3DXConstantTable_SetDefaults(ctable, device);
754     ok(res == D3D_OK, "ID3DXConstantTable_SetDefaults failed: got %08x\n", res);
755
756     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
757     ok(memcmp(out, mat4_default_value, sizeof(mat4_default_value)) == 0,
758             "The variable mat4 was not set correctly to default value\n");
759
760     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 4);
761     ok(memcmp(out, mat3_default_value, sizeof(mat3_default_value)) == 0,
762             "The variable mat3 was not set correctly to default value\n");
763
764     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
765     ok(memcmp(out, arr_default_value, sizeof(arr_default_value)) == 0,
766         "The variable array was not set correctly to default value\n");
767
768     IDirect3DDevice9_GetVertexShaderConstantF(device, 11, out, 1);
769     ok(memcmp(out, vec4_default_value, sizeof(vec4_default_value)) == 0,
770         "The variable vec4 was not set correctly to default value\n");
771
772     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 1);
773     ok(memcmp(out, flt_default_value, sizeof(flt_default_value)) == 0,
774         "The variable flt was not set correctly to default value\n");
775
776     ID3DXConstantTable_Release(ctable);
777 }
778
779 static void test_setting_constants(void)
780 {
781     HWND wnd;
782     IDirect3D9 *d3d;
783     IDirect3DDevice9 *device;
784     D3DPRESENT_PARAMETERS d3dpp;
785     HRESULT hr;
786     ULONG refcnt;
787
788     /* Create the device to use for our tests */
789     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
790     d3d = Direct3DCreate9(D3D_SDK_VERSION);
791     if (!wnd)
792     {
793         skip("Couldn't create application window\n");
794         return;
795     }
796     if (!d3d)
797     {
798         skip("Couldn't create IDirect3D9 object\n");
799         DestroyWindow(wnd);
800         return;
801     }
802
803     ZeroMemory(&d3dpp, sizeof(d3dpp));
804     d3dpp.Windowed   = TRUE;
805     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
806     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
807     if (FAILED(hr))
808     {
809         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
810         IDirect3D9_Release(d3d);
811         DestroyWindow(wnd);
812         return;
813     }
814
815     test_setting_basic_table(device);
816     test_setting_arrays_table(device);
817     test_SetDefaults(device);
818
819     /* Release resources */
820     refcnt = IDirect3DDevice9_Release(device);
821     ok(refcnt == 0, "The Direct3D device reference count was %u, should be 0\n", refcnt);
822
823     refcnt = IDirect3D9_Release(d3d);
824     ok(refcnt == 0, "The Direct3D object referenct count was %u, should be 0\n", refcnt);
825
826     if (wnd) DestroyWindow(wnd);
827 }
828
829 static void test_get_sampler_index(void)
830 {
831     ID3DXConstantTable *ctable;
832
833     HRESULT res;
834     UINT index;
835
836     ULONG refcnt;
837
838     res = D3DXGetShaderConstantTable(ctab_samplers, &ctable);
839     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res);
840
841     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1");
842     ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index);
843
844     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2");
845     ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index);
846
847     index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent");
848     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n",
849             index);
850
851     index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler");
852     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n",
853             index);
854
855     refcnt = ID3DXConstantTable_Release(ctable);
856     ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt);
857 }
858
859 /*
860  * fxc.exe /Tps_3_0
861  */
862 #if 0
863 sampler s;
864 sampler1D s1D;
865 sampler2D s2D;
866 sampler3D s3D;
867 samplerCUBE scube;
868 float4 init;
869 float4 main(float3 tex : TEXCOORD0) : COLOR
870 {
871     float4 tmp = init;
872     tmp = tmp + tex1D(s1D, tex.x);
873     tmp = tmp + tex1D(s1D, tex.y);
874     tmp = tmp + tex3D(s3D, tex.xyz);
875     tmp = tmp + tex1D(s, tex.x);
876     tmp = tmp + tex2D(s2D, tex.xy);
877     tmp = tmp + texCUBE(scube, tex.xyz);
878     return tmp;
879 }
880 #endif
881 static const DWORD get_shader_samplers_blob[] =
882 {
883     0xffff0300,                                                             /* ps_3_0                        */
884     0x0054fffe, FCC_CTAB,                                                   /* CTAB comment                  */
885     0x0000001c, 0x0000011b, 0xffff0300, 0x00000006, 0x0000001c, 0x00000100, /* Header                        */
886     0x00000114,
887     0x00000094, 0x00000002, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 1 desc (init)        */
888     0x000000ac, 0x00040003, 0x00000001, 0x000000b0, 0x00000000,             /* Constant 2 desc (s)           */
889     0x000000c0, 0x00000003, 0x00000001, 0x000000c4, 0x00000000,             /* Constant 3 desc (s1D)         */
890     0x000000d4, 0x00010003, 0x00000001, 0x000000d8, 0x00000000,             /* Constant 4 desc (s2D)         */
891     0x000000e8, 0x00030003, 0x00000001, 0x000000ec, 0x00000000,             /* Constant 5 desc (s3D)         */
892     0x000000fc, 0x00020003, 0x00000001, 0x00000104, 0x00000000,             /* Constant 6 desc (scube)       */
893     0x74696e69, 0xababab00,                                                 /* Constant 1 name               */
894     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
895     0xabab0073,                                                             /* Constant 2 name               */
896     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
897     0x00443173,                                                             /* Constant 3 name               */
898     0x000b0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
899     0x00443273,                                                             /* Constant 4 name               */
900     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 4 type desc          */
901     0x00443373,                                                             /* Constant 5 name               */
902     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 5 type desc          */
903     0x62756373, 0xabab0065,                                                 /* Constant 6 name               */
904     0x000e0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 6 type desc          */
905     0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, /* Target/Creator name string    */
906     0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
907     0x332e3235, 0x00313131,
908     0x0200001f, 0x80000005, 0x90070000, 0x0200001f, 0x90000000, 0xa00f0800, /* shader                        */
909     0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x98000000, 0xa00f0802,
910     0x0200001f, 0xa0000000, 0xa00f0803, 0x0200001f, 0x90000000, 0xa00f0804,
911     0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
912     0x80e40000, 0xa0e40000, 0x03000042, 0x800f0001, 0x90550000, 0xa0e40800,
913     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
914     0x90e40000, 0xa0e40803, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001,
915     0x03000042, 0x800f0001, 0x90e40000, 0xa0e40804, 0x03000002, 0x800f0000,
916     0x80e40000, 0x80e40001, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801,
917     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
918     0x90e40000, 0xa0e40802, 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001,
919     0x0000ffff,                                                             /* END                           */
920 };
921
922 static void test_get_shader_samplers(void)
923 {
924     LPCSTR samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */
925     LPCSTR sampler_orig;
926     UINT count = 2;
927     HRESULT hr;
928
929 #if 0
930     /* crashes if bytecode is NULL */
931     hr = D3DXGetShaderSamplers(NULL, NULL, &count);
932     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
933 #endif
934
935     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, NULL);
936     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
937
938     samplers[5] = "dummy";
939
940     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL);
941     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
942
943     /* check that sampler points to shader blob */
944     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
945     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
946
947     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
948     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
949
950     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
951     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
952
953     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
954     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
955
956     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
957     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
958
959     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
960
961     /* reset samplers */
962     memset(samplers, 0, sizeof(samplers));
963     samplers[5] = "dummy";
964
965     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, &count);
966     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
967     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
968
969     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, &count);
970     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
971     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
972
973     /* check that sampler points to shader blob */
974     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
975     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
976
977     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
978     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
979
980     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
981     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
982
983     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
984     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
985
986     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
987     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
988
989     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
990
991     /* check without ctab */
992     hr = D3DXGetShaderSamplers(simple_vs, samplers, &count);
993     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
994     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
995
996     /* check invalid ctab */
997     hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count);
998     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
999     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
1000 }
1001
1002 START_TEST(shader)
1003 {
1004     test_get_shader_size();
1005     test_get_shader_version();
1006     test_find_shader_comment();
1007     test_get_shader_constant_table_ex();
1008     test_constant_tables();
1009     test_setting_constants();
1010     test_get_sampler_index();
1011     test_get_shader_samplers();
1012 }