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