d3dx9: Implement ID3DXConstantTable::SetMatrixPointerArray.
[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     static const D3DXMATRIX *matrix_pointer[] = {&mvp};
573
574     ID3DXConstantTable *ctable;
575
576     HRESULT res;
577     float out[16];
578     ULONG refcnt;
579
580     /* Get the constant table from the shader itself */
581     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
582     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
583
584     /* Set constants */
585     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
586     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res);
587
588     res = ID3DXConstantTable_SetInt(ctable, device, "i", i + 1);
589     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
590
591     /* Check that setting i again will overwrite the previous value */
592     res = ID3DXConstantTable_SetInt(ctable, device, "i", i);
593     ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
594
595     res = ID3DXConstantTable_SetFloat(ctable, device, "f", f);
596     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res);
597
598     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
599     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res);
600
601     /* Get constants back and validate */
602     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
603     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,
604             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
605             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
606     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,
607             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
608             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
609     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,
610             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
611             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
612     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,
613             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
614             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
615
616     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1);
617     ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
618             "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n",
619             out[0], out[1], out[2], out[3], i);
620
621     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
622     ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
623             "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n",
624             out[0], out[1], out[2], out[3], f);
625
626     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
627     ok(memcmp(out, &f4, sizeof(f4)) == 0,
628             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
629             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
630
631     /* Finally test using a set* function for one type to set a variable of another type (should succeed) */
632     res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4);
633     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
634
635     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
636     ok(out[0] == f4.x && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
637             "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n",
638             out[0], f4.x);
639
640     memset(out, 0, sizeof(out));
641     IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
642     res = ID3DXConstantTable_SetMatrix(ctable, device, "f", &mvp);
643     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable f: 0x%08x\n", res);
644
645     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
646     ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
647             "The variable f was not set correctly by ID3DXConstantTable_SetMatrix, got %f, should be %f\n",
648             out[0], U(S(mvp))._11);
649
650     /* Clear registers */
651     memset(out, 0, sizeof(out));
652     IDirect3DDevice9_SetVertexShaderConstantF(device, 0, out, 4);
653     IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
654     IDirect3DDevice9_SetVertexShaderConstantF(device, 7, out, 1);
655
656     /* SetVector shouldn't change the value of a matrix constant */
657     res = ID3DXConstantTable_SetVector(ctable, device, "mvp", &f4);
658     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
659
660     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
661     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
662             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
663             && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
664             && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
665             "The variable mvp was not set correctly by ID3DXConstantTable_SetVector, "
666             "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
667             "should be all 0.0f\n",
668             out[0], out[1], out[2], out[3],
669             out[4], out[5], out[6], out[7],
670             out[8], out[9], out[10], out[11],
671             out[12], out[13], out[14], out[15]);
672
673     res = ID3DXConstantTable_SetFloat(ctable, device, "mvp", f);
674     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable mvp: 0x%08x\n", res);
675
676     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
677     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
678             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
679             && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
680             && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
681             "The variable mvp was not set correctly by ID3DXConstantTable_SetFloat, "
682             "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
683             "should be all 0.0f\n",
684             out[0], out[1], out[2], out[3],
685             out[4], out[5], out[6], out[7],
686             out[8], out[9], out[10], out[11],
687             out[12], out[13], out[14], out[15]);
688
689     res = ID3DXConstantTable_SetFloat(ctable, device, "f4", f);
690     ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f4: 0x%08x\n", res);
691
692     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
693     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
694             "The variable f4 was not set correctly by ID3DXConstantTable_SetFloat, "
695             "got {%f, %f, %f, %f}, should be all 0.0f\n",
696             out[0], out[1], out[2], out[3]);
697
698     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f", &mvp);
699     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f: 0x%08x\n", res);
700
701     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
702     ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
703             "The variable f was not set correctly by ID3DXConstantTable_SetMatrixTranspose, got %f, should be %f\n",
704             out[0], U(S(mvp))._11);
705
706     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f4", &mvp);
707     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f4: 0x%08x\n", res);
708
709     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
710     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,
711             "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixTranspose, "
712             "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
713             out[0], out[1], out[2], out[3],
714             S(U(mvp))._11, S(U(mvp))._21, S(U(mvp))._31, S(U(mvp))._41);
715
716     memset(out, 0, sizeof(out));
717     IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
718     res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f", matrix_pointer, 1);
719     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f: got %#x\n", res);
720
721     IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
722     ok(out[0] == U(S(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
723             "The variable f was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, "
724             "got %f, should be %f\n",
725             out[0], U(S(mvp))._11);
726
727     res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f4", matrix_pointer, 1);
728     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f4: got %#x\n", res);
729
730     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
731     ok(out[0] == U(S(mvp))._11 && out[1] == U(S(mvp))._12 && out[2] == U(S(mvp))._13 && out[3] == U(S(mvp))._14,
732             "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, "
733             "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
734             out[0], out[1], out[2], out[3],
735             U(S(mvp))._11, U(S(mvp))._12, U(S(mvp))._13, U(S(mvp))._14);
736
737     refcnt = ID3DXConstantTable_Release(ctable);
738     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
739 }
740
741 static void test_setting_matrices_table(IDirect3DDevice9 *device)
742 {
743     static const D3DXMATRIX fmatrix =
744         {{{2.001f, 1.502f, 9.003f, 1.004f,
745            5.005f, 3.006f, 3.007f, 6.008f,
746            9.009f, 5.010f, 7.011f, 1.012f,
747            5.013f, 5.014f, 5.015f, 9.016f}}};
748     static const D3DXMATRIX *matrix_pointer[] = {&fmatrix};
749
750     ID3DXConstantTable *ctable;
751
752     HRESULT res;
753     float out[32];
754
755     res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
756     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
757
758     res = ID3DXConstantTable_SetMatrix(ctable, device, "imatrix2x3", &fmatrix);
759     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable fmatrix2x3: got %#x\n", res);
760
761     res = ID3DXConstantTable_SetMatrix(ctable, device, "fmatrix3x1", &fmatrix);
762     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable fmatrix3x1: got %#x\n", res);
763
764     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
765     todo_wine ok(out[0] == (int)S(U(fmatrix))._11 && out[1] == (int)S(U(fmatrix))._12 && out[2] == (int)S(U(fmatrix))._13
766             && out[3] == 0
767             && out[4] == (int)S(U(fmatrix))._21 && out[5] == (int)S(U(fmatrix))._22 && out[6] == (int)S(U(fmatrix))._23
768             && out[7] == 0,
769             "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
770             "should be {%d, %d, %d, %d; %d, %d, %d, %d}\n",
771             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
772             (int)S(U(fmatrix))._11, (int)S(U(fmatrix))._12, (int)S(U(fmatrix))._13, 0,
773             (int)S(U(fmatrix))._21, (int)S(U(fmatrix))._22, (int)S(U(fmatrix))._23, 0);
774
775     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
776     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f,
777             "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
778             out[0], out[1], out[2], out[3],
779             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f);
780
781     ID3DXConstantTable_Release(ctable);
782
783     res = D3DXGetShaderConstantTable(ctab_matrices2, &ctable);
784     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
785
786     /* SetMatrix */
787     res = ID3DXConstantTable_SetMatrix(ctable, device, "c2x3", &fmatrix);
788     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c2x3: got %#x\n", res);
789
790     res = ID3DXConstantTable_SetMatrix(ctable, device, "r2x3", &fmatrix);
791     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r2x3: got %#x\n", res);
792
793     res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x2", &fmatrix);
794     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x2: got %#x\n", res);
795
796     res = ID3DXConstantTable_SetMatrix(ctable, device, "r3x2", &fmatrix);
797     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r3x2: got %#x\n", res);
798
799     res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x3", &fmatrix);
800     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x3: got %#x\n", res);
801
802     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
803     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f
804             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
805             && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f,
806             "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
807             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
808             out[0], out[1], out[2], out[3],
809             out[4], out[5], out[6], out[7],
810             out[8], out[9], out[10], out[11],
811             S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f,
812             S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f,
813             S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f);
814
815     res = ID3DXConstantTable_SetMatrix(ctable, device, "r4x4", &fmatrix);
816     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r4x4: got %#x\n", res);
817
818     IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
819     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f
820             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f,
821             "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
822             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
823             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
824             S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f,
825             S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f);
826
827     IDirect3DDevice9_GetVertexShaderConstantF(device, 13, out, 2);
828     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
829             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
830             "The variable c3x2 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
831             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
832             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
833             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
834             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
835
836     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 3);
837     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
838             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
839             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
840             "The variable r3x2 was not set correctly, out={%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}\n",
842             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
843             S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
844             S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
845             S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
846
847     IDirect3DDevice9_GetVertexShaderConstantF(device, 10, out, 3);
848     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
849             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f
850             && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == S(U(fmatrix))._33 && out[11] == 0.0f,
851             "The variable c3x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
852             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
853             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
854             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
855             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f,
856             S(U(fmatrix))._13, S(U(fmatrix))._23, S(U(fmatrix))._33, 0.0f);
857
858     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
859     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
860             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == S(U(fmatrix))._24
861             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == S(U(fmatrix))._33 && out[11] == S(U(fmatrix))._34
862             && out[12] == S(U(fmatrix))._41 && out[13] == S(U(fmatrix))._42 && out[14] == S(U(fmatrix))._43 && out[15] == S(U(fmatrix))._44,
863             "The variable r4x4 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
864             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
865             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
866             out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
867             S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, S(U(fmatrix))._14,
868             S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, S(U(fmatrix))._24,
869             S(U(fmatrix))._31, S(U(fmatrix))._32, S(U(fmatrix))._33, S(U(fmatrix))._34,
870             S(U(fmatrix))._41, S(U(fmatrix))._42, S(U(fmatrix))._43, S(U(fmatrix))._44);
871
872     /* SetMatrixTranspose */
873     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "c2x3", &fmatrix);
874     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable c2x3: got %#x\n", res);
875
876     res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "r2x3", &fmatrix);
877     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable r2x3: got %#x\n", res);
878
879     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
880     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
881             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
882             && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
883             "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
884             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
885             out[0], out[1], out[2], out[3],
886             out[4], out[5], out[6], out[7],
887             out[8], out[9], out[10], out[11],
888             S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
889             S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
890             S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
891
892     IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
893     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
894             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
895             "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
896             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
897             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
898             S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
899             S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
900
901     /* SetMatrixPointerArray */
902     res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "c2x3", matrix_pointer, 1);
903     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable c2x3: got %#x\n", res);
904
905     res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "r2x3", matrix_pointer, 1);
906     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable r2x3: got %#x\n", res);
907
908     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
909     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f
910             && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
911             && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f,
912             "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
913             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
914             out[0], out[1], out[2], out[3],
915             out[4], out[5], out[6], out[7],
916             out[8], out[9], out[10], out[11],
917             S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f,
918             S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f,
919             S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f);
920
921     IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
922     ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f
923             && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f,
924             "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
925             "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
926             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
927             S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f,
928             S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f);
929
930     ID3DXConstantTable_Release(ctable);
931 }
932
933 static void test_setting_arrays_table(IDirect3DDevice9 *device)
934 {
935     static const float farray[8] = {
936         0.005f, 0.745f, 0.973f, 0.264f,
937         0.010f, 0.020f, 0.030f, 0.040f};
938     static const D3DXMATRIX fmtxarray[2] = {
939         {{{0.001f, 0.002f, 0.003f, 0.004f,
940            0.005f, 0.006f, 0.007f, 0.008f,
941            0.009f, 0.010f, 0.011f, 0.012f,
942            0.013f, 0.014f, 0.015f, 0.016f}}},
943         {{{0.010f, 0.020f, 0.030f, 0.040f,
944            0.050f, 0.060f, 0.070f, 0.080f,
945            0.090f, 0.100f, 0.110f, 0.120f,
946            0.130f, 0.140f, 0.150f, 0.160f}}}};
947     static const int iarray[4] = {1, 2, 3, 4};
948     static const D3DXVECTOR4 fvecarray[2] = {
949         {0.745f, 0.997f, 0.353f, 0.237f},
950         {0.060f, 0.455f, 0.333f, 0.983f}};
951     static BOOL barray[4] = {FALSE, 100, TRUE, TRUE};
952
953     ID3DXConstantTable *ctable;
954
955     HRESULT res;
956     float out[32];
957     ULONG refcnt;
958
959     /* Clear registers */
960     memset(out, 0, sizeof(out));
961     IDirect3DDevice9_SetVertexShaderConstantF(device,  8, out, 4);
962     IDirect3DDevice9_SetVertexShaderConstantF(device, 12, out, 4);
963
964     /* Get the constant table from the shader */
965     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
966     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
967
968     /* Set constants */
969
970     /* Make sure that we cannot set registers that do not belong to this constant */
971     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8);
972     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res);
973
974     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8);
975     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
976             "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
977             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
978     ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f,
979             "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n",
980             out[16], out[20], out[24], out[28]);
981
982     /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */
983     res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]);
984     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res);
985
986     IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4);
987     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
988        "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]);
989
990     /* Try setting an integer array to an array declared as a float array */
991     res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4);
992     ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res);
993
994     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
995     ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3],
996            "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n",
997             out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]);
998
999     res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4);
1000     ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res);
1001
1002     res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2);
1003     ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res);
1004
1005     res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2);
1006     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res);
1007
1008     res = ID3DXConstantTable_SetBoolArray(ctable, device, "barray", barray, 2);
1009     ok(res == D3D_OK, "ID3DXConstantTable_SetBoolArray failed: got 0x%08x\n", res);
1010
1011     /* Read back constants */
1012     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
1013     ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
1014             "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1015             out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
1016
1017     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
1018     ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w &&
1019             out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w,
1020             "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be "
1021             "{{%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],
1022             fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y,
1023             fvecarray[1].z, fvecarray[1].w);
1024
1025     IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
1026     ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
1027             && out[4] == 1.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
1028             "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",
1029             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1030             0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
1031
1032     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8);
1033     /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */
1034     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,
1035            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1036            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);
1037     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,
1038            "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1039            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);
1040
1041     refcnt = ID3DXConstantTable_Release(ctable);
1042     ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
1043 }
1044
1045 static void test_SetDefaults(IDirect3DDevice9 *device)
1046 {
1047     static const D3DXMATRIX mvp = {{{
1048         0.51f, 0.62f, 0.80f, 0.78f,
1049         0.23f, 0.95f, 0.37f, 0.48f,
1050         0.10f, 0.58f, 0.90f, 0.25f,
1051         0.89f, 0.41f, 0.93f, 0.27f}}};
1052     static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
1053
1054     float out[16];
1055
1056     HRESULT res;
1057     ID3DXConstantTable *ctable;
1058
1059     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
1060     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1061
1062     res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
1063     ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed: got %08x\n", res);
1064
1065     res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
1066     ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got %08x\n", res);
1067
1068     res = ID3DXConstantTable_SetDefaults(ctable, device);
1069     ok(res == D3D_OK, "ID3dXConstantTable_SetDefaults failed: got %08x\n", res);
1070
1071     /* SetDefaults doesn't change constants without default values */
1072     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1073     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,
1074             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1075             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
1076     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,
1077             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1078             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
1079     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,
1080             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1081             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
1082     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,
1083             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1084             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
1085
1086     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1087     ok(memcmp(out, &f4, sizeof(f4)) == 0,
1088             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1089             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
1090
1091     ID3DXConstantTable_Release(ctable);
1092
1093     res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
1094     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1095
1096     res = ID3DXConstantTable_SetDefaults(ctable, device);
1097     ok(res == D3D_OK, "ID3DXConstantTable_SetDefaults failed: got %08x\n", res);
1098
1099     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1100     ok(memcmp(out, mat4_default_value, sizeof(mat4_default_value)) == 0,
1101             "The variable mat4 was not set correctly to default value\n");
1102
1103     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 4);
1104     ok(memcmp(out, mat3_default_value, sizeof(mat3_default_value)) == 0,
1105             "The variable mat3 was not set correctly to default value\n");
1106
1107     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
1108     ok(memcmp(out, arr_default_value, sizeof(arr_default_value)) == 0,
1109         "The variable array was not set correctly to default value\n");
1110
1111     IDirect3DDevice9_GetVertexShaderConstantF(device, 11, out, 1);
1112     ok(memcmp(out, vec4_default_value, sizeof(vec4_default_value)) == 0,
1113         "The variable vec4 was not set correctly to default value\n");
1114
1115     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 1);
1116     ok(memcmp(out, flt_default_value, sizeof(flt_default_value)) == 0,
1117         "The variable flt was not set correctly to default value\n");
1118
1119     ID3DXConstantTable_Release(ctable);
1120 }
1121
1122 static void test_SetValue(IDirect3DDevice9 *device)
1123 {
1124     static const D3DXMATRIX mvp = {{{
1125         0.51f, 0.62f, 0.80f, 0.78f,
1126         0.23f, 0.95f, 0.37f, 0.48f,
1127         0.10f, 0.58f, 0.90f, 0.25f,
1128         0.89f, 0.41f, 0.93f, 0.27f}}};
1129     static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
1130     static const FLOAT arr[] = {0.33f, 0.55f, 0.96f, 1.00f,
1131                                 1.00f, 1.00f, 1.00f, 1.00f,
1132                                 1.00f, 1.00f, 1.00f, 1.00f};
1133     static int imatrix[] = {1, 2, 3, 4, 5, 6};
1134     static float fmatrix[] = {1.1f, 2.2f, 3.3f, 4.4f};
1135     static BOOL barray[] = {TRUE, FALSE};
1136     static float fvecarray[] = {9.1f, 9.2f, 9.3f, 9.4f, 9.5f, 9.6f, 9.7f, 9.8f};
1137     static float farray[] = {2.2f, 3.3f};
1138
1139     static const float def[16] = {5.5f, 5.5f, 5.5f, 5.5f,
1140                                   5.5f, 5.5f, 5.5f, 5.5f,
1141                                   5.5f, 5.5f, 5.5f, 5.5f,
1142                                   5.5f, 5.5f, 5.5f, 5.5f};
1143     float out[16];
1144
1145     HRESULT res;
1146     ID3DXConstantTable *ctable;
1147
1148     res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
1149     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1150
1151     IDirect3DDevice9_SetVertexShaderConstantF(device, 7, def, 1);
1152
1153     /* SetValue called with 0 bytes size doesn't change value */
1154     res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, 0);
1155     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1156
1157     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1158     ok(memcmp(out, def, sizeof(f4)) == 0,
1159             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1160             out[0], out[1], out[2], out[3], def[0], def[1], def[2], def[3]);
1161
1162     res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, sizeof(f4));
1163     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1164
1165     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
1166     ok(memcmp(out, &f4, sizeof(f4)) == 0,
1167             "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1168             out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
1169
1170     IDirect3DDevice9_SetVertexShaderConstantF(device, 0, def, 4);
1171
1172     /* SetValue called with size smaller than constant size doesn't change value */
1173     res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp) / 2);
1174     ok(res == D3D_OK, "ID3DXConstantTable_SetValue returned %08x\n", res);
1175
1176     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1177     ok(memcmp(out, def, sizeof(def)) == 0,
1178             "The variable mvp was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
1179             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
1180             out[0], out[4], out[ 8], out[12],
1181             out[1], out[5], out[ 9], out[13],
1182             out[2], out[6], out[10], out[14],
1183             out[3], out[7], out[11], out[15],
1184             def[0], def[4], def[ 8], def[12],
1185             def[1], def[5], def[ 9], def[13],
1186             def[2], def[6], def[10], def[14],
1187             def[3], def[7], def[11], def[15]);
1188
1189     res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp));
1190     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1191
1192     IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
1193     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,
1194             "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1195             out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
1196     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,
1197             "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1198             out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
1199     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,
1200             "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1201             out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
1202     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,
1203             "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1204             out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
1205
1206     ID3DXConstantTable_Release(ctable);
1207
1208     res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
1209     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1210
1211     res = ID3DXConstantTable_SetValue(ctable, device, "arr", arr, sizeof(arr));
1212     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1213
1214     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
1215     ok(out[0] == arr[0] && out[4] == arr[1] && out[8] == arr[2]
1216             && out[1] == 0 &&  out[2] == 0 && out[3] == 0 && out[5] == 0 && out[6] == 0 && out[7] == 0
1217             && out[9] == 0 && out[10] == 0 && out[11] == 0,
1218             "The variable arr was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f}, "
1219             "should be {0.33, 0, 0, 0, 0.55, 0, 0, 0, 0.96, 0, 0, 0}\n",
1220             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11]);
1221
1222     ID3DXConstantTable_Release(ctable);
1223
1224     res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
1225     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1226
1227     res = ID3DXConstantTable_SetValue(ctable, device, "fmatrix3x1", fmatrix, sizeof(fmatrix));
1228     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1229
1230     res = ID3DXConstantTable_SetValue(ctable, device, "imatrix2x3", imatrix, sizeof(imatrix));
1231     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1232
1233     IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
1234     ok(out[0] == imatrix[0] && out[1] == imatrix[1] && out[2] == imatrix[2] && out[3] == 0.0f
1235             && out[4] == imatrix[3] && out[5] == imatrix[4] && out[6] == imatrix[5] && out[7] == 0.0f,
1236             "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
1237             "should be {%d, %d, %d, 0, %d, %d, %d, 0}\n",
1238             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1239             imatrix[0], imatrix[1], imatrix[2], imatrix[3], imatrix[4], imatrix[5]);
1240
1241     IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 2);
1242     ok(out[0] == fmatrix[0] && out[1] == fmatrix[1] && out[2] == fmatrix[2] && out[3] == 0.0f,
1243             "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
1244             out[0], out[1] ,out[2], out[4],
1245             fmatrix[0], fmatrix[1], fmatrix[2], 0.0f);
1246
1247     ID3DXConstantTable_Release(ctable);
1248
1249     res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
1250     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
1251
1252     res = ID3DXConstantTable_SetValue(ctable, device, "barray", barray, sizeof(barray));
1253     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1254
1255     res = ID3DXConstantTable_SetValue(ctable, device, "fvecarray", fvecarray, sizeof(fvecarray));
1256     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1257
1258     IDirect3DDevice9_SetVertexShaderConstantF(device, 8, def, 4);
1259     res = ID3DXConstantTable_SetValue(ctable, device, "farray", farray, sizeof(farray));
1260     ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
1261
1262     /* 2 elements of farray were set */
1263     IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
1264     ok(out[0] == farray[0] && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
1265             && out[4] == farray[1] && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
1266             && out[8] == def[8] && out[9] == def[9] && out[10] == def[10] && out[11] == def[11]
1267             && out[12] == def[12] && out[13] == def[13] && out[14] == def[14] && out[15] == def[15],
1268             "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}, "
1269             "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
1270             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1271             out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
1272             farray[0], 0.0f, 0.0f, 0.0f,
1273             farray[1], 0.0f, 0.0f, 0.0f,
1274             def[8], def[9], def[10], def[11],
1275             def[12], def[13], def[14], def[15]);
1276
1277     IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
1278     ok(out[0] == fvecarray[0] && out[1] == fvecarray[1] && out[2] == fvecarray[2] && out[3] == fvecarray[3]
1279             && out[4] == fvecarray[4] && out[5] == fvecarray[5] && out[6] == fvecarray[6] && out[7] == fvecarray[7],
1280             "The variable fvecarray was not set correctly, out ={%f, %f, %f, %f, %f, %f, %f, %f}, "
1281             "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
1282             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1283             fvecarray[0], fvecarray[1], fvecarray[2], fvecarray[3], fvecarray[4], fvecarray[5], fvecarray[6], fvecarray[7]);
1284
1285     IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
1286     ok(out[0] == 1.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
1287             && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
1288             "The variable barray was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
1289             "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
1290             out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
1291             1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
1292
1293     ID3DXConstantTable_Release(ctable);
1294 }
1295
1296 static void test_setting_constants(void)
1297 {
1298     HWND wnd;
1299     IDirect3D9 *d3d;
1300     IDirect3DDevice9 *device;
1301     D3DPRESENT_PARAMETERS d3dpp;
1302     HRESULT hr;
1303     ULONG refcnt;
1304
1305     /* Create the device to use for our tests */
1306     wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1307     d3d = Direct3DCreate9(D3D_SDK_VERSION);
1308     if (!wnd)
1309     {
1310         skip("Couldn't create application window\n");
1311         return;
1312     }
1313     if (!d3d)
1314     {
1315         skip("Couldn't create IDirect3D9 object\n");
1316         DestroyWindow(wnd);
1317         return;
1318     }
1319
1320     ZeroMemory(&d3dpp, sizeof(d3dpp));
1321     d3dpp.Windowed   = TRUE;
1322     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1323     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
1324     if (FAILED(hr))
1325     {
1326         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
1327         IDirect3D9_Release(d3d);
1328         DestroyWindow(wnd);
1329         return;
1330     }
1331
1332     test_setting_basic_table(device);
1333     test_setting_matrices_table(device);
1334     test_setting_arrays_table(device);
1335     test_SetDefaults(device);
1336     test_SetValue(device);
1337
1338     /* Release resources */
1339     refcnt = IDirect3DDevice9_Release(device);
1340     ok(refcnt == 0, "The Direct3D device reference count was %u, should be 0\n", refcnt);
1341
1342     refcnt = IDirect3D9_Release(d3d);
1343     ok(refcnt == 0, "The Direct3D object referenct count was %u, should be 0\n", refcnt);
1344
1345     if (wnd) DestroyWindow(wnd);
1346 }
1347
1348 static void test_get_sampler_index(void)
1349 {
1350     ID3DXConstantTable *ctable;
1351
1352     HRESULT res;
1353     UINT index;
1354
1355     ULONG refcnt;
1356
1357     res = D3DXGetShaderConstantTable(ctab_samplers, &ctable);
1358     ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res);
1359
1360     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1");
1361     ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index);
1362
1363     index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2");
1364     ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index);
1365
1366     index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent");
1367     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n",
1368             index);
1369
1370     index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler");
1371     ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n",
1372             index);
1373
1374     refcnt = ID3DXConstantTable_Release(ctable);
1375     ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt);
1376 }
1377
1378 /*
1379  * fxc.exe /Tps_3_0
1380  */
1381 #if 0
1382 sampler s;
1383 sampler1D s1D;
1384 sampler2D s2D;
1385 sampler3D s3D;
1386 samplerCUBE scube;
1387 float4 init;
1388 float4 main(float3 tex : TEXCOORD0) : COLOR
1389 {
1390     float4 tmp = init;
1391     tmp = tmp + tex1D(s1D, tex.x);
1392     tmp = tmp + tex1D(s1D, tex.y);
1393     tmp = tmp + tex3D(s3D, tex.xyz);
1394     tmp = tmp + tex1D(s, tex.x);
1395     tmp = tmp + tex2D(s2D, tex.xy);
1396     tmp = tmp + texCUBE(scube, tex.xyz);
1397     return tmp;
1398 }
1399 #endif
1400 static const DWORD get_shader_samplers_blob[] =
1401 {
1402     0xffff0300,                                                             /* ps_3_0                        */
1403     0x0054fffe, FCC_CTAB,                                                   /* CTAB comment                  */
1404     0x0000001c, 0x0000011b, 0xffff0300, 0x00000006, 0x0000001c, 0x00000100, /* Header                        */
1405     0x00000114,
1406     0x00000094, 0x00000002, 0x00000001, 0x0000009c, 0x00000000,             /* Constant 1 desc (init)        */
1407     0x000000ac, 0x00040003, 0x00000001, 0x000000b0, 0x00000000,             /* Constant 2 desc (s)           */
1408     0x000000c0, 0x00000003, 0x00000001, 0x000000c4, 0x00000000,             /* Constant 3 desc (s1D)         */
1409     0x000000d4, 0x00010003, 0x00000001, 0x000000d8, 0x00000000,             /* Constant 4 desc (s2D)         */
1410     0x000000e8, 0x00030003, 0x00000001, 0x000000ec, 0x00000000,             /* Constant 5 desc (s3D)         */
1411     0x000000fc, 0x00020003, 0x00000001, 0x00000104, 0x00000000,             /* Constant 6 desc (scube)       */
1412     0x74696e69, 0xababab00,                                                 /* Constant 1 name               */
1413     0x00030001, 0x00040001, 0x00000001, 0x00000000,                         /* Constant 1 type desc          */
1414     0xabab0073,                                                             /* Constant 2 name               */
1415     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 2 type desc          */
1416     0x00443173,                                                             /* Constant 3 name               */
1417     0x000b0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 3 type desc          */
1418     0x00443273,                                                             /* Constant 4 name               */
1419     0x000c0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 4 type desc          */
1420     0x00443373,                                                             /* Constant 5 name               */
1421     0x000d0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 5 type desc          */
1422     0x62756373, 0xabab0065,                                                 /* Constant 6 name               */
1423     0x000e0004, 0x00010001, 0x00000001, 0x00000000,                         /* Constant 6 type desc          */
1424     0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, /* Target/Creator name string    */
1425     0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
1426     0x332e3235, 0x00313131,
1427     0x0200001f, 0x80000005, 0x90070000, 0x0200001f, 0x90000000, 0xa00f0800, /* shader                        */
1428     0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x98000000, 0xa00f0802,
1429     0x0200001f, 0xa0000000, 0xa00f0803, 0x0200001f, 0x90000000, 0xa00f0804,
1430     0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
1431     0x80e40000, 0xa0e40000, 0x03000042, 0x800f0001, 0x90550000, 0xa0e40800,
1432     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
1433     0x90e40000, 0xa0e40803, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001,
1434     0x03000042, 0x800f0001, 0x90e40000, 0xa0e40804, 0x03000002, 0x800f0000,
1435     0x80e40000, 0x80e40001, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801,
1436     0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
1437     0x90e40000, 0xa0e40802, 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001,
1438     0x0000ffff,                                                             /* END                           */
1439 };
1440
1441 static void test_get_shader_samplers(void)
1442 {
1443     LPCSTR samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */
1444     LPCSTR sampler_orig;
1445     UINT count = 2;
1446     HRESULT hr;
1447
1448 #if 0
1449     /* crashes if bytecode is NULL */
1450     hr = D3DXGetShaderSamplers(NULL, NULL, &count);
1451     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1452 #endif
1453
1454     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, NULL);
1455     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1456
1457     samplers[5] = "dummy";
1458
1459     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL);
1460     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1461
1462     /* check that sampler points to shader blob */
1463     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
1464     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
1465
1466     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
1467     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
1468
1469     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
1470     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
1471
1472     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
1473     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
1474
1475     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
1476     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
1477
1478     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
1479
1480     /* reset samplers */
1481     memset(samplers, 0, sizeof(samplers));
1482     samplers[5] = "dummy";
1483
1484     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, &count);
1485     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1486     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
1487
1488     hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, &count);
1489     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1490     ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
1491
1492     /* check that sampler points to shader blob */
1493     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x2E];
1494     ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
1495
1496     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x33];
1497     ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
1498
1499     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x38];
1500     ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
1501
1502     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x3D];
1503     ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
1504
1505     sampler_orig = (LPCSTR)&get_shader_samplers_blob[0x42];
1506     ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
1507
1508     ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
1509
1510     /* check without ctab */
1511     hr = D3DXGetShaderSamplers(simple_vs, samplers, &count);
1512     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1513     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
1514
1515     /* check invalid ctab */
1516     hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count);
1517     ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
1518     ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
1519 }
1520
1521 START_TEST(shader)
1522 {
1523     test_get_shader_size();
1524     test_get_shader_version();
1525     test_find_shader_comment();
1526     test_get_shader_constant_table_ex();
1527     test_constant_tables();
1528     test_setting_constants();
1529     test_get_sampler_index();
1530     test_get_shader_samplers();
1531 }