d3dx9_36/tests: Remove variable scaling which is not really used from D3DXMatrixTest.
[wine] / dlls / d3dx9_36 / tests / asm.c
1 /*
2  * Copyright (C) 2008 Stefan Dösinger
3  * Copyright (C) 2009 Matteo Bruni
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 #define COBJMACROS
20 #include "wine/test.h"
21
22 #include <d3dx9.h>
23
24 #include "resources.h"
25
26 struct shader_test {
27     const char *text;
28     const DWORD bytes[128];
29 };
30
31 static HRESULT create_file(const char *filename, const char *data, const unsigned int size)
32 {
33     DWORD received;
34     HANDLE hfile;
35
36     hfile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
37     if(hfile == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError());
38
39     if(WriteFile(hfile, data, size, &received, NULL))
40     {
41         CloseHandle(hfile);
42         return D3D_OK;
43     }
44
45     CloseHandle(hfile);
46     return D3DERR_INVALIDCALL;
47 }
48
49 static void dump_shader(DWORD *shader) {
50     unsigned int i = 0, j = 0;
51     do {
52         trace("0x%08x ", shader[i]);
53         j++;
54         i++;
55         if(j == 6) trace("\n");
56     } while(shader[i - 1] != D3DSIO_END);
57     if(j != 6) trace("\n");
58 }
59
60 static void exec_tests(const char *name, struct shader_test tests[], unsigned int count) {
61     HRESULT hr;
62     DWORD *res;
63     unsigned int i, j;
64     BOOL diff;
65     LPD3DXBUFFER shader, messages;
66
67     for(i = 0; i < count; i++) {
68         /* D3DXAssembleShader sets messages to 0 if there aren't error messages */
69         messages = NULL;
70         hr = D3DXAssembleShader(tests[i].text, strlen(tests[i].text),
71                                 NULL, NULL, D3DXSHADER_SKIPVALIDATION,
72                                 &shader, &messages);
73         ok(hr == D3D_OK, "Test %s, shader %d: D3DXAssembleShader failed with error 0x%x - %d\n", name, i, hr, hr & 0x0000FFFF);
74         if(messages) {
75             trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
76             ID3DXBuffer_Release(messages);
77         }
78         if(FAILED(hr)) continue;
79
80         j = 0;
81         diff = FALSE;
82         res = ID3DXBuffer_GetBufferPointer(shader);
83         while(res[j] != D3DSIO_END && tests[i].bytes[j] != D3DSIO_END) {
84             if(res[j] != tests[i].bytes[j]) diff = TRUE;
85             j++;
86         };
87         /* Both must have an end token */
88         if(res[j] != tests[i].bytes[j]) diff = TRUE;
89
90         if(diff) {
91             ok(FALSE, "Test %s, shader %d: Generated code differs\n", name, i);
92             dump_shader(res);
93         }
94         ID3DXBuffer_Release(shader);
95     }
96 }
97
98 static void preproc_test(void) {
99     struct shader_test tests[] = {
100         {   /* shader 0 */
101             "vs.1.1\r\n"
102             "//some comments\r\n"
103             "//other comments\n"
104             "; yet another comment\r\n"
105             "add r0, r0, r1\n",
106             {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
107         },
108         {   /* shader 1 */
109             "#line 1 \"vertex.vsh\"\n"
110             "vs.1.1\n",
111             {0xfffe0101, 0x0000ffff}
112         },
113         {   /* shader 2 */
114             "#define REG 1 + 2 +\\\n"
115             "3 + 4\n"
116             "vs.1.1\n"
117             "mov r0, c0[ REG ]\n",
118             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4000a, 0x0000ffff}
119         },
120     };
121
122     exec_tests("preproc", tests, sizeof(tests) / sizeof(tests[0]));
123 }
124
125 static void ps_1_1_test(void) {
126     struct shader_test tests[] = {
127         {   /* shader 0 */
128             "ps.1.1\r\n"
129             "tex t0\r\n"
130             "add r0.rgb, r0, r1\r\n"
131             "+mov r0.a, t0\r\n",
132             {0xffff0101, 0x00000042, 0xb00f0000, 0x00000002, 0x80070000, 0x80e40000,
133              0x80e40001, 0x40000001, 0x80080000, 0xb0e40000, 0x0000ffff}
134         },
135     };
136
137     exec_tests("ps_1_1", tests, sizeof(tests) / sizeof(tests[0]));
138 }
139
140 static void vs_1_1_test(void) {
141     struct shader_test tests[] = {
142         /* Basic instruction tests */
143         {   /* shader 0 */
144             "vs_1_1\n"
145             "add r0, r1, r2\n",
146             {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
147         },
148         {   /* shader 1 */
149             "vs_1_1\n"
150             "nop\n",
151             {0xfffe0101, 0x00000000, 0x0000ffff}
152         },
153         /* Output register tests */
154         {   /* shader 2 */
155             "vs_1_1\n"
156             "mov oPos, c0\n",
157             {0xfffe0101, 0x00000001, 0xc00f0000, 0xa0e40000, 0x0000ffff}
158         },
159         {   /* shader 3 */
160             "vs_1_1\n"
161             "mov oT0, c0\n",
162             {0xfffe0101, 0x00000001, 0xe00f0000, 0xa0e40000, 0x0000ffff}
163         },
164         {   /* shader 4 */
165             "vs_1_1\n"
166             "mov oT5, c0\n",
167             {0xfffe0101, 0x00000001, 0xe00f0005, 0xa0e40000, 0x0000ffff}
168         },
169         {   /* shader 5 */
170             "vs_1_1\n"
171             "mov oD0, c0\n",
172             {0xfffe0101, 0x00000001, 0xd00f0000, 0xa0e40000, 0x0000ffff}
173         },
174         {   /* shader 6 */
175             "vs_1_1\n"
176             "mov oD1, c0\n",
177             {0xfffe0101, 0x00000001, 0xd00f0001, 0xa0e40000, 0x0000ffff}
178         },
179         {   /* shader 7 */
180             "vs_1_1\n"
181             "mov oFog, c0.x\n",
182             {0xfffe0101, 0x00000001, 0xc00f0001, 0xa0000000, 0x0000ffff}
183         },
184         {   /* shader 8 */
185             "vs_1_1\n"
186             "mov oPts, c0.x\n",
187             {0xfffe0101, 0x00000001, 0xc00f0002, 0xa0000000, 0x0000ffff}
188         },
189         /* A bunch of tests for declarations */
190         {   /* shader 9 */
191             "vs_1_1\n"
192             "dcl_position0 v0",
193             {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000ffff}
194         },
195         {   /* shader 10 */
196             "vs_1_1\n"
197             "dcl_position v1",
198             {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0001, 0x0000ffff}
199         },
200         {   /* shader 11 */
201             "vs_1_1\n"
202             "dcl_normal12 v15",
203             {0xfffe0101, 0x0000001f, 0x800c0003, 0x900f000f, 0x0000ffff}
204         },
205         {   /* shader 12 */
206             "vs_1_1\n"
207             "add r0, v0, v1\n",
208             {0xfffe0101, 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, 0x0000ffff}
209         },
210         {   /* shader 13 */
211             "vs_1_1\n"
212             "def c12, 0, -1, -0.5, 1024\n",
213             {0xfffe0101, 0x00000051, 0xa00f000c, 0x00000000, 0xbf800000, 0xbf000000,
214              0x44800000, 0x0000ffff}
215         },
216         {   /* shader 14: writemasks, swizzles */
217             "vs_1_1\n"
218             "dp4 r0.xw, r1.wzyx, r2.xxww\n",
219             {0xfffe0101, 0x00000009, 0x80090000, 0x801b0001, 0x80f00002, 0x0000ffff}
220         },
221         {   /* shader 15: negation input modifier. Other modifiers not supprted in vs_1_1 */
222             "vs_1_1\n"
223             "add r0, -r0.x, -r1\n",
224             {0xfffe0101, 0x00000002, 0x800f0000, 0x81000000, 0x81e40001, 0x0000ffff}
225         },
226         {   /* shader 16: relative addressing */
227             "vs_1_1\n"
228             "mov r0, c0[a0.x]\n",
229             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42000, 0x0000ffff}
230         },
231         {   /* shader 17: relative addressing */
232             "vs_1_1\n"
233             "mov r0, c1[a0.x + 2]\n",
234             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42003, 0x0000ffff}
235         },
236         {   /* shader 18 */
237             "vs_1_1\n"
238             "def c0, 1.0f, 1.0f, 1.0f, 0.5f\n",
239             {0xfffe0101, 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000,
240              0x3f000000, 0x0000ffff}
241         },
242         /* Other relative addressing tests */
243         {   /* shader 19 */
244             "vs_1_1\n"
245             "mov r0, c[ a0.x + 12 ]\n",
246             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200c, 0x0000ffff}
247         },
248         {   /* shader 20 */
249             "vs_1_1\n"
250             "mov r0, c[ 2 + a0.x ]\n",
251             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42002, 0x0000ffff}
252         },
253         {   /* shader 21 */
254             "vs_1_1\n"
255             "mov r0, c[ 2 + a0.x + 12 ]\n",
256             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200e, 0x0000ffff}
257         },
258         {   /* shader 22 */
259             "vs_1_1\n"
260             "mov r0, c[ 2 + 10 + 12 ]\n",
261             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40018, 0x0000ffff}
262         },
263         {   /* shader 23 */
264             "vs_1_1\n"
265             "mov r0, c4[ 2 ]\n",
266             {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40006, 0x0000ffff}
267         },
268         {   /* shader 24 */
269             "vs_1_1\n"
270             "rcp r0, v0.x\n",
271             {0xfffe0101, 0x00000006, 0x800f0000, 0x90000000, 0x0000ffff}
272         },
273         {   /* shader 25 */
274             "vs_1_1\n"
275             "rsq r0, v0.x\n",
276             {0xfffe0101, 0x00000007, 0x800f0000, 0x90000000, 0x0000ffff}
277         },
278     };
279
280     exec_tests("vs_1_1", tests, sizeof(tests) / sizeof(tests[0]));
281 }
282
283 static void ps_1_3_test(void) {
284     struct shader_test tests[] = {
285         /* Basic instruction tests */
286         {   /* shader 0 */
287             "ps_1_3\n"
288             "mov r0, r1\n",
289             {0xffff0103, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff}
290         },
291         {   /* shader 1 */
292             "ps_1_3\n"
293             "add r0, r1, r0\n",
294             {0xffff0103, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40000, 0x0000ffff}
295         },
296         /* Color interpolator tests */
297         {   /* shader 2 */
298             "ps_1_3\n"
299             "mov r0, v0\n",
300             {0xffff0103, 0x00000001, 0x800f0000, 0x90e40000, 0x0000ffff}
301         },
302         {   /* shader 3 */
303             "ps_1_3\n"
304             "mov r0, v1\n",
305             {0xffff0103, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff}
306         },
307         /* Texture sampling instructions */
308         {   /* shader 4 */
309             "ps_1_3\n"
310             "tex t0\n",
311             {0xffff0103, 0x00000042, 0xb00f0000, 0x0000ffff}
312         },
313         {   /* shader 5 */
314             "ps_1_3\n"
315             "tex t0\n"
316             "texreg2ar t1, t0\n",
317             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000045, 0xb00f0001, 0xb0e40000,
318              0x0000ffff}
319         },
320         {   /* shader 6 */
321             "ps_1_3\n"
322             "tex t0\n"
323             "texreg2gb t1, t0\n",
324             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000046, 0xb00f0001, 0xb0e40000,
325              0x0000ffff}
326         },
327         {   /* shader 7 */
328             "ps_1_3\n"
329             "tex t0\n"
330             "texreg2rgb t1, t0\n",
331             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000052, 0xb00f0001, 0xb0e40000,
332              0x0000ffff}
333         },
334         {   /* shader 8 */
335             "ps_1_3\n"
336             "cnd r0, r1, r0, v0\n",
337             {0xffff0103, 0x00000050, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000,
338              0x0000ffff}
339         },
340         {   /* shader 9 */
341             "ps_1_3\n"
342             "cmp r0, r1, r0, v0\n",
343             {0xffff0103, 0x00000058, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000,
344              0x0000ffff}
345         },
346         {   /* shader 10 */
347             "ps_1_3\n"
348             "texkill t0\n",
349             {0xffff0103, 0x00000041, 0xb00f0000, 0x0000ffff}
350         },
351         {   /* shader 11 */
352             "ps_1_3\n"
353             "tex t0\n"
354             "texm3x2pad t1, t0\n"
355             "texm3x2tex t2, t0\n",
356             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000,
357              0x00000048, 0xb00f0002, 0xb0e40000, 0x0000ffff}
358         },
359         {   /* shader 12 */
360             "ps_1_3\n"
361             "tex t0\n"
362             "texm3x2pad t1, t0\n"
363             "texm3x2depth t2, t0\n",
364             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000,
365              0x00000054, 0xb00f0002, 0xb0e40000, 0x0000ffff}
366         },
367         {   /* shader 13 */
368             "ps_1_3\n"
369             "tex t0\n"
370             "texbem t1, t0\n",
371             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000043, 0xb00f0001, 0xb0e40000,
372              0x0000ffff}
373         },
374         {   /* shader 14 */
375             "ps_1_3\n"
376             "tex t0\n"
377             "texbeml t1, t0\n",
378             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000044, 0xb00f0001, 0xb0e40000,
379              0x0000ffff}
380         },
381         {   /* shader 15 */
382             "ps_1_3\n"
383             "tex t0\n"
384             "texdp3tex t1, t0\n",
385             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000053, 0xb00f0001, 0xb0e40000,
386              0x0000ffff}
387         },
388         {   /* shader 16 */
389             "ps_1_3\n"
390             "tex t0\n"
391             "texdp3 t1, t0\n",
392             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000055, 0xb00f0001, 0xb0e40000,
393              0x0000ffff}
394         },
395         {   /* shader 17 */
396             "ps_1_3\n"
397             "tex t0\n"
398             "texm3x3pad t1, t0\n"
399             "texm3x3pad t2, t0\n"
400             "texm3x3tex t3, t0\n",
401             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000,
402              0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004a, 0xb00f0003, 0xb0e40000,
403              0x0000ffff}
404         },
405         {   /* shader 18 */
406             "ps_1_3\n"
407             "tex t0\n"
408             "texm3x3pad t1, t0\n"
409             "texm3x3pad t2, t0\n"
410             "texm3x3 t3, t0\n",
411             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000,
412              0x00000049, 0xb00f0002, 0xb0e40000, 0x00000056, 0xb00f0003, 0xb0e40000,
413              0x0000ffff}
414         },
415         {   /* shader 19 */
416             "ps_1_3\n"
417             "tex t0\n"
418             "texm3x3pad t1, t0\n"
419             "texm3x3pad t2, t0\n"
420             "texm3x3spec t3, t0, c0\n",
421             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000,
422              0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004c, 0xb00f0003, 0xb0e40000,
423              0xa0e40000, 0x0000ffff}
424         },
425         {   /* shader 20 */
426             "ps_1_3\n"
427             "tex t0\n"
428             "texm3x3pad t1, t0\n"
429             "texm3x3pad t2, t0\n"
430             "texm3x3vspec t3, t0\n",
431             {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000,
432              0x00000049, 0xb00f0002, 0xb0e40000, 0x0000004d, 0xb00f0003, 0xb0e40000,
433              0x0000ffff}
434         },
435         {   /* shader 21 */
436             "ps_1_3\n"
437             "texcoord t0\n",
438             {0xffff0103, 0x00000040, 0xb00f0000, 0x0000ffff}
439         },
440         /* Modifiers, shifts */
441         {   /* shader 22 */
442             "ps_1_3\n"
443             "mov_x2_sat r0, 1 - r1\n",
444             {0xffff0103, 0x00000001, 0x811f0000, 0x86e40001, 0x0000ffff}
445         },
446         {   /* shader 23 */
447             "ps_1_3\n"
448             "mov_d8 r0, -r1\n",
449             {0xffff0103, 0x00000001, 0x8d0f0000, 0x81e40001, 0x0000ffff}
450         },
451         {   /* shader 24 */
452             "ps_1_3\n"
453             "mov_sat r0, r1_bx2\n",
454             {0xffff0103, 0x00000001, 0x801f0000, 0x84e40001, 0x0000ffff}
455         },
456         {   /* shader 25 */
457             "ps_1_3\n"
458             "mov_sat r0, r1_bias\n",
459             {0xffff0103, 0x00000001, 0x801f0000, 0x82e40001, 0x0000ffff}
460         },
461         {   /* shader 26 */
462             "ps_1_3\n"
463             "mov_sat r0, -r1_bias\n",
464             {0xffff0103, 0x00000001, 0x801f0000, 0x83e40001, 0x0000ffff}
465         },
466         {   /* shader 27 */
467             "ps_1_3\n"
468             "mov_sat r0, -r1_bx2\n",
469             {0xffff0103, 0x00000001, 0x801f0000, 0x85e40001, 0x0000ffff}
470         },
471         {   /* shader 28 */
472             "ps_1_3\n"
473             "mov_sat r0, -r1_x2\n",
474             {0xffff0103, 0x00000001, 0x801f0000, 0x88e40001, 0x0000ffff}
475         },
476         {   /* shader 29 */
477             "ps_1_3\n"
478             "mov_x4_sat r0.a, -r1_bx2.a\n",
479             {0xffff0103, 0x00000001, 0x82180000, 0x85ff0001, 0x0000ffff}
480         },
481     };
482
483     exec_tests("ps_1_3", tests, sizeof(tests) / sizeof(tests[0]));
484 }
485
486 static void ps_1_4_test(void) {
487     struct shader_test tests[] = {
488         /* Basic instruction tests */
489         {   /* shader 0 */
490             "ps_1_4\n"
491             "mov r0, r1\n",
492             {0xffff0104, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff}
493         },
494         {   /* shader 1 */
495             "ps_1_4\n"
496             "mov r0, r5\n",
497             {0xffff0104, 0x00000001, 0x800f0000, 0x80e40005, 0x0000ffff}
498         },
499         {   /* shader 2 */
500             "ps_1_4\n"
501             "mov r0, c7\n",
502             {0xffff0104, 0x00000001, 0x800f0000, 0xa0e40007, 0x0000ffff}
503         },
504         {   /* shader 3 */
505             "ps_1_4\n"
506             "mov r0, v1\n",
507             {0xffff0104, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff}
508         },
509         {   /* shader 4 */
510             "ps_1_4\n"
511             "phase\n",
512             {0xffff0104, 0x0000fffd, 0x0000ffff}
513         },
514         {   /* shader 5 */
515             "ps_1_4\n"
516             "texcrd r0, t0\n",
517             {0xffff0104, 0x00000040, 0x800f0000, 0xb0e40000, 0x0000ffff}
518         },
519         {   /* shader 6 */
520             "ps_1_4\n"
521             "texcrd r4, t3\n",
522             {0xffff0104, 0x00000040, 0x800f0004, 0xb0e40003, 0x0000ffff}
523         },
524         {   /* shader 7 */
525             "ps_1_4\n"
526             "texcrd_sat r4, t3\n",
527             {0xffff0104, 0x00000040, 0x801f0004, 0xb0e40003, 0x0000ffff}
528         },
529         {   /* shader 8 */
530             "ps_1_4\n"
531             "texld r0, t0\n",
532             {0xffff0104, 0x00000042, 0x800f0000, 0xb0e40000, 0x0000ffff}
533         },
534         {   /* shader 9 */
535             "ps_1_4\n"
536             "texld r1, t4\n",
537             {0xffff0104, 0x00000042, 0x800f0001, 0xb0e40004, 0x0000ffff}
538         },
539         {   /* shader 10 */
540             "ps_1_4\n"
541             "texld r5, r0\n",
542             {0xffff0104, 0x00000042, 0x800f0005, 0x80e40000, 0x0000ffff}
543         },
544         {   /* shader 11 */
545             "ps_1_4\n"
546             "texld r5, c0\n", /* Assembly succeeds, validation fails */
547             {0xffff0104, 0x00000042, 0x800f0005, 0xa0e40000, 0x0000ffff}
548         },
549         {   /* shader 12 */
550             "ps_1_4\n"
551             "texld r5, r2_dz\n",
552             {0xffff0104, 0x00000042, 0x800f0005, 0x89e40002, 0x0000ffff}
553         },
554         {   /* shader 13 */
555             "ps_1_4\n"
556             "bem r1.rg, c0, r0\n",
557             {0xffff0104, 0x00000059, 0x80030001, 0xa0e40000, 0x80e40000, 0x0000ffff}
558         },
559         {   /* shader 14 */
560             "ps_1_4\n"
561             "texdepth r5\n",
562             {0xffff0104, 0x00000057, 0x800f0005, 0x0000ffff}
563         },
564     };
565
566     exec_tests("ps_1_4", tests, sizeof(tests) / sizeof(tests[0]));
567 }
568
569 static void vs_2_0_test(void) {
570     struct shader_test tests[] = {
571         /* Basic instruction tests */
572         {   /* shader 0 */
573             "vs_2_0\n"
574             "mov r0, r1\n",
575             {0xfffe0200, 0x02000001, 0x800f0000, 0x80e40001, 0x0000ffff}
576         },
577         {   /* shader 1 */
578             "vs_2_0\n"
579             "lrp r0, v0, c0, r1\n",
580             {0xfffe0200, 0x04000012, 0x800f0000, 0x90e40000, 0xa0e40000, 0x80e40001,
581              0x0000ffff}
582         },
583         {   /* shader 2 */
584             "vs_2_0\n"
585             "dp4 oPos, v0, c0\n",
586             {0xfffe0200, 0x03000009, 0xc00f0000, 0x90e40000, 0xa0e40000, 0x0000ffff}
587         },
588         {   /* shader 3 */
589             "vs_2_0\n"
590             "mov r0, c0[a0.x]\n",
591             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0000000, 0x0000ffff}
592         },
593         {   /* shader 4 */
594             "vs_2_0\n"
595             "mov r0, c0[a0.y]\n",
596             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0550000, 0x0000ffff}
597         },
598         {   /* shader 5 */
599             "vs_2_0\n"
600             "mov r0, c0[a0.z]\n",
601             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0aa0000, 0x0000ffff}
602         },
603         {   /* shader 6 */
604             "vs_2_0\n"
605             "mov r0, c0[a0.w]\n",
606             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0ff0000, 0x0000ffff}
607         },
608         {   /* shader 7 */
609             "vs_2_0\n"
610             "mov r0, c0[a0.w].x\n",
611             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0002000, 0xb0ff0000, 0x0000ffff}
612         },
613         {   /* shader 8 */
614             "vs_2_0\n"
615             "mov r0, -c0[a0.w+5].x\n",
616             {0xfffe0200, 0x03000001, 0x800f0000, 0xa1002005, 0xb0ff0000, 0x0000ffff}
617         },
618         {   /* shader 9 */
619             "vs_2_0\n"
620             "mov r0, c0[a0]\n",
621             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0e40000, 0x0000ffff}
622         },
623         {   /* shader 10 */
624             "vs_2_0\n"
625             "mov r0, c0[a0.xyww]\n",
626             {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0f40000, 0x0000ffff}
627         },
628         {   /* shader 11 */
629             "vs_2_0\n"
630             "add r0, c0[a0.x], c1[a0.y]\n", /* validation would fail on this line */
631             {0xfffe0200, 0x05000002, 0x800f0000, 0xa0e42000, 0xb0000000, 0xa0e42001,
632              0xb0550000, 0x0000ffff}
633         },
634         {   /* shader 12 */
635             "vs_2_0\n"
636             "rep i0\n"
637             "endrep\n",
638             {0xfffe0200, 0x01000026, 0xf0e40000, 0x00000027, 0x0000ffff}
639         },
640         {   /* shader 13 */
641             "vs_2_0\n"
642             "if b0\n"
643             "else\n"
644             "endif\n",
645             {0xfffe0200, 0x01000028, 0xe0e40800, 0x0000002a, 0x0000002b, 0x0000ffff}
646         },
647         {   /* shader 14 */
648             "vs_2_0\n"
649             "loop aL, i0\n"
650             "endloop\n",
651             {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x0000001d, 0x0000ffff}
652         },
653         {   /* shader 15 */
654             "vs_2_0\n"
655             "nrm r0, c0\n",
656             {0xfffe0200, 0x02000024, 0x800f0000, 0xa0e40000, 0x0000ffff}
657         },
658         {   /* shader 16 */
659             "vs_2_0\n"
660             "crs r0, r1, r2\n",
661             {0xfffe0200, 0x03000021, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
662         },
663         {   /* shader 17 */
664             "vs_2_0\n"
665             "sgn r0, r1, r2, r3\n",
666             {0xfffe0200, 0x04000022, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003,
667              0x0000ffff}
668         },
669         {   /* shader 18 */
670             "vs_2_0\n"
671             "sincos r0, r1, r2, r3\n",
672             {0xfffe0200, 0x04000025, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003,
673              0x0000ffff}
674         },
675         {   /* shader 19 */
676             "vs_2_0\n"
677             "pow r0, r1, r2\n",
678             {0xfffe0200, 0x03000020, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
679         },
680         {   /* shader 20 */
681             "vs_2_0\n"
682             "mova a0.y, c0.z\n",
683             {0xfffe0200, 0x0200002e, 0xb0020000, 0xa0aa0000, 0x0000ffff}
684         },
685         {   /* shader 21 */
686             "vs_2_0\n"
687             "defb b0, true\n"
688             "defb b1, false\n",
689             {0xfffe0200, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801,
690              0x00000000, 0x0000ffff}
691         },
692         {   /* shader 22 */
693             "vs_2_0\n"
694             "defi i0, -1, 1, 10, 0\n"
695             "defi i1, 0, 40, 30, 10\n",
696             {0xfffe0200, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a,
697              0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e,
698              0x0000000a, 0x0000ffff}
699         },
700         {   /* shader 23 */
701             "vs_2_0\n"
702             "loop aL, i0\n"
703             "mov r0, c0[aL]\n"
704             "endloop\n",
705             {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000,
706              0xa0e42000, 0xf0e40800, 0x0000001d, 0x0000ffff}
707         },
708         {   /* shader 24 */
709             "vs_2_0\n"
710             "call l0\n"
711             "ret\n"
712             "label l0\n"
713             "ret\n",
714             {0xfffe0200, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000,
715              0x0000001c, 0x0000ffff}
716         },
717         {   /* shader 25 */
718             "vs_2_0\n"
719             "callnz l0, b0\n"
720             "ret\n"
721             "label l0\n"
722             "ret\n",
723             {0xfffe0200, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e,
724              0xa0e41000, 0x0000001c, 0x0000ffff}
725         },
726         {   /* shader 26 */
727             "vs_2_0\n"
728             "callnz l0, !b0\n"
729             "ret\n"
730             "label l0\n"
731             "ret\n",
732             {0xfffe0200, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e,
733              0xa0e41000, 0x0000001c, 0x0000ffff}
734         },
735         {   /* shader 27 */
736             "vs_2_0\n"
737             "if !b0\n"
738             "else\n"
739             "endif\n",
740             {0xfffe0200, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff}
741         },
742     };
743
744     exec_tests("vs_2_0", tests, sizeof(tests) / sizeof(tests[0]));
745 }
746
747 static void vs_2_x_test(void) {
748     struct shader_test tests[] = {
749         {   /* shader 0 */
750             "vs_2_x\n"
751             "rep i0\n"
752             "break\n"
753             "endrep\n",
754             {0xfffe0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff}
755         },
756         {   /* shader 1 */
757             "vs_2_x\n"
758             "if_ge r0, r1\n"
759             "endif\n",
760             {0xfffe0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff}
761         },
762         {   /* shader 2 */
763             "vs_2_x\n"
764             "rep i0\n"
765             "break_ne r0, r1\n"
766             "endrep",
767             {0xfffe0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001,
768              0x00000027, 0x0000ffff}
769         },
770
771         /* predicates */
772         {   /* shader 3 */
773             "vs_2_x\n"
774             "setp_gt p0, r0, r1\n"
775             "(!p0) add r2, r2, r3\n",
776             {0xfffe0201, 0x0301005e, 0xb00f1000, 0x80e40000, 0x80e40001, 0x14000002,
777              0x800f0002, 0xbde41000, 0x80e40002, 0x80e40003, 0x0000ffff}
778         },
779         {   /* shader 4 */
780             "vs_2_x\n"
781             "if p0.x\n"
782             "else\n"
783             "endif\n",
784             {0xfffe0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff}
785         },
786         {   /* shader 5 */
787             "vs_2_x\n"
788             "callnz l0, !p0.z\n"
789             "ret\n"
790             "label l0\n"
791             "ret\n",
792             {0xfffe0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c,
793              0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff}
794         },
795         {   /* shader 6 */
796             "vs_2_x\n"
797             "rep i0\n"
798             "breakp p0.w\n"
799             "endrep\n",
800             {0xfffe0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000,
801              0x00000027, 0x0000ffff}
802         },
803     };
804
805     exec_tests("vs_2_x", tests, sizeof(tests) / sizeof(tests[0]));
806 }
807
808 static void ps_2_0_test(void) {
809     struct shader_test tests[] = {
810         {   /* shader 0 */
811             "ps_2_0\n"
812             "dcl_2d s0\n",
813             {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
814         },
815         {   /* shader 1 */
816             "ps_2_0\n"
817             "dcl_cube s0\n",
818             {0xffff0200, 0x0200001f, 0x98000000, 0xa00f0800, 0x0000ffff}
819         },
820         {   /* shader 2 */
821             "ps_2_0\n"
822             "dcl_volume s0\n",
823             {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0000ffff}
824         },
825         {   /* shader 3 */
826             "ps_2_0\n"
827             "dcl_volume s0\n"
828             "dcl_cube s1\n"
829             "dcl_2d s2\n",
830             {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0200001f, 0x98000000,
831              0xa00f0801, 0x0200001f, 0x90000000, 0xa00f0802, 0x0000ffff}
832         },
833         {   /* shader 4 */
834             "ps_2_0\n"
835             "mov r0, t0\n",
836             {0xffff0200, 0x02000001, 0x800f0000, 0xb0e40000, 0x0000ffff}
837         },
838         {   /* shader 5 */
839             "ps_2_0\n"
840             "dcl_2d s2\n"
841             "texld r0, t1, s2\n",
842             {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000,
843              0xb0e40001, 0xa0e40802, 0x0000ffff}
844         },
845         {   /* shader 6 */
846             "ps_2_0\n"
847             "texkill t0\n",
848             {0xffff0200, 0x01000041, 0xb00f0000, 0x0000ffff}
849         },
850         {   /* shader 7 */
851             "ps_2_0\n"
852             "mov oC0, c0\n"
853             "mov oC1, c1\n",
854             {0xffff0200, 0x02000001, 0x800f0800, 0xa0e40000, 0x02000001, 0x800f0801,
855              0xa0e40001, 0x0000ffff}
856         },
857         {   /* shader 8 */
858             "ps_2_0\n"
859             "mov oDepth, c0.x\n",
860             {0xffff0200, 0x02000001, 0x900f0800, 0xa0000000, 0x0000ffff}
861         },
862         {   /* shader 9 */
863             "ps_2_0\n"
864             "dcl_2d s2\n"
865             "texldp r0, t1, s2\n",
866             {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03010042, 0x800f0000,
867              0xb0e40001, 0xa0e40802, 0x0000ffff}
868         },
869         {   /* shader 10 */
870             "ps_2_0\n"
871             "dcl_2d s2\n"
872             "texldb r0, t1, s2\n",
873             {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03020042, 0x800f0000,
874              0xb0e40001, 0xa0e40802, 0x0000ffff}
875         },
876     };
877
878     exec_tests("ps_2_0", tests, sizeof(tests) / sizeof(tests[0]));
879 }
880
881 static void ps_2_x_test(void) {
882     struct shader_test tests[] = {
883         /* defb and defi are not supposed to work in ps_2_0 (even if defb actually works in ps_2_0 with native) */
884         {   /* shader 0 */
885             "ps_2_x\n"
886             "defb b0, true\n"
887             "defb b1, false\n",
888             {0xffff0201, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801,
889              0x00000000, 0x0000ffff}
890         },
891         {   /* shader 1 */
892             "ps_2_x\n"
893             "defi i0, -1, 1, 10, 0\n"
894             "defi i1, 0, 40, 30, 10\n",
895             {0xffff0201, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a,
896              0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e,
897              0x0000000a, 0x0000ffff}
898         },
899         {   /* shader 2 */
900             "ps_2_x\n"
901             "dsx r0, r0\n",
902             {0xffff0201, 0x0200005b, 0x800f0000, 0x80e40000, 0x0000ffff}
903         },
904         {   /* shader 3 */
905             "ps_2_x\n"
906             "dsy r0, r0\n",
907             {0xffff0201, 0x0200005c, 0x800f0000, 0x80e40000, 0x0000ffff}
908         },
909         {   /* shader 4 */
910             "ps_2_x\n"
911             "dcl_2d s2\n"
912             "texldd r0, v1, s2, r3, r4\n",
913             {0xffff0201, 0x0200001f, 0x90000000, 0xa00f0802, 0x0500005d, 0x800f0000,
914              0x90e40001, 0xa0e40802, 0x80e40003, 0x80e40004, 0x0000ffff}
915         },
916         /* Static flow control tests */
917         {   /* shader 5 */
918             "ps_2_x\n"
919             "call l0\n"
920             "ret\n"
921             "label l0\n"
922             "ret\n",
923             {0xffff0201, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000,
924              0x0000001c, 0x0000ffff}
925         },
926         {   /* shader 6 */
927             "ps_2_x\n"
928             "callnz l0, b0\n"
929             "ret\n"
930             "label l0\n"
931             "ret\n",
932             {0xffff0201, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e,
933              0xa0e41000, 0x0000001c, 0x0000ffff}
934         },
935         {   /* shader 7 */
936             "ps_2_x\n"
937             "callnz l0, !b0\n"
938             "ret\n"
939             "label l0\n"
940             "ret\n",
941             {0xffff0201, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e,
942              0xa0e41000, 0x0000001c, 0x0000ffff}
943         },
944         {   /* shader 8 */
945             "ps_2_x\n"
946             "if !b0\n"
947             "else\n"
948             "endif\n",
949             {0xffff0201, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff}
950         },
951         /* Dynamic flow control tests */
952         {   /* shader 9 */
953             "ps_2_x\n"
954             "rep i0\n"
955             "break\n"
956             "endrep\n",
957             {0xffff0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff}
958         },
959         {   /* shader 10 */
960             "ps_2_x\n"
961             "if_ge r0, r1\n"
962             "endif\n",
963             {0xffff0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff}
964         },
965         {   /* shader 11 */
966             "ps_2_x\n"
967             "rep i0\n"
968             "break_ne r0, r1\n"
969             "endrep",
970             {0xffff0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001,
971              0x00000027, 0x0000ffff}
972         },
973         /* Predicates */
974         {   /* shader 12 */
975             "ps_2_x\n"
976             "setp_gt p0, r0, r1\n"
977             "(!p0) add r2, r2, r3\n",
978             {0xffff0201, 0x0301005e, 0xb00f1000, 0x80e40000, 0x80e40001, 0x14000002,
979              0x800f0002, 0xbde41000, 0x80e40002, 0x80e40003, 0x0000ffff}
980         },
981         {   /* shader 13 */
982             "ps_2_x\n"
983             "if p0.x\n"
984             "else\n"
985             "endif\n",
986             {0xffff0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff}
987         },
988         {   /* shader 14 */
989             "ps_2_x\n"
990             "callnz l0, !p0.z\n"
991             "ret\n"
992             "label l0\n"
993             "ret\n",
994             {0xffff0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c,
995              0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff}
996         },
997         {   /* shader 15 */
998             "ps_2_x\n"
999             "rep i0\n"
1000             "breakp p0.w\n"
1001             "endrep\n",
1002             {0xffff0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000,
1003              0x00000027, 0x0000ffff}
1004         },
1005     };
1006
1007     exec_tests("ps_2_x", tests, sizeof(tests) / sizeof(tests[0]));
1008 }
1009
1010 static void vs_3_0_test(void) {
1011     /* FIXME: Some tests are temporarily commented out, because the
1012        current implementation doesn't support the entire vs_3_0 syntax
1013        and it is not trivial to remove todo_wine only from
1014        a subset of the tests here */
1015     struct shader_test tests[] = {
1016         {   /* shader 0 */
1017             "vs_3_0\n"
1018             "mov r0, c0\n",
1019             {0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
1020         },
1021 /*      {*/ /* shader 1 */
1022 /*          "vs_3_0\n"
1023             "dcl_2d s0\n",
1024             {0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
1025         },*/
1026 /*      {*/ /* shader 2 */
1027 /*          "vs_3_0\n"
1028             "dcl_position o0\n",
1029             {0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
1030         },*/
1031 /*      {*/ /* shader 3 */
1032 /*          "vs_3_0\n"
1033             "dcl_texcoord12 o11\n",
1034             {0xfffe0300, 0x0200001f, 0x800c0005, 0xe00f000b, 0x0000ffff}
1035         },*/
1036         {   /* shader 4 */
1037             "vs_3_0\n"
1038             "texldl r0, v0, s0\n",
1039             {0xfffe0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
1040         },
1041         {   /* shader 5 */
1042             "vs_3_0\n"
1043             "mov r0, c0[aL]\n",
1044             {0xfffe0300, 0x03000001, 0x800f0000, 0xa0e42000, 0xf0e40800, 0x0000ffff}
1045         },
1046         {   /* shader 6 */
1047             "vs_3_0\n"
1048             "mov o[ a0.x + 12 ], r0\n",
1049             {0xfffe0300, 0x03000001, 0xe00f200c, 0xb0000000, 0x80e40000, 0x0000ffff}
1050         },
1051         {   /* shader 7 */
1052             "vs_3_0\n"
1053             "add_sat r0, r0, r1\n",
1054             {0xfffe0300, 0x03000002, 0x801f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
1055         },
1056         {   /* shader 8 */
1057             "vs_3_0\n"
1058             "mov r2, r1_abs\n",
1059             {0xfffe0300, 0x02000001, 0x800f0002, 0x8be40001, 0x0000ffff}
1060         },
1061         {   /* shader 9 */
1062             "vs_3_0\n"
1063             "mov r2, r1.xygb\n",
1064             {0xfffe0300, 0x02000001, 0x800f0002, 0x80940001, 0x0000ffff}
1065         },
1066         {   /* shader 10 */
1067             "vs_3_0\n"
1068             "mov r2.xyb, r1\n",
1069             {0xfffe0300, 0x02000001, 0x80070002, 0x80e40001, 0x0000ffff}
1070         },
1071         {   /* shader 11 */
1072             "vs_3_0\n"
1073             "mova_sat a0.x, r1\n",
1074             {0xfffe0300, 0x0200002e, 0xb0110000, 0x80e40001, 0x0000ffff}
1075         },
1076         {   /* shader 12 */
1077             "vs_3_0\n"
1078             "sincos r0, r1\n",
1079             {0xfffe0300, 0x02000025, 0x800f0000, 0x80e40001, 0x0000ffff}
1080         },
1081     };
1082
1083     exec_tests("vs_3_0", tests, sizeof(tests) / sizeof(tests[0]));
1084 }
1085
1086 static void ps_3_0_test(void) {
1087     struct shader_test tests[] = {
1088         {   /* shader 0 */
1089             "ps_3_0\n"
1090             "mov r0, c0\n",
1091             {0xffff0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
1092         },
1093         {   /* shader 1 */
1094             "ps_3_0\n"
1095             "dcl_normal5 v0\n",
1096             {0xffff0300, 0x0200001f, 0x80050003, 0x900f0000, 0x0000ffff}
1097         },
1098         {   /* shader 2 */
1099             "ps_3_0\n"
1100             "mov r0, vPos\n",
1101             {0xffff0300, 0x02000001, 0x800f0000, 0x90e41000, 0x0000ffff}
1102         },
1103         {   /* shader 3 */
1104             "ps_3_0\n"
1105             "mov r0, vFace\n",
1106             {0xffff0300, 0x02000001, 0x800f0000, 0x90e41001, 0x0000ffff}
1107         },
1108         {   /* shader 4 */
1109             "ps_3_0\n"
1110             "mov r0, v[ aL + 12 ]\n",
1111             {0xffff0300, 0x03000001, 0x800f0000, 0x90e4200c, 0xf0e40800, 0x0000ffff}
1112         },
1113         {   /* shader 5 */
1114             "ps_3_0\n"
1115             "loop aL, i0\n"
1116             "mov r0, v0[aL]\n"
1117             "endloop\n",
1118             {0xffff0300, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000,
1119              0x90e42000, 0xf0e40800, 0x0000001d, 0x0000ffff}
1120         },
1121         {   /* shader 6 */
1122             "ps_3_0\n"
1123             "texldl r0, v0, s0\n",
1124             {0xffff0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
1125         },
1126     };
1127
1128     exec_tests("ps_3_0", tests, sizeof(tests) / sizeof(tests[0]));
1129 }
1130
1131 static void failure_test(void) {
1132     const char * tests[] = {
1133         /* shader 0: instruction modifier not allowed */
1134         "ps_3_0\n"
1135         "dcl_2d s2\n"
1136         "texldd_x2 r0, v1, s2, v3, v4\n",
1137         /* shader 1: coissue not supported in vertex shaders */
1138         "vs.1.1\r\n"
1139         "add r0.rgb, r0, r1\n"
1140         "+add r0.a, r0, r2\n",
1141         /* shader 2: coissue not supported in pixel shader version >= 2.0 */
1142         "ps_2_0\n"
1143         "texld r0, t0, s0\n"
1144         "add r0.rgb, r0, r1\n"
1145         "+add r0.a, r0, v1\n",
1146         /* shader 3: predicates not supported in vertex shader < 2.0 */
1147         "vs_1_1\n"
1148         "(p0) add r0, r0, v0\n",
1149         /* shader 4: register a0 doesn't exist in pixel shaders */
1150         "ps_3_0\n"
1151         "mov r0, v[ a0 + 12 ]\n",
1152         /* shader 5: s0 doesn't exist in vs_1_1 */
1153         "vs_1_1\n"
1154         "mov r0, s0\n",
1155         /* shader 6: aL is a scalar register, no swizzles allowed */
1156         "ps_3_0\n"
1157         "mov r0, v[ aL.x + 12 ]\n",
1158         /* shader 7: tn doesn't exist in ps_3_0 */
1159         "ps_3_0\n"
1160         "dcl_2d s2\n"
1161         "texldd r0, t1, s2, v3, v4\n",
1162         /* shader 8: two shift modifiers */
1163         "ps_1_3\n"
1164         "mov_x2_x2 r0, r1\n",
1165         /* shader 9: too many source registers for mov instruction */
1166         "vs_1_1\n"
1167         "mov r0, r1, r2\n",
1168         /* shader 10: invalid combination of negate and divide modifiers */
1169         "ps_1_4\n"
1170         "texld r5, -r2_dz\n",
1171         /* shader 11: complement modifier not allowed in >= PS 2 */
1172         "ps_2_0\n"
1173         "mov r2, 1 - r0\n",
1174         /* shader 12: invalid modifier */
1175         "vs_3_0\n"
1176         "mov r2, 2 - r0\n",
1177         /* shader 13: float value in relative addressing */
1178         "vs_3_0\n"
1179         "mov r2, c[ aL + 3.4 ]\n",
1180         /* shader 14: complement modifier not available in VS */
1181         "vs_3_0\n"
1182         "mov r2, 1 - r1\n",
1183         /* shader 15: _x2 modifier not available in VS */
1184         "vs_1_1\n"
1185         "mov r2, r1_x2\n",
1186         /* shader 16: _abs modifier not available in < VS 3.0 */
1187         "vs_1_1\n"
1188         "mov r2, r1_abs\n",
1189         /* shader 17: _x2 modifier not available in >= PS 2.0 */
1190         "ps_2_0\n"
1191         "mov r0, r1_x2\n",
1192         /* shader 18: wrong swizzle */
1193         "vs_2_0\n"
1194         "mov r0, r1.abcd\n",
1195         /* shader 19: wrong swizzle */
1196         "vs_2_0\n"
1197         "mov r0, r1.xyzwx\n",
1198         /* shader 20: wrong swizzle */
1199         "vs_2_0\n"
1200         "mov r0, r1.\n",
1201         /* shader 21: invalid writemask */
1202         "vs_2_0\n"
1203         "mov r0.xxyz, r1\n",
1204         /* shader 22: register r5 doesn't exist in PS < 1.4 */
1205         "ps_1_3\n"
1206         "mov r5, r0\n",
1207     };
1208     HRESULT hr;
1209     unsigned int i;
1210     LPD3DXBUFFER shader,messages;
1211
1212     for(i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
1213         shader = NULL;
1214         messages = NULL;
1215         hr = D3DXAssembleShader(tests[i], strlen(tests[i]),
1216                                 NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1217                                 &shader, &messages);
1218         ok(hr == D3DXERR_INVALIDDATA, "Failure test, shader %d: "
1219            "expected D3DXAssembleShader failure with D3DXERR_INVALIDDATA, "
1220            "got 0x%x - %d\n", i, hr, hr & 0x0000FFFF);
1221         if(messages) {
1222             trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1223             ID3DXBuffer_Release(messages);
1224         }
1225         if(shader) {
1226             DWORD *res = ID3DXBuffer_GetBufferPointer(shader);
1227             dump_shader(res);
1228             ID3DXBuffer_Release(shader);
1229         }
1230     }
1231 }
1232
1233
1234 static HRESULT WINAPI testD3DXInclude_open(ID3DXInclude *iface,
1235                                            D3DXINCLUDE_TYPE include_type,
1236                                            LPCSTR filename, LPCVOID parent_data,
1237                                            LPCVOID *data, UINT *bytes) {
1238     char *buffer;
1239     char include[] = "#define REGISTER r0\nvs.1.1\n";
1240
1241     trace("filename = %s\n",filename);
1242
1243     buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include));
1244     CopyMemory(buffer, include, sizeof(include));
1245     *data = buffer;
1246     *bytes = sizeof(include);
1247     return S_OK;
1248 }
1249
1250 static HRESULT WINAPI testD3DXInclude_close(ID3DXInclude *iface, LPCVOID data) {
1251     HeapFree(GetProcessHeap(), 0, (LPVOID)data);
1252     return S_OK;
1253 }
1254
1255 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = {
1256     testD3DXInclude_open,
1257     testD3DXInclude_close
1258 };
1259
1260 struct D3DXIncludeImpl {
1261     const ID3DXIncludeVtbl *lpVtbl;
1262 };
1263
1264 static void assembleshader_test(void) {
1265     const char test1[] = {
1266         "vs.1.1\n"
1267         "mov DEF2, v0\n"
1268     };
1269     const char testincl[] = {
1270         "#define REGISTER r0\n"
1271         "vs.1.1\n"
1272     };
1273     const char testshader[] = {
1274         "#include \"incl.vsh\"\n"
1275         "mov REGISTER, v0\n"
1276     };
1277     HRESULT hr;
1278     LPD3DXBUFFER shader, messages;
1279     D3DXMACRO defines[] = {
1280         {
1281             "DEF1", "10 + 15"
1282         },
1283         {
1284             "DEF2", "r0"
1285         },
1286         {
1287             NULL, NULL
1288         }
1289     };
1290     struct D3DXIncludeImpl include;
1291     HRESULT shader_vsh_res, incl_vsh_res;
1292
1293     todo_wine {
1294
1295     /* pDefines test */
1296     shader = NULL;
1297     messages = NULL;
1298     hr = D3DXAssembleShader(test1, strlen(test1),
1299                             defines, NULL, D3DXSHADER_SKIPVALIDATION,
1300                             &shader, &messages);
1301     ok(hr == D3D_OK, "pDefines test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1302     if(messages) {
1303         trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1304         ID3DXBuffer_Release(messages);
1305     }
1306     if(shader) ID3DXBuffer_Release(shader);
1307
1308     /* pInclude test */
1309     shader = NULL;
1310     messages = NULL;
1311     include.lpVtbl = &D3DXInclude_Vtbl;
1312     hr = D3DXAssembleShader(testshader, strlen(testshader),
1313                             NULL, (LPD3DXINCLUDE)&include, D3DXSHADER_SKIPVALIDATION,
1314                             &shader, &messages);
1315     ok(hr == D3D_OK, "pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1316     if(messages) {
1317         trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1318         ID3DXBuffer_Release(messages);
1319     }
1320     if(shader) ID3DXBuffer_Release(shader);
1321
1322     shader_vsh_res = create_file("shader.vsh", testshader, sizeof(testshader));
1323     if(SUCCEEDED(shader_vsh_res)) {
1324         incl_vsh_res = create_file("incl.vsh", testincl, sizeof(testincl));
1325         if(SUCCEEDED(incl_vsh_res)) {
1326             /* D3DXAssembleShaderFromFile + #include test */
1327             shader = NULL;
1328             messages = NULL;
1329             hr = D3DXAssembleShaderFromFileA("shader.vsh",
1330                                              NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1331                                              &shader, &messages);
1332             ok(hr == D3D_OK, "D3DXAssembleShaderFromFile test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1333             if(messages) {
1334                 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1335                 ID3DXBuffer_Release(messages);
1336             }
1337             if(shader) ID3DXBuffer_Release(shader);
1338         } else skip("Couldn't create \"incl.vsh\"\n");
1339
1340         /* D3DXAssembleShaderFromFile + pInclude test */
1341         shader = NULL;
1342         messages = NULL;
1343         hr = D3DXAssembleShaderFromFileA("shader.vsh",
1344                                          NULL, (LPD3DXINCLUDE)&include, D3DXSHADER_SKIPVALIDATION,
1345                                          &shader, &messages);
1346         ok(hr == D3D_OK, "D3DXAssembleShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1347         if(messages) {
1348             trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1349             ID3DXBuffer_Release(messages);
1350         }
1351         if(shader) ID3DXBuffer_Release(shader);
1352     } else skip("Couldn't create \"shader.vsh\"\n");
1353
1354     } /* todo_wine */
1355
1356     /* NULL shader tests */
1357     shader = NULL;
1358     messages = NULL;
1359     hr = D3DXAssembleShader(NULL, 0,
1360                             NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1361                             &shader, &messages);
1362     ok(hr == D3DXERR_INVALIDDATA, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1363     if(messages) {
1364         trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1365         ID3DXBuffer_Release(messages);
1366     }
1367     if(shader) ID3DXBuffer_Release(shader);
1368
1369     todo_wine {
1370
1371     shader = NULL;
1372     messages = NULL;
1373     hr = D3DXAssembleShaderFromFileA("nonexistent.vsh",
1374                                      NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1375                                      &shader, &messages);
1376     ok(hr == D3DXERR_INVALIDDATA || hr == E_FAIL, /* I get this on WinXP */
1377         "D3DXAssembleShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
1378         hr, hr & 0x0000FFFF);
1379     if(messages) {
1380         trace("D3DXAssembleShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1381         ID3DXBuffer_Release(messages);
1382     }
1383     if(shader) ID3DXBuffer_Release(shader);
1384
1385     /* D3DXAssembleShaderFromResource test */
1386     shader = NULL;
1387     messages = NULL;
1388     hr = D3DXAssembleShaderFromResourceA(NULL, MAKEINTRESOURCEA(IDB_ASMSHADER),
1389                                          NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1390                                          &shader, &messages);
1391     ok(hr == D3D_OK, "D3DXAssembleShaderFromResource test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1392     if(messages) {
1393         trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1394         ID3DXBuffer_Release(messages);
1395     }
1396     if(shader) ID3DXBuffer_Release(shader);
1397
1398     } /* end of todo_wine */
1399
1400     /* D3DXAssembleShaderFromResource with missing shader resource test */
1401     shader = NULL;
1402     messages = NULL;
1403     hr = D3DXAssembleShaderFromResourceA(NULL, "notexisting",
1404                                          NULL, NULL, D3DXSHADER_SKIPVALIDATION,
1405                                          &shader, &messages);
1406     ok(hr == D3DXERR_INVALIDDATA, "D3DXAssembleShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
1407     if(messages) {
1408         trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
1409         ID3DXBuffer_Release(messages);
1410     }
1411     if(shader) ID3DXBuffer_Release(shader);
1412
1413     /* cleanup */
1414     if(SUCCEEDED(shader_vsh_res)) {
1415         DeleteFileA("shader.vsh");
1416         if(SUCCEEDED(incl_vsh_res)) DeleteFileA("incl.vsh");
1417     }
1418 }
1419
1420 START_TEST(asm)
1421 {
1422     todo_wine preproc_test();
1423     todo_wine ps_1_1_test();
1424     todo_wine vs_1_1_test();
1425     todo_wine ps_1_3_test();
1426     todo_wine ps_1_4_test();
1427     todo_wine vs_2_0_test();
1428     todo_wine vs_2_x_test();
1429     todo_wine ps_2_0_test();
1430     todo_wine ps_2_x_test();
1431     vs_3_0_test();
1432     todo_wine ps_3_0_test();
1433
1434     failure_test();
1435
1436     assembleshader_test();
1437 }