d3dx9: Correctly handle constants without default values in D3DXGetShaderConstantTableEx.
[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_samplers[] = {
161     0xfffe0300,                                                             /* vs_3_0                        */
162     0x0032fffe, FCC_CTAB,                                                   /* CTAB comment                  */
163     0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header                        */
164     0x000000ac,
165     0x00000058, 0x00020002, 0x00000001, 0x00000064, 0x00000000,             /* Constant 1 desc (notsampler)  */
166     0x00000074, 0x00000003, 0x00000001, 0x00000080, 0x00000000,             /* Constant 2 desc (sampler1)    */
167     0x00000090, 0x00030003, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 3 desc (sampler2)    */
168     0x73746f6e, 0x6c706d61, 0xab007265,                                     /* Constant 1 name               */
169     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
170     0x706d6173, 0x3172656c, 0xababab00,                                     /* Constant 2 name               */
171     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
172     0x706d6173, 0x3272656c, 0xababab00,                                     /* Constant 3 name               */
173     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
174     0x335f7376, 0xab00305f,                                                 /* Target name string            */
175     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string           */
176     0x0000ffff};                                                            /* END                           */
177
178 static const D3DXCONSTANT_DESC ctab_samplers_expected[] = {
179     {"sampler1",   D3DXRS_SAMPLER, 0, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER2D, 1, 1, 1, 0, 4,  NULL},
180     {"sampler2",   D3DXRS_SAMPLER, 3, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER3D, 1, 1, 1, 0, 4,  NULL},
181     {"notsampler", D3DXRS_FLOAT4,  2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT,     1, 4, 1, 0, 16, NULL}};
182
183 static void test_get_shader_size(void)
184 {
185     UINT shader_size, expected;
186
187     shader_size = D3DXGetShaderSize(simple_vs);
188     expected = sizeof(simple_vs);
189     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
190
191     shader_size = D3DXGetShaderSize(simple_ps);
192     expected = sizeof(simple_ps);
193     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
194
195     shader_size = D3DXGetShaderSize(NULL);
196     ok(shader_size == 0, "Got shader size %u, expected 0\n", shader_size);
197 }
198
199 static void test_get_shader_version(void)
200 {
201     DWORD shader_version;
202
203     shader_version = D3DXGetShaderVersion(simple_vs);
204     ok(shader_version == D3DVS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
205             shader_version, D3DVS_VERSION(1, 1));
206
207     shader_version = D3DXGetShaderVersion(simple_ps);
208     ok(shader_version == D3DPS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
209             shader_version, D3DPS_VERSION(1, 1));
210
211     shader_version = D3DXGetShaderVersion(NULL);
212     ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version);
213 }
214
215 static void test_find_shader_comment(void)
216 {
217     HRESULT hr;
218     LPCVOID data = (LPVOID)0xdeadbeef;
219     UINT size = 100;
220
221     hr = D3DXFindShaderComment(NULL, MAKEFOURCC('C','T','A','B'), &data, &size);
222     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
223     ok(!data, "Got %p, expected NULL\n", data);
224     ok(!size, "Got %u, expected 0\n", size);
225
226     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), NULL, &size);
227     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
228     ok(size == 28, "Got %u, expected 28\n", size);
229
230     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, NULL);
231     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
232     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
233
234     hr = D3DXFindShaderComment(shader_with_ctab, 0, &data, &size);
235     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
236     ok(!data, "Got %p, expected NULL\n", data);
237     ok(!size, "Got %u, expected 0\n", size);
238
239     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('X','X','X','X'), &data, &size);
240     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
241     ok(!data, "Got %p, expected NULL\n", data);
242     ok(!size, "Got %u, expected 0\n", size);
243
244     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, &size);
245     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
246     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
247     ok(size == 28, "Got result %d, expected 28\n", size);
248 }
249
250 static void test_get_shader_constant_table_ex(void)
251 {
252     LPD3DXCONSTANTTABLE constant_table = NULL;
253     HRESULT hr;
254     LPVOID data;
255     DWORD size;
256     D3DXCONSTANTTABLE_DESC desc;
257
258     hr = D3DXGetShaderConstantTableEx(NULL, 0, &constant_table);
259     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
260
261     /* No CTAB data */
262     hr = D3DXGetShaderConstantTableEx(simple_ps, 0, &constant_table);
263     ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
264
265     /* With invalid CTAB data */
266     hr = D3DXGetShaderConstantTableEx(shader_with_invalid_ctab, 0, &constant_table);
267     ok(hr == D3DXERR_INVALIDDATA || broken(hr == D3D_OK), /* winxp 64-bit, w2k3 64-bit */
268        "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
269     if (constant_table) ID3DXConstantTable_Release(constant_table);
270
271     hr = D3DXGetShaderConstantTableEx(shader_with_ctab, 0, &constant_table);
272     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
273
274     if (constant_table)
275     {
276         size = ID3DXConstantTable_GetBufferSize(constant_table);
277         ok(size == 28, "Got result %x, expected 28\n", size);
278
279         data = ID3DXConstantTable_GetBufferPointer(constant_table);
280         ok(!memcmp(data, shader_with_ctab + 6, size), "Retrieved wrong CTAB data\n");
281
282         hr = ID3DXConstantTable_GetDesc(constant_table, NULL);
283         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
284
285         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
286         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
287         ok(desc.Creator == (LPCSTR)data + 0x10, "Got result %p, expected %p\n", desc.Creator, (LPCSTR)data + 0x10);
288         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
289         ok(desc.Constants == 0, "Got result %x, expected 0\n", desc.Constants);
290
291         ID3DXConstantTable_Release(constant_table);
292     }
293
294     hr = D3DXGetShaderConstantTableEx(shader_with_ctab_constants, 0, &constant_table);
295     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
296
297     if (SUCCEEDED(hr))
298     {
299         D3DXHANDLE constant;
300         D3DXCONSTANT_DESC constant_desc;
301         D3DXCONSTANT_DESC constant_desc_save;
302         UINT nb;
303
304         /* Test GetDesc */
305         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
306         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
307         ok(!strcmp(desc.Creator, "Wine project"), "Got result '%s', expected 'Wine project'\n", desc.Creator);
308         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
309         ok(desc.Constants == 3, "Got result %x, expected 3\n", desc.Constants);
310
311         /* Test GetConstant */
312         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
313         ok(constant != NULL, "No constant found\n");
314         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
315         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
316         ok(!strcmp(constant_desc.Name, "Constant1"), "Got result '%s', expected 'Constant1'\n",
317             constant_desc.Name);
318         ok(constant_desc.Class == D3DXPC_VECTOR, "Got result %x, expected %u (D3DXPC_VECTOR)\n",
319             constant_desc.Class, D3DXPC_VECTOR);
320         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
321             constant_desc.Type, D3DXPT_FLOAT);
322         ok(constant_desc.Rows == 1, "Got result %x, expected 1\n", constant_desc.Rows);
323         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
324
325         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 1);
326         ok(constant != NULL, "No constant found\n");
327         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
328         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
329         ok(!strcmp(constant_desc.Name, "Constant2"), "Got result '%s', expected 'Constant2'\n",
330             constant_desc.Name);
331         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
332             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
333         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
334             constant_desc.Type, D3DXPT_FLOAT);
335         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
336         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
337
338         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 2);
339         ok(constant != NULL, "No constant found\n");
340         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
341         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
342         ok(!strcmp(constant_desc.Name, "Constant3"), "Got result '%s', expected 'Constant3'\n",
343             constant_desc.Name);
344         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
345             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
346         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
347             constant_desc.Type, D3DXPT_FLOAT);
348         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
349         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
350         constant_desc_save = constant_desc; /* For GetConstantDesc test */
351
352         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 3);
353         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
354
355         /* Test GetConstantByName */
356         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant unknown");
357         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
358         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant3");
359         ok(constant != NULL, "No constant found\n");
360         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
361         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
362         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
363
364         /* Test GetConstantDesc */
365         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
366         ok(constant != NULL, "No constant found\n");
367         hr = ID3DXConstantTable_GetConstantDesc(constant_table, NULL, &constant_desc, &nb);
368         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
369         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, NULL, &nb);
370         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
371         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, NULL);
372         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
373         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant unknow", &constant_desc, &nb);
374         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
375         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant3", &constant_desc, &nb);
376         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
377         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
378
379         ID3DXConstantTable_Release(constant_table);
380     }
381 }
382
383 static void test_constant_table(const char *test_name, const DWORD *ctable_fn,
384         const D3DXCONSTANT_DESC *expecteds, UINT count)
385 {
386     UINT i;
387     ID3DXConstantTable *ctable;
388
389     HRESULT res;
390
391     /* Get the constant table from the shader itself */
392     res = D3DXGetShaderConstantTable(ctable_fn, &ctable);
393     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on %s: got %08x\n", test_name, res);
394
395     for (i = 0; i < count; i++)
396     {
397         const D3DXCONSTANT_DESC *expected = &expecteds[i];
398         D3DXHANDLE const_handle;
399         D3DXCONSTANT_DESC actual;
400         UINT pCount = 1;
401
402         const_handle = ID3DXConstantTable_GetConstantByName(ctable, NULL, expected->Name);
403
404         res = ID3DXConstantTable_GetConstantDesc(ctable, const_handle, &actual, &pCount);
405         ok(SUCCEEDED(res), "%s in %s: ID3DXConstantTable_GetConstantDesc returned %08x\n", expected->Name,
406                 test_name, res);
407         ok(pCount == 1, "%s in %s: Got more or less descriptions: %d\n", expected->Name, test_name, pCount);
408
409         ok(strcmp(actual.Name, expected->Name) == 0,
410            "%s in %s: Got different names: Got %s, expected %s\n", expected->Name,
411            test_name, actual.Name, expected->Name);
412         ok(actual.RegisterSet == expected->RegisterSet,
413            "%s in %s: Got different register sets: Got %d, expected %d\n",
414            expected->Name, test_name, actual.RegisterSet, expected->RegisterSet);
415         ok(actual.RegisterIndex == expected->RegisterIndex,
416            "%s in %s: Got different register indices: Got %d, expected %d\n",
417            expected->Name, test_name, actual.RegisterIndex, expected->RegisterIndex);
418         ok(actual.RegisterCount == expected->RegisterCount,
419            "%s in %s: Got different register counts: Got %d, expected %d\n",
420            expected->Name, test_name, actual.RegisterCount, expected->RegisterCount);
421         ok(actual.Class == expected->Class,
422            "%s in %s: Got different classes: Got %d, expected %d\n", expected->Name,
423            test_name, actual.Class, expected->Class);
424         ok(actual.Type == expected->Type,
425            "%s in %s: Got different types: Got %d, expected %d\n", expected->Name,
426            test_name, actual.Type, expected->Type);
427         ok(actual.Rows == expected->Rows && actual.Columns == expected->Columns,
428            "%s in %s: Got different dimensions: Got (%d, %d), expected (%d, %d)\n",
429            expected->Name, test_name, actual.Rows, actual.Columns, expected->Rows,
430            expected->Columns);
431         ok(actual.Elements == expected->Elements,
432            "%s in %s: Got different element count: Got %d, expected %d\n",
433            expected->Name, test_name, actual.Elements, expected->Elements);
434         ok(actual.StructMembers == expected->StructMembers,
435            "%s in %s: Got different struct member count: Got %d, expected %d\n",
436            expected->Name, test_name, actual.StructMembers, expected->StructMembers);
437         ok(actual.Bytes == expected->Bytes,
438            "%s in %s: Got different byte count: Got %d, expected %d\n",
439            expected->Name, test_name, actual.Bytes, expected->Bytes);
440         ok(actual.DefaultValue == expected->DefaultValue,
441             "%s in %s: Got different default value: Got %p, expected %p\n",
442             expected->Name, test_name, actual.DefaultValue, expected->DefaultValue);
443     }
444
445     /* Finally, release the constant table */
446     ID3DXConstantTable_Release(ctable);
447 }
448
449 static void test_constant_tables(void)
450 {
451     test_constant_table("test_basic", ctab_basic, ctab_basic_expected,
452             sizeof(ctab_basic_expected)/sizeof(*ctab_basic_expected));
453     test_constant_table("test_matrices", ctab_matrices, ctab_matrices_expected,
454             sizeof(ctab_matrices_expected)/sizeof(*ctab_matrices_expected));
455     test_constant_table("test_arrays", ctab_arrays, ctab_arrays_expected,
456             sizeof(ctab_arrays_expected)/sizeof(*ctab_arrays_expected));
457     test_constant_table("test_samplers", ctab_samplers, ctab_samplers_expected,
458             sizeof(ctab_samplers_expected)/sizeof(*ctab_samplers_expected));
459 }
460
461 static void test_setting_basic_table(IDirect3DDevice9 *device)
462 {
463     static const D3DXMATRIX mvp = {{{
464         0.514f, 0.626f, 0.804f, 0.786f,
465         0.238f, 0.956f, 0.374f, 0.483f,
466         0.109f, 0.586f, 0.900f, 0.255f,
467         0.898f, 0.411f, 0.932f, 0.275f}}};
468     static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f};
469     static const float f = 0.12543f;
470     static const int i = 321;
471
472     ID3DXConstantTable *ctable;
473
474     HRESULT res;
475     float out[16];
476     ULONG refcnt;
477
478     /* Get the constant table from the shader itself */
479     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
480     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
481
482     /* Set constants */
483     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
484     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res);
485
486     res = ID3DXConstantTable_SetInt(ctable, device, "i", i + 1);
487     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
488
489     /* Check that setting i again will overwrite the previous value */
490     res = ID3DXConstantTable_SetInt(ctable, device, "i", i);
491     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
492
493     res = ID3DXConstantTable_SetFloat(ctable, device, "f", f);
494     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res);
495
496     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
497     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res);
498
499     /* Get constants back and validate */
500     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
501     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,
502             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
503             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
504     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,
505             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
506             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
507     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,
508             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
509             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
510     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,
511             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
512             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
513
514     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1);
515     ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
516             "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n",
517             out[0], out[1], out[2], out[3], i);
518
519     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
520     ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
521             "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n",
522             out[0], out[1], out[2], out[3], f);
523
524     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
525     ok(memcmp(out, (void*)&f4, sizeof(f4)) == 0,
526             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
527             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
528
529     /* Finally test using a set* function for one type to set a variable of another type (should succeed) */
530     res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4);
531     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
532
533     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
534     ok(out[0] == f4.x, "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n",
535             out[0], f4.x);
536
537     refcnt = ID3DXConstantTable_Release(ctable);
538     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
539 }
540
541 static void test_setting_arrays_table(IDirect3DDevice9 *device)
542 {
543     static const float farray[8] = {
544         0.005f, 0.745f, 0.973f, 0.264f,
545         0.010f, 0.020f, 0.030f, 0.040f};
546     static const D3DXMATRIX fmtxarray[2] = {
547         {{{0.001f, 0.002f, 0.003f, 0.004f,
548            0.005f, 0.006f, 0.007f, 0.008f,
549            0.009f, 0.010f, 0.011f, 0.012f,
550            0.013f, 0.014f, 0.015f, 0.016f}}},
551         {{{0.010f, 0.020f, 0.030f, 0.040f,
552            0.050f, 0.060f, 0.070f, 0.080f,
553            0.090f, 0.100f, 0.110f, 0.120f,
554            0.130f, 0.140f, 0.150f, 0.160f}}}};
555     static const int iarray[4] = {1, 2, 3, 4};
556     static const D3DXVECTOR4 fvecarray[2] = {
557         {0.745f, 0.997f, 0.353f, 0.237f},
558         {0.060f, 0.455f, 0.333f, 0.983f}};
559
560     ID3DXConstantTable *ctable;
561
562     HRESULT res;
563     float out[32];
564     ULONG refcnt;
565
566     /* Get the constant table from the shader */
567     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
568     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
569
570     /* Set constants */
571
572     /* Make sure that we cannot set registers that do not belong to this constant */
573     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8);
574     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res);
575
576     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8);
577     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
578             "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
579             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
580     ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f,
581             "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n",
582             out[16], out[20], out[24], out[28]);
583
584     /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */
585     res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]);
586     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res);
587
588     IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4);
589     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
590        "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]);
591
592     /* Try setting an integer array to an array declared as a float array */
593     res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4);
594     ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res);
595
596     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
597     ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3],
598            "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n",
599             out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]);
600
601     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4);
602     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res);
603
604     res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2);
605     ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res);
606
607     res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2);
608     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res);
609
610     /* Read back constants */
611     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
612     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
613             "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
614             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
615
616     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
617     ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w &&
618             out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w,
619             "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be "
620             "{{%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],
621             fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y,
622             fvecarray[1].z, fvecarray[1].w);
623
624     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8);
625     /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */
626     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,
627            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
628            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);
629     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,
630            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
631            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);
632
633     refcnt = ID3DXConstantTable_Release(ctable);
634     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
635 }
636
637 static void test_setting_constants(void)
638 {
639     HWND wnd;
640     IDirect3D9 *d3d;
641     IDirect3DDevice9 *device;
642     D3DPRESENT_PARAMETERS d3dpp;
643     HRESULT hr;
644     ULONG refcnt;
645
646     /* Create the device to use for our tests */
647     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
648     d3d = Direct3DCreate9(D3D_SDK_VERSION);
649     if (!wnd)
650     {
651         skip("Couldn't create application window\n");
652         return;
653     }
654     if (!d3d)
655     {
656         skip("Couldn't create IDirect3D9 object\n");
657         DestroyWindow(wnd);
658         return;
659     }
660
661     ZeroMemory(&d3dpp, sizeof(d3dpp));
662     d3dpp.Windowed   = TRUE;
663     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
664     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
665     if (FAILED(hr))
666     {
667         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
668         IDirect3D9_Release(d3d);
669         DestroyWindow(wnd);
670         return;
671     }
672
673     test_setting_basic_table(device);
674     test_setting_arrays_table(device);
675
676     /* Release resources */
677     refcnt = IDirect3DDevice9_Release(device);
678     ok(refcnt == 0, "The Direct3D device reference count was %u, should be 0\n", refcnt);
679
680     refcnt = IDirect3D9_Release(d3d);
681     ok(refcnt == 0, "The Direct3D object referenct count was %u, should be 0\n", refcnt);
682
683     if (wnd) DestroyWindow(wnd);
684 }
685
686 static void test_get_sampler_index(void)
687 {
688     ID3DXConstantTable *ctable;
689
690     HRESULT res;
691     UINT index;
692
693     ULONG refcnt;
694
695     res = D3DXGetShaderConstantTable(ctab_samplers, &ctable);
696     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res);
697
698     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1");
699     ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index);
700
701     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2");
702     ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index);
703
704     index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent");
705     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n",
706             index);
707
708     index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler");
709     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n",
710             index);
711
712     refcnt = ID3DXConstantTable_Release(ctable);
713     ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt);
714 }
715
716 /*
717  * fxc.exe /Tps_3_0
718  */
719 #if 0
720 sampler s;
721 sampler1D s1D;
722 sampler2D s2D;
723 sampler3D s3D;
724 samplerCUBE scube;
725 float4 init;
726 float4 main(float3 tex : TEXCOORD0) : COLOR
727 {
728     float4 tmp = init;
729     tmp = tmp + tex1D(s1D, tex.x);
730     tmp = tmp + tex1D(s1D, tex.y);
731     tmp = tmp + tex3D(s3D, tex.xyz);
732     tmp = tmp + tex1D(s, tex.x);
733     tmp = tmp + tex2D(s2D, tex.xy);
734     tmp = tmp + texCUBE(scube, tex.xyz);
735     return tmp;
736 }
737 #endif
738 static const DWORD get_shader_samplers_blob[] =
739 {
740     0xffff0300,                                                             /* ps_3_0                        */
741     0x0054fffe, FCC_CTAB,                                                   /* CTAB comment                  */
742     0x0000001c, 0x0000011b, 0xffff0300, 0x00000006, 0x0000001c, 0x00000100, /* Header                        */
743     0x00000114,
744     0x00000094, 0x00000002, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 1 desc (init)        */
745     0x000000ac, 0x00040003, 0x00000001, 0x000000b0, 0x00000000,             /* Constant 2 desc (s)           */
746     0x000000c0, 0x00000003, 0x00000001, 0x000000c4, 0x00000000,             /* Constant 3 desc (s1D)         */
747     0x000000d4, 0x00010003, 0x00000001, 0x000000d8, 0x00000000,             /* Constant 4 desc (s2D)         */
748     0x000000e8, 0x00030003, 0x00000001, 0x000000ec, 0x00000000,             /* Constant 5 desc (s3D)         */
749     0x000000fc, 0x00020003, 0x00000001, 0x00000104, 0x00000000,             /* Constant 6 desc (scube)       */
750     0x74696e69, 0xababab00,                                                 /* Constant 1 name               */
751     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
752     0xabab0073,                                                             /* Constant 2 name               */
753     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
754     0x00443173,                                                             /* Constant 3 name               */
755     0x000b0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
756     0x00443273,                                                             /* Constant 4 name               */
757     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 4 type desc          */
758     0x00443373,                                                             /* Constant 5 name               */
759     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 5 type desc          */
760     0x62756373, 0xabab0065,                                                 /* Constant 6 name               */
761     0x000e0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 6 type desc          */
762     0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, /* Target/Creator name string    */
763     0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
764     0x332e3235, 0x00313131,
765     0x0200001f, 0x80000005, 0x90070000, 0x0200001f, 0x90000000, 0xa00f0800, /* shader                        */
766     0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x98000000, 0xa00f0802,
767     0x0200001f, 0xa0000000, 0xa00f0803, 0x0200001f, 0x90000000, 0xa00f0804,
768     0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
769     0x80e40000, 0xa0e40000, 0x03000042, 0x800f0001, 0x90550000, 0xa0e40800,
770     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
771     0x90e40000, 0xa0e40803, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001,
772     0x03000042, 0x800f0001, 0x90e40000, 0xa0e40804, 0x03000002, 0x800f0000,
773     0x80e40000, 0x80e40001, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801,
774     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
775     0x90e40000, 0xa0e40802, 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001,
776     0x0000ffff,                                                             /* END                           */
777 };
778
779 static void test_get_shader_samplers(void)
780 {
781     LPCSTR samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */
782     LPCSTR sampler_orig;
783     UINT count = 2;
784     HRESULT hr;
785
786 #if 0
787     /* crashes if bytecode is NULL */
788     hr = D3DXGetShaderSamplers(NULL, NULL, &count);
789     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
790 #endif
791
792     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, NULL);
793     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
794
795     samplers[5] = "dummy";
796
797     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL);
798     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
799
800     /* check that sampler points to shader blob */
801     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
802     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
803
804     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
805     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
806
807     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
808     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
809
810     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
811     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
812
813     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
814     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
815
816     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
817
818     /* reset samplers */
819     memset(samplers, 0, sizeof(samplers));
820     samplers[5] = "dummy";
821
822     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, &count);
823     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
824     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
825
826     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, &count);
827     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
828     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
829
830     /* check that sampler points to shader blob */
831     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
832     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
833
834     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
835     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
836
837     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
838     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
839
840     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
841     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
842
843     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
844     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
845
846     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
847
848     /* check without ctab */
849     hr = D3DXGetShaderSamplers(simple_vs, samplers, &count);
850     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
851     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
852
853     /* check invalid ctab */
854     hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count);
855     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
856     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
857 }
858
859 START_TEST(shader)
860 {
861     test_get_shader_size();
862     test_get_shader_version();
863     test_find_shader_comment();
864     test_get_shader_constant_table_ex();
865     test_constant_tables();
866     test_setting_constants();
867     test_get_sampler_index();
868     test_get_shader_samplers();
869 }