d3dx9: Implement ID3DXConstantTable::SetMatrixTranspose.
[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_matrices2[] = {
126     0xfffe0200,                                                             /* vs_2_0                        */
127     0x0058fffe, FCC_CTAB,                                                   /* CTAB comment                  */
128     0x0000001c, 0x0000012b, 0xfffe0200, 0x00000006, 0x0000001c, 0x00000100, /* Header                        */
129     0x00000124,
130     0x00000094, 0x00070002, 0x00000003, 0x0000009c, 0x00000000,             /* Constant 1 desc (c2x3)        */
131     0x000000ac, 0x000d0002, 0x00000002, 0x000000b4, 0x00000000,             /* Constant 2 desc (c3x2)        */
132     0x000000c4, 0x000a0002, 0x00000003, 0x000000cc, 0x00000000,             /* Constant 3 desc (c3x3)        */
133     0x000000dc, 0x000f0002, 0x00000002, 0x000000e4, 0x00000000,             /* Constant 4 desc (r2x3)        */
134     0x000000f4, 0x00040002, 0x00000003, 0x000000fc, 0x00000000,             /* Constant 5 desc (r3x2)        */
135     0x0000010c, 0x00000002, 0x00000004, 0x00000114, 0x00000000,             /* Constant 6 desc (r4x4)        */
136     0x33783263, 0xababab00,                                                 /* Constant 1 name               */
137     0x00030003, 0x00030002, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
138     0x32783363, 0xababab00,                                                 /* Constant 2 name               */
139     0x00030003, 0x00020003, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
140     0x33783363, 0xababab00,                                                 /* Constant 3 name               */
141     0x00030003, 0x00030003, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
142     0x33783272, 0xababab00,                                                 /* Constant 4 name               */
143     0x00030002, 0x00030002, 0x00000001, 0x00000000,                         /* Constant 4 type desc          */
144     0x32783372, 0xababab00,                                                 /* Constant 5 name               */
145     0x00030002, 0x00020003, 0x00000001, 0x00000000,                         /* Constant 5 type desc          */
146     0x34783472, 0xababab00,                                                 /* Constant 6 name               */
147     0x00030002, 0x00040004, 0x00000001, 0x00000000,                         /* Constant 6 type desc          */
148     0x325f7376, 0x4100305f, 0x41414141, 0x00414141,                         /* Target and Creator name       */
149     0x0000ffff};                                                            /* END                           */
150
151 static const D3DXCONSTANT_DESC ctab_matrices2_expected[] = {
152     {"c2x3", D3DXRS_FLOAT4,  7, 3, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL},
153     {"c3x2", D3DXRS_FLOAT4, 13, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL},
154     {"c3x3", D3DXRS_FLOAT4, 10, 3, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 3, 1, 0, 36, NULL},
155     {"r2x3", D3DXRS_FLOAT4, 15, 2, D3DXPC_MATRIX_ROWS,    D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL},
156     {"r3x2", D3DXRS_FLOAT4,  4, 3, D3DXPC_MATRIX_ROWS,    D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL},
157     {"r4x4", D3DXRS_FLOAT4,  0, 4, D3DXPC_MATRIX_ROWS,    D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL}};
158
159 static const DWORD ctab_arrays[] = {
160     0xfffe0300,                                                             /* vs_3_0                       */
161     0x0052fffe, FCC_CTAB,                                                   /* CTAB comment                 */
162     0x0000001c, 0x0000013c, 0xfffe0300, 0x00000006, 0x0000001c, 0x20008100, /* Header                       */
163     0x00000134,
164     0x00000094, 0x000E0002, 0x00000002, 0x0000009c, 0x00000000,             /* Constant 1 desc (barray)     */
165     0x000000ac, 0x00100002, 0x00000002, 0x000000b8, 0x00000000,             /* Constant 2 desc (bvecarray)  */
166     0x000000c8, 0x00080002, 0x00000004, 0x000000d0, 0x00000000,             /* Constant 3 desc (farray)     */
167     0x000000e0, 0x00000002, 0x00000008, 0x000000ec, 0x00000000,             /* Constant 4 desc (fmtxarray)  */
168     0x000000fc, 0x000C0002, 0x00000002, 0x00000108, 0x00000000,             /* Constant 5 desc (fvecarray)  */
169     0x00000118, 0x00120002, 0x00000001, 0x00000124, 0x00000000,             /* Constant 6 desc (ivecarray)  */
170     0x72726162, 0xab007961,                                                 /* Constant 1 name              */
171     0x00010000, 0x00010001, 0x00000002, 0x00000000,                         /* Constant 1 type desc         */
172     0x63657662, 0x61727261, 0xabab0079,                                     /* Constant 2 name              */
173     0x00010001, 0x00030001, 0x00000003, 0x00000000,                         /* Constant 2 type desc         */
174     0x72726166, 0xab007961,                                                 /* Constant 3 name              */
175     0x00030000, 0x00010001, 0x00000004, 0x00000000,                         /* constant 3 type desc         */
176     0x78746d66, 0x61727261, 0xabab0079,                                     /* Constant 4 name              */
177     0x00030002, 0x00040004, 0x00000002, 0x00000000,                         /* Constant 4 type desc         */
178     0x63657666, 0x61727261, 0xabab0079,                                     /* Constant 5 name              */
179     0x00030001, 0x00040001, 0x00000002, 0x00000000,                         /* Constant 5 type desc         */
180     0x63657669, 0x61727261, 0xabab0079,                                     /* Constant 6 name              */
181     0x00020001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 6 type desc         */
182     0x335f7376, 0xab00305f,                                                 /* Target name string           */
183     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string          */
184     0x0000ffff};                                                            /* END                          */
185
186 static const D3DXCONSTANT_DESC ctab_arrays_expected[] = {
187     {"fmtxarray", D3DXRS_FLOAT4,  0, 8, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 2, 0, 128, NULL},
188     {"farray",    D3DXRS_FLOAT4,  8, 4, D3DXPC_SCALAR,      D3DXPT_FLOAT, 1, 1, 4, 0,  16, NULL},
189     {"fvecarray", D3DXRS_FLOAT4, 12, 2, D3DXPC_VECTOR,      D3DXPT_FLOAT, 1, 4, 2, 0,  32, NULL},
190     {"barray",    D3DXRS_FLOAT4, 14, 2, D3DXPC_SCALAR,      D3DXPT_BOOL,  1, 1, 2, 0,   8, NULL},
191     {"bvecarray", D3DXRS_FLOAT4, 16, 2, D3DXPC_VECTOR,      D3DXPT_BOOL,  1, 3, 3, 0,  36, NULL},
192     {"ivecarray", D3DXRS_FLOAT4, 18, 1, D3DXPC_VECTOR,      D3DXPT_INT,   1, 4, 1, 0,  16, NULL}};
193
194 static const DWORD ctab_with_default_values[] = {
195     0xfffe0200,                                                 /* vs_2_0 */
196     0x007bfffe, FCC_CTAB,                                       /* CTAB comment */
197     0x0000001c, 0x000001b7, 0xfffe0200, 0x00000005, 0x0000001c, /* header */
198     0x00000100, 0x000001b0,
199     0x00000080, 0x00080002, 0x00000003, 0x00000084, 0x00000094, /* constant 1 desc (arr) */
200     0x000000c4, 0x000c0002, 0x00000001, 0x000000c8, 0x000000d8, /* constant 2 desc (flt) */
201     0x000000e8, 0x00040002, 0x00000004, 0x000000f0, 0x00000100, /* constant 3 desc (mat3) */
202     0x00000140, 0x00000002, 0x00000004, 0x000000f0, 0x00000148, /* constant 4 desc (mat4) */
203     0x00000188, 0x000b0002, 0x00000001, 0x00000190, 0x000001a0, /* constant 5 desc (vec4) */
204     0x00727261,                                                 /* constant 1 name */
205     0x00030000, 0x00010001, 0x00000003, 0x00000000,             /* constant 1 type desc */
206     0x42c80000, 0x00000000, 0x00000000, 0x00000000,             /* constant 1 default value */
207     0x43480000, 0x00000000, 0x00000000, 0x00000000,
208     0x43960000, 0x00000000, 0x00000000, 0x00000000,
209     0x00746c66,                                                 /* constant 2 name */
210     0x00030000, 0x00010001, 0x00000001, 0x00000000,             /* constant 2 type desc */
211     0x411fd70a, 0x00000000, 0x00000000, 0x00000000,             /* constant 2 default value */
212     0x3374616d,                                                 /* constant 3 name */
213     0xababab00,
214     0x00030003, 0x00040004, 0x00000001, 0x00000000,             /* constant 3 & 4 type desc */
215     0x41300000, 0x425c0000, 0x42c60000, 0x44a42000,             /* constat 3 default value */
216     0x41b00000, 0x42840000, 0x447c8000, 0x44b0c000,
217     0x42040000, 0x429a0000, 0x448ae000, 0x44bd6000,
218     0x42300000, 0x42b00000, 0x44978000, 0x44ca0000,
219     0x3474616d,                                                 /* constant 4 name */
220     0xababab00,
221     0x3f800000, 0x40a00000, 0x41100000, 0x41500000,             /* constant 4 default value */
222     0x40000000, 0x40c00000, 0x41200000, 0x41600000,
223     0x40400000, 0x40e00000, 0x41300000, 0x41700000,
224     0x40800000, 0x41000000, 0x41400000, 0x41800000,
225     0x34636576,                                                 /* constant 5 name */
226     0xababab00,
227     0x00030001, 0x00040001, 0x00000001, 0x00000000,             /* constant 5 type desc */
228     0x41200000, 0x41a00000, 0x41f00000, 0x42200000,             /* constant 5 default value */
229     0x325f7376, 0x4d004141, 0x41414141, 0x00000000,             /* target & creator string */
230     0x0000ffff};                                                /* END */
231
232 static const float mat4_default_value[] = {1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16};
233 static const float mat3_default_value[] = {11, 55, 99, 1313, 22, 66, 1010, 1414, 33, 77, 1111, 1515, 44, 88, 1212, 1616};
234 static const float arr_default_value[] = {100, 0, 0, 0, 200, 0, 0, 0, 300, 0, 0, 0};
235 static const float vec4_default_value[] = {10, 20, 30, 40};
236 static const float flt_default_value[] = {9.99, 0, 0, 0};
237
238 static const D3DXCONSTANT_DESC ctab_with_default_values_expected[] = {
239     {"mat4", D3DXRS_FLOAT4,  0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat4_default_value},
240     {"mat3", D3DXRS_FLOAT4,  4, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat3_default_value},
241     {"arr",  D3DXRS_FLOAT4,  8, 3, D3DXPC_SCALAR,         D3DXPT_FLOAT, 1, 1, 3, 0, 12, arr_default_value},
242     {"vec4", D3DXRS_FLOAT4, 11, 1, D3DXPC_VECTOR,         D3DXPT_FLOAT, 1, 4, 1, 0, 16, vec4_default_value},
243     {"flt",  D3DXRS_FLOAT4, 12, 1, D3DXPC_SCALAR,         D3DXPT_FLOAT, 1, 1, 1, 0,  4, flt_default_value}};
244
245 static const DWORD ctab_samplers[] = {
246     0xfffe0300,                                                             /* vs_3_0                        */
247     0x0032fffe, FCC_CTAB,                                                   /* CTAB comment                  */
248     0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header                        */
249     0x000000ac,
250     0x00000058, 0x00020002, 0x00000001, 0x00000064, 0x00000000,             /* Constant 1 desc (notsampler)  */
251     0x00000074, 0x00000003, 0x00000001, 0x00000080, 0x00000000,             /* Constant 2 desc (sampler1)    */
252     0x00000090, 0x00030003, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 3 desc (sampler2)    */
253     0x73746f6e, 0x6c706d61, 0xab007265,                                     /* Constant 1 name               */
254     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
255     0x706d6173, 0x3172656c, 0xababab00,                                     /* Constant 2 name               */
256     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
257     0x706d6173, 0x3272656c, 0xababab00,                                     /* Constant 3 name               */
258     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
259     0x335f7376, 0xab00305f,                                                 /* Target name string            */
260     0x656e6957, 0x6f727020, 0x7463656a, 0xababab00,                         /* Creator name string           */
261     0x0000ffff};                                                            /* END                           */
262
263 static const D3DXCONSTANT_DESC ctab_samplers_expected[] = {
264     {"sampler1",   D3DXRS_SAMPLER, 0, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER2D, 1, 1, 1, 0, 4,  NULL},
265     {"sampler2",   D3DXRS_SAMPLER, 3, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER3D, 1, 1, 1, 0, 4,  NULL},
266     {"notsampler", D3DXRS_FLOAT4,  2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT,     1, 4, 1, 0, 16, NULL}};
267
268 static void test_get_shader_size(void)
269 {
270     UINT shader_size, expected;
271
272     shader_size = D3DXGetShaderSize(simple_vs);
273     expected = sizeof(simple_vs);
274     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
275
276     shader_size = D3DXGetShaderSize(simple_ps);
277     expected = sizeof(simple_ps);
278     ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
279
280     shader_size = D3DXGetShaderSize(NULL);
281     ok(shader_size == 0, "Got shader size %u, expected 0\n", shader_size);
282 }
283
284 static void test_get_shader_version(void)
285 {
286     DWORD shader_version;
287
288     shader_version = D3DXGetShaderVersion(simple_vs);
289     ok(shader_version == D3DVS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
290             shader_version, D3DVS_VERSION(1, 1));
291
292     shader_version = D3DXGetShaderVersion(simple_ps);
293     ok(shader_version == D3DPS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
294             shader_version, D3DPS_VERSION(1, 1));
295
296     shader_version = D3DXGetShaderVersion(NULL);
297     ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version);
298 }
299
300 static void test_find_shader_comment(void)
301 {
302     HRESULT hr;
303     LPCVOID data = (LPVOID)0xdeadbeef;
304     UINT size = 100;
305
306     hr = D3DXFindShaderComment(NULL, MAKEFOURCC('C','T','A','B'), &data, &size);
307     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
308     ok(!data, "Got %p, expected NULL\n", data);
309     ok(!size, "Got %u, expected 0\n", size);
310
311     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), NULL, &size);
312     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
313     ok(size == 28, "Got %u, expected 28\n", size);
314
315     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, NULL);
316     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
317     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
318
319     hr = D3DXFindShaderComment(shader_with_ctab, 0, &data, &size);
320     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
321     ok(!data, "Got %p, expected NULL\n", data);
322     ok(!size, "Got %u, expected 0\n", size);
323
324     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('X','X','X','X'), &data, &size);
325     ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
326     ok(!data, "Got %p, expected NULL\n", data);
327     ok(!size, "Got %u, expected 0\n", size);
328
329     hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, &size);
330     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
331     ok(data == (LPCVOID)(shader_with_ctab + 6), "Got result %p, expected %p\n", data, shader_with_ctab + 6);
332     ok(size == 28, "Got result %d, expected 28\n", size);
333 }
334
335 static void test_get_shader_constant_table_ex(void)
336 {
337     LPD3DXCONSTANTTABLE constant_table = NULL;
338     HRESULT hr;
339     LPVOID data;
340     DWORD size;
341     D3DXCONSTANTTABLE_DESC desc;
342
343     hr = D3DXGetShaderConstantTableEx(NULL, 0, &constant_table);
344     ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
345
346     /* No CTAB data */
347     hr = D3DXGetShaderConstantTableEx(simple_ps, 0, &constant_table);
348     ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
349
350     /* With invalid CTAB data */
351     hr = D3DXGetShaderConstantTableEx(shader_with_invalid_ctab, 0, &constant_table);
352     ok(hr == D3DXERR_INVALIDDATA || broken(hr == D3D_OK), /* winxp 64-bit, w2k3 64-bit */
353        "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
354     if (constant_table) ID3DXConstantTable_Release(constant_table);
355
356     hr = D3DXGetShaderConstantTableEx(shader_with_ctab, 0, &constant_table);
357     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
358
359     if (constant_table)
360     {
361         size = ID3DXConstantTable_GetBufferSize(constant_table);
362         ok(size == 28, "Got result %x, expected 28\n", size);
363
364         data = ID3DXConstantTable_GetBufferPointer(constant_table);
365         ok(!memcmp(data, shader_with_ctab + 6, size), "Retrieved wrong CTAB data\n");
366
367         hr = ID3DXConstantTable_GetDesc(constant_table, NULL);
368         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
369
370         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
371         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
372         ok(desc.Creator == (LPCSTR)data + 0x10, "Got result %p, expected %p\n", desc.Creator, (LPCSTR)data + 0x10);
373         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
374         ok(desc.Constants == 0, "Got result %x, expected 0\n", desc.Constants);
375
376         ID3DXConstantTable_Release(constant_table);
377     }
378
379     hr = D3DXGetShaderConstantTableEx(shader_with_ctab_constants, 0, &constant_table);
380     ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
381
382     if (SUCCEEDED(hr))
383     {
384         D3DXHANDLE constant;
385         D3DXCONSTANT_DESC constant_desc;
386         D3DXCONSTANT_DESC constant_desc_save;
387         UINT nb;
388
389         /* Test GetDesc */
390         hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
391         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
392         ok(!strcmp(desc.Creator, "Wine project"), "Got result '%s', expected 'Wine project'\n", desc.Creator);
393         ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
394         ok(desc.Constants == 3, "Got result %x, expected 3\n", desc.Constants);
395
396         /* Test GetConstant */
397         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
398         ok(constant != NULL, "No constant found\n");
399         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
400         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
401         ok(!strcmp(constant_desc.Name, "Constant1"), "Got result '%s', expected 'Constant1'\n",
402             constant_desc.Name);
403         ok(constant_desc.Class == D3DXPC_VECTOR, "Got result %x, expected %u (D3DXPC_VECTOR)\n",
404             constant_desc.Class, D3DXPC_VECTOR);
405         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
406             constant_desc.Type, D3DXPT_FLOAT);
407         ok(constant_desc.Rows == 1, "Got result %x, expected 1\n", constant_desc.Rows);
408         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
409
410         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 1);
411         ok(constant != NULL, "No constant found\n");
412         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
413         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
414         ok(!strcmp(constant_desc.Name, "Constant2"), "Got result '%s', expected 'Constant2'\n",
415             constant_desc.Name);
416         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
417             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
418         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
419             constant_desc.Type, D3DXPT_FLOAT);
420         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
421         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
422
423         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 2);
424         ok(constant != NULL, "No constant found\n");
425         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
426         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
427         ok(!strcmp(constant_desc.Name, "Constant3"), "Got result '%s', expected 'Constant3'\n",
428             constant_desc.Name);
429         ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
430             constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
431         ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
432             constant_desc.Type, D3DXPT_FLOAT);
433         ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
434         ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
435         constant_desc_save = constant_desc; /* For GetConstantDesc test */
436
437         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 3);
438         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
439
440         /* Test GetConstantByName */
441         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant unknown");
442         ok(constant == NULL, "Got result %p, expected NULL\n", constant);
443         constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant3");
444         ok(constant != NULL, "No constant found\n");
445         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
446         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
447         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
448
449         /* Test GetConstantDesc */
450         constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
451         ok(constant != NULL, "No constant found\n");
452         hr = ID3DXConstantTable_GetConstantDesc(constant_table, NULL, &constant_desc, &nb);
453         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
454         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, NULL, &nb);
455         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
456         hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, NULL);
457         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
458         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant unknow", &constant_desc, &nb);
459         ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
460         hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant3", &constant_desc, &nb);
461         ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
462         ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
463
464         ID3DXConstantTable_Release(constant_table);
465     }
466 }
467
468 static void test_constant_table(const char *test_name, const DWORD *ctable_fn,
469         const D3DXCONSTANT_DESC *expecteds, UINT count)
470 {
471     UINT i;
472     ID3DXConstantTable *ctable;
473
474     HRESULT res;
475
476     /* Get the constant table from the shader itself */
477     res = D3DXGetShaderConstantTable(ctable_fn, &ctable);
478     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on %s: got %08x\n", test_name, res);
479
480     for (i = 0; i < count; i++)
481     {
482         const D3DXCONSTANT_DESC *expected = &expecteds[i];
483         D3DXHANDLE const_handle;
484         D3DXCONSTANT_DESC actual;
485         UINT pCount = 1;
486
487         const_handle = ID3DXConstantTable_GetConstantByName(ctable, NULL, expected->Name);
488
489         res = ID3DXConstantTable_GetConstantDesc(ctable, const_handle, &actual, &pCount);
490         ok(SUCCEEDED(res), "%s in %s: ID3DXConstantTable_GetConstantDesc returned %08x\n", expected->Name,
491                 test_name, res);
492         ok(pCount == 1, "%s in %s: Got more or less descriptions: %d\n", expected->Name, test_name, pCount);
493
494         ok(strcmp(actual.Name, expected->Name) == 0,
495            "%s in %s: Got different names: Got %s, expected %s\n", expected->Name,
496            test_name, actual.Name, expected->Name);
497         ok(actual.RegisterSet == expected->RegisterSet,
498            "%s in %s: Got different register sets: Got %d, expected %d\n",
499            expected->Name, test_name, actual.RegisterSet, expected->RegisterSet);
500         ok(actual.RegisterIndex == expected->RegisterIndex,
501            "%s in %s: Got different register indices: Got %d, expected %d\n",
502            expected->Name, test_name, actual.RegisterIndex, expected->RegisterIndex);
503         ok(actual.RegisterCount == expected->RegisterCount,
504            "%s in %s: Got different register counts: Got %d, expected %d\n",
505            expected->Name, test_name, actual.RegisterCount, expected->RegisterCount);
506         ok(actual.Class == expected->Class,
507            "%s in %s: Got different classes: Got %d, expected %d\n", expected->Name,
508            test_name, actual.Class, expected->Class);
509         ok(actual.Type == expected->Type,
510            "%s in %s: Got different types: Got %d, expected %d\n", expected->Name,
511            test_name, actual.Type, expected->Type);
512         ok(actual.Rows == expected->Rows && actual.Columns == expected->Columns,
513            "%s in %s: Got different dimensions: Got (%d, %d), expected (%d, %d)\n",
514            expected->Name, test_name, actual.Rows, actual.Columns, expected->Rows,
515            expected->Columns);
516         ok(actual.Elements == expected->Elements,
517            "%s in %s: Got different element count: Got %d, expected %d\n",
518            expected->Name, test_name, actual.Elements, expected->Elements);
519         ok(actual.StructMembers == expected->StructMembers,
520            "%s in %s: Got different struct member count: Got %d, expected %d\n",
521            expected->Name, test_name, actual.StructMembers, expected->StructMembers);
522         ok(actual.Bytes == expected->Bytes,
523            "%s in %s: Got different byte count: Got %d, expected %d\n",
524            expected->Name, test_name, actual.Bytes, expected->Bytes);
525
526         if (!expected->DefaultValue)
527         {
528             ok(actual.DefaultValue == NULL,
529                 "%s in %s: Got different default value: expected NULL\n",
530                 expected->Name, test_name);
531         }
532         else
533         {
534             ok(actual.DefaultValue != NULL,
535                 "%s in %s: Got different default value: expected non-NULL\n",
536                 expected->Name, test_name);
537             ok(memcmp(actual.DefaultValue, expected->DefaultValue, expected->Bytes) == 0,
538                 "%s in %s: Got different default value\n", expected->Name, test_name);
539         }
540     }
541
542     /* Finally, release the constant table */
543     ID3DXConstantTable_Release(ctable);
544 }
545
546 static void test_constant_tables(void)
547 {
548     test_constant_table("test_basic", ctab_basic, ctab_basic_expected,
549             sizeof(ctab_basic_expected)/sizeof(*ctab_basic_expected));
550     test_constant_table("test_matrices", ctab_matrices, ctab_matrices_expected,
551             sizeof(ctab_matrices_expected)/sizeof(*ctab_matrices_expected));
552     test_constant_table("test_matrices2", ctab_matrices2, ctab_matrices2_expected,
553             sizeof(ctab_matrices2_expected)/sizeof(*ctab_matrices2_expected));
554     test_constant_table("test_arrays", ctab_arrays, ctab_arrays_expected,
555             sizeof(ctab_arrays_expected)/sizeof(*ctab_arrays_expected));
556     test_constant_table("test_default_values", ctab_with_default_values, ctab_with_default_values_expected,
557             sizeof(ctab_with_default_values_expected)/sizeof(*ctab_with_default_values_expected));
558     test_constant_table("test_samplers", ctab_samplers, ctab_samplers_expected,
559             sizeof(ctab_samplers_expected)/sizeof(*ctab_samplers_expected));
560 }
561
562 static void test_setting_basic_table(IDirect3DDevice9 *device)
563 {
564     static const D3DXMATRIX mvp = {{{
565         0.514f, 0.626f, 0.804f, 0.786f,
566         0.238f, 0.956f, 0.374f, 0.483f,
567         0.109f, 0.586f, 0.900f, 0.255f,
568         0.898f, 0.411f, 0.932f, 0.275f}}};
569     static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f};
570     static const float f = 0.12543f;
571     static const int i = 321;
572
573     ID3DXConstantTable *ctable;
574
575     HRESULT res;
576     float out[16];
577     ULONG refcnt;
578
579     /* Get the constant table from the shader itself */
580     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
581     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
582
583     /* Set constants */
584     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
585     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res);
586
587     res = ID3DXConstantTable_SetInt(ctable, device, "i", i + 1);
588     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
589
590     /* Check that setting i again will overwrite the previous value */
591     res = ID3DXConstantTable_SetInt(ctable, device, "i", i);
592     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
593
594     res = ID3DXConstantTable_SetFloat(ctable, device, "f", f);
595     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res);
596
597     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
598     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res);
599
600     /* Get constants back and validate */
601     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
602     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,
603             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
604             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
605     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,
606             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
607             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
608     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,
609             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
610             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
611     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,
612             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
613             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
614
615     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1);
616     ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
617             "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n",
618             out[0], out[1], out[2], out[3], i);
619
620     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
621     ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
622             "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n",
623             out[0], out[1], out[2], out[3], f);
624
625     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
626     ok(memcmp(out, &f4, sizeof(f4)) == 0,
627             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
628             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
629
630     /* Finally test using a set* function for one type to set a variable of another type (should succeed) */
631     res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4);
632     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
633
634     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
635     ok(out[0] == f4.x && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
636             "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n",
637             out[0], f4.x);
638
639     memset(out, 0, sizeof(out));
640     IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
641     res = ID3DXConstantTable_SetMatrix(ctable, device, "f", &mvp);
642     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable f: 0x%08x\n", res);
643
644     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
645     ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
646             "The variable f was not set correctly by ID3DXConstantTable_SetMatrix, got %f, should be %f\n",
647             out[0], U(S(mvp))._11);
648
649     /* Clear registers */
650     memset(out, 0, sizeof(out));
651     IDirect3DDevice9_SetVertexShaderConstantF(device, 0, out, 4);
652     IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
653     IDirect3DDevice9_SetVertexShaderConstantF(device, 7, out, 1);
654
655     /* SetVector shouldn't change the value of a matrix constant */
656     res = ID3DXConstantTable_SetVector(ctable, device, "mvp", &f4);
657     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
658
659     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
660     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
661             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
662             && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
663             && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
664             "The variable mvp was not set correctly by ID3DXConstantTable_SetVector, "
665             "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
666             "should be all 0.0f\n",
667             out[0], out[1], out[2], out[3],
668             out[4], out[5], out[6], out[7],
669             out[8], out[9], out[10], out[11],
670             out[12], out[13], out[14], out[15]);
671
672     res = ID3DXConstantTable_SetFloat(ctable, device, "mvp", f);
673     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable mvp: 0x%08x\n", res);
674
675     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
676     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
677             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
678             && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
679             && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
680             "The variable mvp was not set correctly by ID3DXConstantTable_SetFloat, "
681             "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
682             "should be all 0.0f\n",
683             out[0], out[1], out[2], out[3],
684             out[4], out[5], out[6], out[7],
685             out[8], out[9], out[10], out[11],
686             out[12], out[13], out[14], out[15]);
687
688     res = ID3DXConstantTable_SetFloat(ctable, device, "f4", f);
689     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f4: 0x%08x\n", res);
690
691     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
692     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
693             "The variable f4 was not set correctly by ID3DXConstantTable_SetFloat, "
694             "got {%f, %f, %f, %f}, should be all 0.0f\n",
695             out[0], out[1], out[2], out[3]);
696
697     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f", &mvp);
698     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f: 0x%08x\n", res);
699
700     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
701     ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
702             "The variable f was not set correctly by ID3DXConstantTable_SetMatrixTranspose, got %f, should be %f\n",
703             out[0], U(S(mvp))._11);
704
705     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f4", &mvp);
706     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f4: 0x%08x\n", res);
707
708     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
709     todo_wine ok(out[0] == S(U(mvp))._11 && out[1] == S(U(mvp))._21 && out[2] == S(U(mvp))._31 && out[3] == S(U(mvp))._41,
710             "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixTranspose, "
711             "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
712             out[0], out[1], out[2], out[3],
713             S(U(mvp))._11, S(U(mvp))._21, S(U(mvp))._31, S(U(mvp))._41);
714
715     refcnt = ID3DXConstantTable_Release(ctable);
716     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
717 }
718
719 static void test_setting_matrices_table(IDirect3DDevice9 *device)
720 {
721     static const D3DXMATRIX fmatrix =
722         {{{2.001f, 1.502f, 9.003f, 1.004f,
723            5.005f, 3.006f, 3.007f, 6.008f,
724            9.009f, 5.010f, 7.011f, 1.012f,
725            5.013f, 5.014f, 5.015f, 9.016f}}};
726
727     ID3DXConstantTable *ctable;
728
729     HRESULT res;
730     float out[32];
731
732     res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
733     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
734
735     res = ID3DXConstantTable_SetMatrix(ctable, device, "imatrix2x3", &fmatrix);
736     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable fmatrix2x3: got %#x\n", res);
737
738     res = ID3DXConstantTable_SetMatrix(ctable, device, "fmatrix3x1", &fmatrix);
739     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable fmatrix3x1: got %#x\n", res);
740
741     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
742     todo_wine ok(out[0] == (int)S(U(fmatrix))._11 && out[1] == (int)S(U(fmatrix))._12 && out[2] == (int)S(U(fmatrix))._13
743             && out[3] == 0
744             && out[4] == (int)S(U(fmatrix))._21 && out[5] == (int)S(U(fmatrix))._22 && out[6] == (int)S(U(fmatrix))._23
745             && out[7] == 0,
746             "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
747             "should be {%d, %d, %d, %d; %d, %d, %d, %d}\n",
748             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
749             (int)S(U(fmatrix))._11, (int)S(U(fmatrix))._12, (int)S(U(fmatrix))._13, 0,
750             (int)S(U(fmatrix))._21, (int)S(U(fmatrix))._22, (int)S(U(fmatrix))._23, 0);
751
752     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
753     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f,
754             "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
755             out[0], out[1], out[2], out[3],
756             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f);
757
758     ID3DXConstantTable_Release(ctable);
759
760     res = D3DXGetShaderConstantTable(ctab_matrices2, &ctable);
761     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
762
763     /* SetMatrix */
764     res = ID3DXConstantTable_SetMatrix(ctable, device, "c2x3", &fmatrix);
765     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c2x3: got %#x\n", res);
766
767     res = ID3DXConstantTable_SetMatrix(ctable, device, "r2x3", &fmatrix);
768     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r2x3: got %#x\n", res);
769
770     res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x2", &fmatrix);
771     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x2: got %#x\n", res);
772
773     res = ID3DXConstantTable_SetMatrix(ctable, device, "r3x2", &fmatrix);
774     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r3x2: got %#x\n", res);
775
776     res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x3", &fmatrix);
777     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x3: got %#x\n", res);
778
779     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
780     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f
781             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
782             && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f,
783             "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
784             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
785             out[0], out[1], out[2], out[3],
786             out[4], out[5], out[6], out[7],
787             out[8], out[9], out[10], out[11],
788             S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f,
789             S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f,
790             S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f);
791
792     res = ID3DXConstantTable_SetMatrix(ctable, device, "r4x4", &fmatrix);
793     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r4x4: got %#x\n", res);
794
795     IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
796     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f
797             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f,
798             "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
799             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
800             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
801             S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f,
802             S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f);
803
804     IDirect3DDevice9_GetVertexShaderConstantF(device, 13, out, 2);
805     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
806             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
807             "The variable c3x2 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
808             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
809             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
810             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
811             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
812
813     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 3);
814     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
815             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
816             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
817             "The variable r3x2 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
818             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
819             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
820             S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
821             S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
822             S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
823
824     IDirect3DDevice9_GetVertexShaderConstantF(device, 10, out, 3);
825     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
826             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f
827             && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == S(U(fmatrix))._33 && out[11] == 0.0f,
828             "The variable c3x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
829             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
830             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
831             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
832             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f,
833             S(U(fmatrix))._13, S(U(fmatrix))._23, S(U(fmatrix))._33, 0.0f);
834
835     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
836     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == S(U(fmatrix))._14
837             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == S(U(fmatrix))._24
838             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == S(U(fmatrix))._33 && out[11] == S(U(fmatrix))._34
839             && out[12] == S(U(fmatrix))._41 && out[13] == S(U(fmatrix))._42 && out[14] == S(U(fmatrix))._43 && out[15] == S(U(fmatrix))._44,
840             "The variable r4x4 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
841             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
842             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
843             out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
844             S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, S(U(fmatrix))._14,
845             S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, S(U(fmatrix))._24,
846             S(U(fmatrix))._31, S(U(fmatrix))._32, S(U(fmatrix))._33, S(U(fmatrix))._34,
847             S(U(fmatrix))._41, S(U(fmatrix))._42, S(U(fmatrix))._43, S(U(fmatrix))._44);
848
849     /* SetMatrixTranspose */
850     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "c2x3", &fmatrix);
851     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable c2x3: got %#x\n", res);
852
853     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "r2x3", &fmatrix);
854     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable r2x3: got %#x\n", res);
855
856     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
857     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
858             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
859             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
860             "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
861             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
862             out[0], out[1], out[2], out[3],
863             out[4], out[5], out[6], out[7],
864             out[8], out[9], out[10], out[11],
865             S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
866             S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
867             S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
868
869     IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
870     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
871             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
872             "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
873             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
874             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
875             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
876             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
877
878     ID3DXConstantTable_Release(ctable);
879 }
880
881 static void test_setting_arrays_table(IDirect3DDevice9 *device)
882 {
883     static const float farray[8] = {
884         0.005f, 0.745f, 0.973f, 0.264f,
885         0.010f, 0.020f, 0.030f, 0.040f};
886     static const D3DXMATRIX fmtxarray[2] = {
887         {{{0.001f, 0.002f, 0.003f, 0.004f,
888            0.005f, 0.006f, 0.007f, 0.008f,
889            0.009f, 0.010f, 0.011f, 0.012f,
890            0.013f, 0.014f, 0.015f, 0.016f}}},
891         {{{0.010f, 0.020f, 0.030f, 0.040f,
892            0.050f, 0.060f, 0.070f, 0.080f,
893            0.090f, 0.100f, 0.110f, 0.120f,
894            0.130f, 0.140f, 0.150f, 0.160f}}}};
895     static const int iarray[4] = {1, 2, 3, 4};
896     static const D3DXVECTOR4 fvecarray[2] = {
897         {0.745f, 0.997f, 0.353f, 0.237f},
898         {0.060f, 0.455f, 0.333f, 0.983f}};
899     static BOOL barray[4] = {FALSE, 100, TRUE, TRUE};
900
901     ID3DXConstantTable *ctable;
902
903     HRESULT res;
904     float out[32];
905     ULONG refcnt;
906
907     /* Clear registers */
908     memset(out, 0, sizeof(out));
909     IDirect3DDevice9_SetVertexShaderConstantF(device,  8, out, 4);
910     IDirect3DDevice9_SetVertexShaderConstantF(device, 12, out, 4);
911
912     /* Get the constant table from the shader */
913     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
914     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
915
916     /* Set constants */
917
918     /* Make sure that we cannot set registers that do not belong to this constant */
919     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8);
920     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res);
921
922     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8);
923     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
924             "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
925             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
926     ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f,
927             "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n",
928             out[16], out[20], out[24], out[28]);
929
930     /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */
931     res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]);
932     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res);
933
934     IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4);
935     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
936        "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]);
937
938     /* Try setting an integer array to an array declared as a float array */
939     res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4);
940     ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res);
941
942     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
943     ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3],
944            "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n",
945             out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]);
946
947     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4);
948     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res);
949
950     res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2);
951     ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res);
952
953     res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2);
954     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res);
955
956     res = ID3DXConstantTable_SetBoolArray(ctable, device, "barray", barray, 2);
957     ok(res == D3D_OK, "ID3DXConstantTable_SetBoolArray failed: got 0x%08x\n", res);
958
959     /* Read back constants */
960     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
961     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
962             "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
963             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
964
965     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
966     ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w &&
967             out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w,
968             "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be "
969             "{{%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],
970             fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y,
971             fvecarray[1].z, fvecarray[1].w);
972
973     IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
974     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
975             && out[4] == 1.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
976             "The variable barray was not set correctly, out={%f, %f %f, %f; %f, %f, %f, %f}, should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
977             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
978             0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
979
980     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8);
981     /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */
982     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,
983            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
984            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);
985     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,
986            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
987            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);
988
989     refcnt = ID3DXConstantTable_Release(ctable);
990     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
991 }
992
993 static void test_SetDefaults(IDirect3DDevice9 *device)
994 {
995     static const D3DXMATRIX mvp = {{{
996         0.51f, 0.62f, 0.80f, 0.78f,
997         0.23f, 0.95f, 0.37f, 0.48f,
998         0.10f, 0.58f, 0.90f, 0.25f,
999         0.89f, 0.41f, 0.93f, 0.27f}}};
1000     static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
1001
1002     float out[16];
1003
1004     HRESULT res;
1005     ID3DXConstantTable *ctable;
1006
1007     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
1008     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1009
1010     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
1011     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed: got %08x\n", res);
1012
1013     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
1014     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got %08x\n", res);
1015
1016     res = ID3DXConstantTable_SetDefaults(ctable, device);
1017     ok(res == D3D_OK, "ID3dXConstantTable_SetDefaults failed: got %08x\n", res);
1018
1019     /* SetDefaults doesn't change constants without default values */
1020     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1021     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,
1022             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1023             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
1024     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,
1025             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1026             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
1027     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,
1028             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1029             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
1030     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,
1031             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1032             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
1033
1034     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1035     ok(memcmp(out, &f4, sizeof(f4)) == 0,
1036             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1037             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
1038
1039     ID3DXConstantTable_Release(ctable);
1040
1041     res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
1042     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1043
1044     res = ID3DXConstantTable_SetDefaults(ctable, device);
1045     ok(res == D3D_OK, "ID3DXConstantTable_SetDefaults failed: got %08x\n", res);
1046
1047     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1048     ok(memcmp(out, mat4_default_value, sizeof(mat4_default_value)) == 0,
1049             "The variable mat4 was not set correctly to default value\n");
1050
1051     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 4);
1052     ok(memcmp(out, mat3_default_value, sizeof(mat3_default_value)) == 0,
1053             "The variable mat3 was not set correctly to default value\n");
1054
1055     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
1056     ok(memcmp(out, arr_default_value, sizeof(arr_default_value)) == 0,
1057         "The variable array was not set correctly to default value\n");
1058
1059     IDirect3DDevice9_GetVertexShaderConstantF(device, 11, out, 1);
1060     ok(memcmp(out, vec4_default_value, sizeof(vec4_default_value)) == 0,
1061         "The variable vec4 was not set correctly to default value\n");
1062
1063     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 1);
1064     ok(memcmp(out, flt_default_value, sizeof(flt_default_value)) == 0,
1065         "The variable flt was not set correctly to default value\n");
1066
1067     ID3DXConstantTable_Release(ctable);
1068 }
1069
1070 static void test_SetValue(IDirect3DDevice9 *device)
1071 {
1072     static const D3DXMATRIX mvp = {{{
1073         0.51f, 0.62f, 0.80f, 0.78f,
1074         0.23f, 0.95f, 0.37f, 0.48f,
1075         0.10f, 0.58f, 0.90f, 0.25f,
1076         0.89f, 0.41f, 0.93f, 0.27f}}};
1077     static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
1078     static const FLOAT arr[] = {0.33f, 0.55f, 0.96f, 1.00f,
1079                                 1.00f, 1.00f, 1.00f, 1.00f,
1080                                 1.00f, 1.00f, 1.00f, 1.00f};
1081     static int imatrix[] = {1, 2, 3, 4, 5, 6};
1082     static float fmatrix[] = {1.1f, 2.2f, 3.3f, 4.4f};
1083     static BOOL barray[] = {TRUE, FALSE};
1084     static float fvecarray[] = {9.1f, 9.2f, 9.3f, 9.4f, 9.5f, 9.6f, 9.7f, 9.8f};
1085     static float farray[] = {2.2f, 3.3f};
1086
1087     static const float def[16] = {5.5f, 5.5f, 5.5f, 5.5f,
1088                                   5.5f, 5.5f, 5.5f, 5.5f,
1089                                   5.5f, 5.5f, 5.5f, 5.5f,
1090                                   5.5f, 5.5f, 5.5f, 5.5f};
1091     float out[16];
1092
1093     HRESULT res;
1094     ID3DXConstantTable *ctable;
1095
1096     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
1097     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1098
1099     IDirect3DDevice9_SetVertexShaderConstantF(device, 7, def, 1);
1100
1101     /* SetValue called with 0 bytes size doesn't change value */
1102     res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, 0);
1103     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1104
1105     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1106     ok(memcmp(out, def, sizeof(f4)) == 0,
1107             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1108             out[0], out[1], out[2], out[3], def[0], def[1], def[2], def[3]);
1109
1110     res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, sizeof(f4));
1111     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1112
1113     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1114     ok(memcmp(out, &f4, sizeof(f4)) == 0,
1115             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1116             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
1117
1118     IDirect3DDevice9_SetVertexShaderConstantF(device, 0, def, 4);
1119
1120     /* SetValue called with size smaller than constant size doesn't change value */
1121     res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp) / 2);
1122     ok(res == D3D_OK, "ID3DXConstantTable_SetValue returned %08x\n", res);
1123
1124     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1125     ok(memcmp(out, def, sizeof(def)) == 0,
1126             "The variable mvp was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
1127             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
1128             out[0], out[4], out[ 8], out[12],
1129             out[1], out[5], out[ 9], out[13],
1130             out[2], out[6], out[10], out[14],
1131             out[3], out[7], out[11], out[15],
1132             def[0], def[4], def[ 8], def[12],
1133             def[1], def[5], def[ 9], def[13],
1134             def[2], def[6], def[10], def[14],
1135             def[3], def[7], def[11], def[15]);
1136
1137     res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp));
1138     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1139
1140     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1141     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,
1142             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1143             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
1144     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,
1145             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1146             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
1147     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,
1148             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1149             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
1150     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,
1151             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1152             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
1153
1154     ID3DXConstantTable_Release(ctable);
1155
1156     res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
1157     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1158
1159     res = ID3DXConstantTable_SetValue(ctable, device, "arr", arr, sizeof(arr));
1160     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1161
1162     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
1163     ok(out[0] == arr[0] && out[4] == arr[1] && out[8] == arr[2]
1164             && out[1] == 0 &&  out[2] == 0 && out[3] == 0 && out[5] == 0 && out[6] == 0 && out[7] == 0
1165             && out[9] == 0 && out[10] == 0 && out[11] == 0,
1166             "The variable arr was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f}, "
1167             "should be {0.33, 0, 0, 0, 0.55, 0, 0, 0, 0.96, 0, 0, 0}\n",
1168             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11]);
1169
1170     ID3DXConstantTable_Release(ctable);
1171
1172     res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
1173     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1174
1175     res = ID3DXConstantTable_SetValue(ctable, device, "fmatrix3x1", fmatrix, sizeof(fmatrix));
1176     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1177
1178     res = ID3DXConstantTable_SetValue(ctable, device, "imatrix2x3", imatrix, sizeof(imatrix));
1179     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1180
1181     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
1182     ok(out[0] == imatrix[0] && out[1] == imatrix[1] && out[2] == imatrix[2] && out[3] == 0.0f
1183             && out[4] == imatrix[3] && out[5] == imatrix[4] && out[6] == imatrix[5] && out[7] == 0.0f,
1184             "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
1185             "should be {%d, %d, %d, 0, %d, %d, %d, 0}\n",
1186             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1187             imatrix[0], imatrix[1], imatrix[2], imatrix[3], imatrix[4], imatrix[5]);
1188
1189     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 2);
1190     ok(out[0] == fmatrix[0] && out[1] == fmatrix[1] && out[2] == fmatrix[2] && out[3] == 0.0f,
1191             "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1192             out[0], out[1] ,out[2], out[4],
1193             fmatrix[0], fmatrix[1], fmatrix[2], 0.0f);
1194
1195     ID3DXConstantTable_Release(ctable);
1196
1197     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
1198     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1199
1200     res = ID3DXConstantTable_SetValue(ctable, device, "barray", barray, sizeof(barray));
1201     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1202
1203     res = ID3DXConstantTable_SetValue(ctable, device, "fvecarray", fvecarray, sizeof(fvecarray));
1204     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1205
1206     IDirect3DDevice9_SetVertexShaderConstantF(device, 8, def, 4);
1207     res = ID3DXConstantTable_SetValue(ctable, device, "farray", farray, sizeof(farray));
1208     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1209
1210     /* 2 elements of farray were set */
1211     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
1212     ok(out[0] == farray[0] && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
1213             && out[4] == farray[1] && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
1214             && out[8] == def[8] && out[9] == def[9] && out[10] == def[10] && out[11] == def[11]
1215             && out[12] == def[12] && out[13] == def[13] && out[14] == def[14] && out[15] == def[15],
1216             "The variable farray was not set correctly, should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
1217             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
1218             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1219             out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
1220             farray[0], 0.0f, 0.0f, 0.0f,
1221             farray[1], 0.0f, 0.0f, 0.0f,
1222             def[8], def[9], def[10], def[11],
1223             def[12], def[13], def[14], def[15]);
1224
1225     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
1226     ok(out[0] == fvecarray[0] && out[1] == fvecarray[1] && out[2] == fvecarray[2] && out[3] == fvecarray[3]
1227             && out[4] == fvecarray[4] && out[5] == fvecarray[5] && out[6] == fvecarray[6] && out[7] == fvecarray[7],
1228             "The variable fvecarray was not set correctly, out ={%f, %f, %f, %f, %f, %f, %f, %f}, "
1229             "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
1230             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1231             fvecarray[0], fvecarray[1], fvecarray[2], fvecarray[3], fvecarray[4], fvecarray[5], fvecarray[6], fvecarray[7]);
1232
1233     IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
1234     ok(out[0] == 1.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
1235             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
1236             "The variable barray was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
1237             "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
1238             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1239             1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
1240
1241     ID3DXConstantTable_Release(ctable);
1242 }
1243
1244 static void test_setting_constants(void)
1245 {
1246     HWND wnd;
1247     IDirect3D9 *d3d;
1248     IDirect3DDevice9 *device;
1249     D3DPRESENT_PARAMETERS d3dpp;
1250     HRESULT hr;
1251     ULONG refcnt;
1252
1253     /* Create the device to use for our tests */
1254     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1255     d3d = Direct3DCreate9(D3D_SDK_VERSION);
1256     if (!wnd)
1257     {
1258         skip("Couldn't create application window\n");
1259         return;
1260     }
1261     if (!d3d)
1262     {
1263         skip("Couldn't create IDirect3D9 object\n");
1264         DestroyWindow(wnd);
1265         return;
1266     }
1267
1268     ZeroMemory(&d3dpp, sizeof(d3dpp));
1269     d3dpp.Windowed   = TRUE;
1270     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1271     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
1272     if (FAILED(hr))
1273     {
1274         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
1275         IDirect3D9_Release(d3d);
1276         DestroyWindow(wnd);
1277         return;
1278     }
1279
1280     test_setting_basic_table(device);
1281     test_setting_matrices_table(device);
1282     test_setting_arrays_table(device);
1283     test_SetDefaults(device);
1284     test_SetValue(device);
1285
1286     /* Release resources */
1287     refcnt = IDirect3DDevice9_Release(device);
1288     ok(refcnt == 0, "The Direct3D device reference count was %u, should be 0\n", refcnt);
1289
1290     refcnt = IDirect3D9_Release(d3d);
1291     ok(refcnt == 0, "The Direct3D object referenct count was %u, should be 0\n", refcnt);
1292
1293     if (wnd) DestroyWindow(wnd);
1294 }
1295
1296 static void test_get_sampler_index(void)
1297 {
1298     ID3DXConstantTable *ctable;
1299
1300     HRESULT res;
1301     UINT index;
1302
1303     ULONG refcnt;
1304
1305     res = D3DXGetShaderConstantTable(ctab_samplers, &ctable);
1306     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res);
1307
1308     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1");
1309     ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index);
1310
1311     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2");
1312     ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index);
1313
1314     index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent");
1315     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n",
1316             index);
1317
1318     index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler");
1319     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n",
1320             index);
1321
1322     refcnt = ID3DXConstantTable_Release(ctable);
1323     ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt);
1324 }
1325
1326 /*
1327  * fxc.exe /Tps_3_0
1328  */
1329 #if 0
1330 sampler s;
1331 sampler1D s1D;
1332 sampler2D s2D;
1333 sampler3D s3D;
1334 samplerCUBE scube;
1335 float4 init;
1336 float4 main(float3 tex : TEXCOORD0) : COLOR
1337 {
1338     float4 tmp = init;
1339     tmp = tmp + tex1D(s1D, tex.x);
1340     tmp = tmp + tex1D(s1D, tex.y);
1341     tmp = tmp + tex3D(s3D, tex.xyz);
1342     tmp = tmp + tex1D(s, tex.x);
1343     tmp = tmp + tex2D(s2D, tex.xy);
1344     tmp = tmp + texCUBE(scube, tex.xyz);
1345     return tmp;
1346 }
1347 #endif
1348 static const DWORD get_shader_samplers_blob[] =
1349 {
1350     0xffff0300,                                                             /* ps_3_0                        */
1351     0x0054fffe, FCC_CTAB,                                                   /* CTAB comment                  */
1352     0x0000001c, 0x0000011b, 0xffff0300, 0x00000006, 0x0000001c, 0x00000100, /* Header                        */
1353     0x00000114,
1354     0x00000094, 0x00000002, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 1 desc (init)        */
1355     0x000000ac, 0x00040003, 0x00000001, 0x000000b0, 0x00000000,             /* Constant 2 desc (s)           */
1356     0x000000c0, 0x00000003, 0x00000001, 0x000000c4, 0x00000000,             /* Constant 3 desc (s1D)         */
1357     0x000000d4, 0x00010003, 0x00000001, 0x000000d8, 0x00000000,             /* Constant 4 desc (s2D)         */
1358     0x000000e8, 0x00030003, 0x00000001, 0x000000ec, 0x00000000,             /* Constant 5 desc (s3D)         */
1359     0x000000fc, 0x00020003, 0x00000001, 0x00000104, 0x00000000,             /* Constant 6 desc (scube)       */
1360     0x74696e69, 0xababab00,                                                 /* Constant 1 name               */
1361     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
1362     0xabab0073,                                                             /* Constant 2 name               */
1363     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
1364     0x00443173,                                                             /* Constant 3 name               */
1365     0x000b0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
1366     0x00443273,                                                             /* Constant 4 name               */
1367     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 4 type desc          */
1368     0x00443373,                                                             /* Constant 5 name               */
1369     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 5 type desc          */
1370     0x62756373, 0xabab0065,                                                 /* Constant 6 name               */
1371     0x000e0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 6 type desc          */
1372     0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, /* Target/Creator name string    */
1373     0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
1374     0x332e3235, 0x00313131,
1375     0x0200001f, 0x80000005, 0x90070000, 0x0200001f, 0x90000000, 0xa00f0800, /* shader                        */
1376     0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x98000000, 0xa00f0802,
1377     0x0200001f, 0xa0000000, 0xa00f0803, 0x0200001f, 0x90000000, 0xa00f0804,
1378     0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
1379     0x80e40000, 0xa0e40000, 0x03000042, 0x800f0001, 0x90550000, 0xa0e40800,
1380     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
1381     0x90e40000, 0xa0e40803, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001,
1382     0x03000042, 0x800f0001, 0x90e40000, 0xa0e40804, 0x03000002, 0x800f0000,
1383     0x80e40000, 0x80e40001, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801,
1384     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
1385     0x90e40000, 0xa0e40802, 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001,
1386     0x0000ffff,                                                             /* END                           */
1387 };
1388
1389 static void test_get_shader_samplers(void)
1390 {
1391     LPCSTR samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */
1392     LPCSTR sampler_orig;
1393     UINT count = 2;
1394     HRESULT hr;
1395
1396 #if 0
1397     /* crashes if bytecode is NULL */
1398     hr = D3DXGetShaderSamplers(NULL, NULL, &count);
1399     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1400 #endif
1401
1402     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, NULL);
1403     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1404
1405     samplers[5] = "dummy";
1406
1407     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL);
1408     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1409
1410     /* check that sampler points to shader blob */
1411     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
1412     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
1413
1414     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
1415     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
1416
1417     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
1418     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
1419
1420     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
1421     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
1422
1423     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
1424     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
1425
1426     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
1427
1428     /* reset samplers */
1429     memset(samplers, 0, sizeof(samplers));
1430     samplers[5] = "dummy";
1431
1432     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, &count);
1433     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1434     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
1435
1436     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, &count);
1437     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1438     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
1439
1440     /* check that sampler points to shader blob */
1441     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
1442     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
1443
1444     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
1445     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
1446
1447     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
1448     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
1449
1450     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
1451     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
1452
1453     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
1454     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
1455
1456     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
1457
1458     /* check without ctab */
1459     hr = D3DXGetShaderSamplers(simple_vs, samplers, &count);
1460     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1461     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
1462
1463     /* check invalid ctab */
1464     hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count);
1465     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1466     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
1467 }
1468
1469 START_TEST(shader)
1470 {
1471     test_get_shader_size();
1472     test_get_shader_version();
1473     test_find_shader_comment();
1474     test_get_shader_constant_table_ex();
1475     test_constant_tables();
1476     test_setting_constants();
1477     test_get_sampler_index();
1478     test_get_shader_samplers();
1479 }