2 * Copyright (C) 2008 Stefan Dösinger
3 * Copyright (C) 2009 Matteo Bruni
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.
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.
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
20 #include "wine/test.h"
24 #include "resources.h"
28 const DWORD bytes
[128];
31 static HRESULT
create_file(const char *filename
, const char *data
, const unsigned int size
)
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());
39 if(WriteFile(hfile
, data
, size
, &received
, NULL
))
46 return D3DERR_INVALIDCALL
;
49 static void dump_shader(DWORD
*shader
) {
50 unsigned int i
= 0, j
= 0;
52 trace("0x%08x ", shader
[i
]);
55 if(j
== 6) trace("\n");
56 } while(shader
[i
- 1] != D3DSIO_END
);
57 if(j
!= 6) trace("\n");
60 static void exec_tests(const char *name
, struct shader_test tests
[], unsigned int count
) {
65 LPD3DXBUFFER shader
, messages
;
67 for(i
= 0; i
< count
; i
++) {
68 /* D3DXAssembleShader sets messages to 0 if there aren't error messages */
70 hr
= D3DXAssembleShader(tests
[i
].text
, strlen(tests
[i
].text
),
71 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
73 ok(hr
== D3D_OK
, "Test %s, shader %d: D3DXAssembleShader failed with error 0x%x - %d\n", name
, i
, hr
, hr
& 0x0000FFFF);
75 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
76 ID3DXBuffer_Release(messages
);
78 if(FAILED(hr
)) continue;
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
;
87 /* Both must have an end token */
88 if(res
[j
] != tests
[i
].bytes
[j
]) diff
= TRUE
;
91 ok(FALSE
, "Test %s, shader %d: Generated code differs\n", name
, i
);
94 ID3DXBuffer_Release(shader
);
98 static void preproc_test(void) {
99 struct shader_test tests
[] = {
102 "//some comments\r\n"
104 "; yet another comment\r\n"
106 {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
109 "#line 1 \"vertex.vsh\"\n"
111 {0xfffe0101, 0x0000ffff}
114 "#define REG 1 + 2 +\\\n"
117 "mov r0, c0[ REG ]\n",
118 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4000a, 0x0000ffff}
122 exec_tests("preproc", tests
, sizeof(tests
) / sizeof(tests
[0]));
125 static void ps_1_1_test(void) {
126 struct shader_test tests
[] = {
130 "add r0.rgb, r0, r1\r\n"
132 {0xffff0101, 0x00000042, 0xb00f0000, 0x00000002, 0x80070000, 0x80e40000,
133 0x80e40001, 0x40000001, 0x80080000, 0xb0e40000, 0x0000ffff}
137 exec_tests("ps_1_1", tests
, sizeof(tests
) / sizeof(tests
[0]));
140 static void vs_1_1_test(void) {
141 struct shader_test tests
[] = {
142 /* Basic instruction tests */
146 {0xfffe0101, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
151 {0xfffe0101, 0x00000000, 0x0000ffff}
153 /* Output register tests */
157 {0xfffe0101, 0x00000001, 0xc00f0000, 0xa0e40000, 0x0000ffff}
162 {0xfffe0101, 0x00000001, 0xe00f0000, 0xa0e40000, 0x0000ffff}
167 {0xfffe0101, 0x00000001, 0xe00f0005, 0xa0e40000, 0x0000ffff}
172 {0xfffe0101, 0x00000001, 0xd00f0000, 0xa0e40000, 0x0000ffff}
177 {0xfffe0101, 0x00000001, 0xd00f0001, 0xa0e40000, 0x0000ffff}
182 {0xfffe0101, 0x00000001, 0xc00f0001, 0xa0000000, 0x0000ffff}
187 {0xfffe0101, 0x00000001, 0xc00f0002, 0xa0000000, 0x0000ffff}
189 /* A bunch of tests for declarations */
193 {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000ffff}
198 {0xfffe0101, 0x0000001f, 0x80000000, 0x900f0001, 0x0000ffff}
203 {0xfffe0101, 0x0000001f, 0x800c0003, 0x900f000f, 0x0000ffff}
208 {0xfffe0101, 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, 0x0000ffff}
212 "def c12, 0, -1, -0.5, 1024\n",
213 {0xfffe0101, 0x00000051, 0xa00f000c, 0x00000000, 0xbf800000, 0xbf000000,
214 0x44800000, 0x0000ffff}
216 { /* shader 14: writemasks, swizzles */
218 "dp4 r0.xw, r1.wzyx, r2.xxww\n",
219 {0xfffe0101, 0x00000009, 0x80090000, 0x801b0001, 0x80f00002, 0x0000ffff}
221 { /* shader 15: negation input modifier. Other modifiers not supprted in vs_1_1 */
223 "add r0, -r0.x, -r1\n",
224 {0xfffe0101, 0x00000002, 0x800f0000, 0x81000000, 0x81e40001, 0x0000ffff}
226 { /* shader 16: relative addressing */
228 "mov r0, c0[a0.x]\n",
229 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42000, 0x0000ffff}
231 { /* shader 17: relative addressing */
233 "mov r0, c1[a0.x + 2]\n",
234 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42003, 0x0000ffff}
238 "def c0, 1.0f, 1.0f, 1.0f, 0.5f\n",
239 {0xfffe0101, 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000,
240 0x3f000000, 0x0000ffff}
242 /* Other relative addressing tests */
245 "mov r0, c[ a0.x + 12 ]\n",
246 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200c, 0x0000ffff}
250 "mov r0, c[ 2 + a0.x ]\n",
251 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e42002, 0x0000ffff}
255 "mov r0, c[ 2 + a0.x + 12 ]\n",
256 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e4200e, 0x0000ffff}
260 "mov r0, c[ 2 + 10 + 12 ]\n",
261 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40018, 0x0000ffff}
266 {0xfffe0101, 0x00000001, 0x800f0000, 0xa0e40006, 0x0000ffff}
271 {0xfffe0101, 0x00000006, 0x800f0000, 0x90000000, 0x0000ffff}
276 {0xfffe0101, 0x00000007, 0x800f0000, 0x90000000, 0x0000ffff}
280 exec_tests("vs_1_1", tests
, sizeof(tests
) / sizeof(tests
[0]));
283 static void ps_1_3_test(void) {
284 struct shader_test tests
[] = {
285 /* Basic instruction tests */
289 {0xffff0103, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff}
294 {0xffff0103, 0x00000002, 0x800f0000, 0x80e40001, 0x80e40000, 0x0000ffff}
296 /* Color interpolator tests */
300 {0xffff0103, 0x00000001, 0x800f0000, 0x90e40000, 0x0000ffff}
305 {0xffff0103, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff}
307 /* Texture sampling instructions */
311 {0xffff0103, 0x00000042, 0xb00f0000, 0x0000ffff}
316 "texreg2ar t1, t0\n",
317 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000045, 0xb00f0001, 0xb0e40000,
323 "texreg2gb t1, t0\n",
324 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000046, 0xb00f0001, 0xb0e40000,
330 "texreg2rgb t1, t0\n",
331 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000052, 0xb00f0001, 0xb0e40000,
336 "cnd r0, r1, r0, v0\n",
337 {0xffff0103, 0x00000050, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000,
342 "cmp r0, r1, r0, v0\n",
343 {0xffff0103, 0x00000058, 0x800f0000, 0x80e40001, 0x80e40000, 0x90e40000,
349 {0xffff0103, 0x00000041, 0xb00f0000, 0x0000ffff}
354 "texm3x2pad t1, t0\n"
355 "texm3x2tex t2, t0\n",
356 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000,
357 0x00000048, 0xb00f0002, 0xb0e40000, 0x0000ffff}
362 "texm3x2pad t1, t0\n"
363 "texm3x2depth t2, t0\n",
364 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000047, 0xb00f0001, 0xb0e40000,
365 0x00000054, 0xb00f0002, 0xb0e40000, 0x0000ffff}
371 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000043, 0xb00f0001, 0xb0e40000,
378 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000044, 0xb00f0001, 0xb0e40000,
384 "texdp3tex t1, t0\n",
385 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000053, 0xb00f0001, 0xb0e40000,
392 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000055, 0xb00f0001, 0xb0e40000,
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,
408 "texm3x3pad t1, t0\n"
409 "texm3x3pad t2, t0\n"
411 {0xffff0103, 0x00000042, 0xb00f0000, 0x00000049, 0xb00f0001, 0xb0e40000,
412 0x00000049, 0xb00f0002, 0xb0e40000, 0x00000056, 0xb00f0003, 0xb0e40000,
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}
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,
438 {0xffff0103, 0x00000040, 0xb00f0000, 0x0000ffff}
440 /* Modifiers, shifts */
443 "mov_x2_sat r0, 1 - r1\n",
444 {0xffff0103, 0x00000001, 0x811f0000, 0x86e40001, 0x0000ffff}
449 {0xffff0103, 0x00000001, 0x8d0f0000, 0x81e40001, 0x0000ffff}
453 "mov_sat r0, r1_bx2\n",
454 {0xffff0103, 0x00000001, 0x801f0000, 0x84e40001, 0x0000ffff}
458 "mov_sat r0, r1_bias\n",
459 {0xffff0103, 0x00000001, 0x801f0000, 0x82e40001, 0x0000ffff}
463 "mov_sat r0, -r1_bias\n",
464 {0xffff0103, 0x00000001, 0x801f0000, 0x83e40001, 0x0000ffff}
468 "mov_sat r0, -r1_bx2\n",
469 {0xffff0103, 0x00000001, 0x801f0000, 0x85e40001, 0x0000ffff}
473 "mov_sat r0, -r1_x2\n",
474 {0xffff0103, 0x00000001, 0x801f0000, 0x88e40001, 0x0000ffff}
478 "mov_x4_sat r0.a, -r1_bx2.a\n",
479 {0xffff0103, 0x00000001, 0x82180000, 0x85ff0001, 0x0000ffff}
483 exec_tests("ps_1_3", tests
, sizeof(tests
) / sizeof(tests
[0]));
486 static void ps_1_4_test(void) {
487 struct shader_test tests
[] = {
488 /* Basic instruction tests */
492 {0xffff0104, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff}
497 {0xffff0104, 0x00000001, 0x800f0000, 0x80e40005, 0x0000ffff}
502 {0xffff0104, 0x00000001, 0x800f0000, 0xa0e40007, 0x0000ffff}
507 {0xffff0104, 0x00000001, 0x800f0000, 0x90e40001, 0x0000ffff}
512 {0xffff0104, 0x0000fffd, 0x0000ffff}
517 {0xffff0104, 0x00000040, 0x800f0000, 0xb0e40000, 0x0000ffff}
522 {0xffff0104, 0x00000040, 0x800f0004, 0xb0e40003, 0x0000ffff}
526 "texcrd_sat r4, t3\n",
527 {0xffff0104, 0x00000040, 0x801f0004, 0xb0e40003, 0x0000ffff}
532 {0xffff0104, 0x00000042, 0x800f0000, 0xb0e40000, 0x0000ffff}
537 {0xffff0104, 0x00000042, 0x800f0001, 0xb0e40004, 0x0000ffff}
542 {0xffff0104, 0x00000042, 0x800f0005, 0x80e40000, 0x0000ffff}
546 "texld r5, c0\n", /* Assembly succeeds, validation fails */
547 {0xffff0104, 0x00000042, 0x800f0005, 0xa0e40000, 0x0000ffff}
552 {0xffff0104, 0x00000042, 0x800f0005, 0x89e40002, 0x0000ffff}
556 "bem r1.rg, c0, r0\n",
557 {0xffff0104, 0x00000059, 0x80030001, 0xa0e40000, 0x80e40000, 0x0000ffff}
562 {0xffff0104, 0x00000057, 0x800f0005, 0x0000ffff}
566 exec_tests("ps_1_4", tests
, sizeof(tests
) / sizeof(tests
[0]));
569 static void vs_2_0_test(void) {
570 struct shader_test tests
[] = {
571 /* Basic instruction tests */
575 {0xfffe0200, 0x02000001, 0x800f0000, 0x80e40001, 0x0000ffff}
579 "lrp r0, v0, c0, r1\n",
580 {0xfffe0200, 0x04000012, 0x800f0000, 0x90e40000, 0xa0e40000, 0x80e40001,
585 "dp4 oPos, v0, c0\n",
586 {0xfffe0200, 0x03000009, 0xc00f0000, 0x90e40000, 0xa0e40000, 0x0000ffff}
590 "mov r0, c0[a0.x]\n",
591 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0000000, 0x0000ffff}
595 "mov r0, c0[a0.y]\n",
596 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0550000, 0x0000ffff}
600 "mov r0, c0[a0.z]\n",
601 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0aa0000, 0x0000ffff}
605 "mov r0, c0[a0.w]\n",
606 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0ff0000, 0x0000ffff}
610 "mov r0, c0[a0.w].x\n",
611 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0002000, 0xb0ff0000, 0x0000ffff}
615 "mov r0, -c0[a0.w+5].x\n",
616 {0xfffe0200, 0x03000001, 0x800f0000, 0xa1002005, 0xb0ff0000, 0x0000ffff}
621 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0e40000, 0x0000ffff}
625 "mov r0, c0[a0.xyww]\n",
626 {0xfffe0200, 0x03000001, 0x800f0000, 0xa0e42000, 0xb0f40000, 0x0000ffff}
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}
638 {0xfffe0200, 0x01000026, 0xf0e40000, 0x00000027, 0x0000ffff}
645 {0xfffe0200, 0x01000028, 0xe0e40800, 0x0000002a, 0x0000002b, 0x0000ffff}
651 {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x0000001d, 0x0000ffff}
656 {0xfffe0200, 0x02000024, 0x800f0000, 0xa0e40000, 0x0000ffff}
661 {0xfffe0200, 0x03000021, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
665 "sgn r0, r1, r2, r3\n",
666 {0xfffe0200, 0x04000022, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003,
671 "sincos r0, r1, r2, r3\n",
672 {0xfffe0200, 0x04000025, 0x800f0000, 0x80e40001, 0x80e40002, 0x80e40003,
678 {0xfffe0200, 0x03000020, 0x800f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
683 {0xfffe0200, 0x0200002e, 0xb0020000, 0xa0aa0000, 0x0000ffff}
689 {0xfffe0200, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801,
690 0x00000000, 0x0000ffff}
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}
705 {0xfffe0200, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000,
706 0xa0e42000, 0xf0e40800, 0x0000001d, 0x0000ffff}
714 {0xfffe0200, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000,
715 0x0000001c, 0x0000ffff}
723 {0xfffe0200, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e,
724 0xa0e41000, 0x0000001c, 0x0000ffff}
732 {0xfffe0200, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e,
733 0xa0e41000, 0x0000001c, 0x0000ffff}
740 {0xfffe0200, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff}
744 exec_tests("vs_2_0", tests
, sizeof(tests
) / sizeof(tests
[0]));
747 static void vs_2_x_test(void) {
748 struct shader_test tests
[] = {
754 {0xfffe0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff}
760 {0xfffe0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff}
767 {0xfffe0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001,
768 0x00000027, 0x0000ffff}
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}
784 {0xfffe0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff}
792 {0xfffe0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c,
793 0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff}
800 {0xfffe0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000,
801 0x00000027, 0x0000ffff}
805 exec_tests("vs_2_x", tests
, sizeof(tests
) / sizeof(tests
[0]));
808 static void ps_2_0_test(void) {
809 struct shader_test tests
[] = {
813 {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
818 {0xffff0200, 0x0200001f, 0x98000000, 0xa00f0800, 0x0000ffff}
823 {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0000ffff}
830 {0xffff0200, 0x0200001f, 0xa0000000, 0xa00f0800, 0x0200001f, 0x98000000,
831 0xa00f0801, 0x0200001f, 0x90000000, 0xa00f0802, 0x0000ffff}
836 {0xffff0200, 0x02000001, 0x800f0000, 0xb0e40000, 0x0000ffff}
841 "texld r0, t1, s2\n",
842 {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000,
843 0xb0e40001, 0xa0e40802, 0x0000ffff}
848 {0xffff0200, 0x01000041, 0xb00f0000, 0x0000ffff}
854 {0xffff0200, 0x02000001, 0x800f0800, 0xa0e40000, 0x02000001, 0x800f0801,
855 0xa0e40001, 0x0000ffff}
859 "mov oDepth, c0.x\n",
860 {0xffff0200, 0x02000001, 0x900f0800, 0xa0000000, 0x0000ffff}
865 "texldp r0, t1, s2\n",
866 {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03010042, 0x800f0000,
867 0xb0e40001, 0xa0e40802, 0x0000ffff}
872 "texldb r0, t1, s2\n",
873 {0xffff0200, 0x0200001f, 0x90000000, 0xa00f0802, 0x03020042, 0x800f0000,
874 0xb0e40001, 0xa0e40802, 0x0000ffff}
878 exec_tests("ps_2_0", tests
, sizeof(tests
) / sizeof(tests
[0]));
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) */
888 {0xffff0201, 0x0200002f, 0xe00f0800, 0x00000001, 0x0200002f, 0xe00f0801,
889 0x00000000, 0x0000ffff}
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}
902 {0xffff0201, 0x0200005b, 0x800f0000, 0x80e40000, 0x0000ffff}
907 {0xffff0201, 0x0200005c, 0x800f0000, 0x80e40000, 0x0000ffff}
912 "texldd r0, v1, s2, r3, r4\n",
913 {0xffff0201, 0x0200001f, 0x90000000, 0xa00f0802, 0x0500005d, 0x800f0000,
914 0x90e40001, 0xa0e40802, 0x80e40003, 0x80e40004, 0x0000ffff}
916 /* Static flow control tests */
923 {0xffff0201, 0x01000019, 0xa0e41000, 0x0000001c, 0x0100001e, 0xa0e41000,
924 0x0000001c, 0x0000ffff}
932 {0xffff0201, 0x0200001a, 0xa0e41000, 0xe0e40800, 0x0000001c, 0x0100001e,
933 0xa0e41000, 0x0000001c, 0x0000ffff}
941 {0xffff0201, 0x0200001a, 0xa0e41000, 0xede40800, 0x0000001c, 0x0100001e,
942 0xa0e41000, 0x0000001c, 0x0000ffff}
949 {0xffff0201, 0x01000028, 0xede40800, 0x0000002a, 0x0000002b, 0x0000ffff}
951 /* Dynamic flow control tests */
957 {0xffff0201, 0x01000026, 0xf0e40000, 0x0000002c, 0x00000027, 0x0000ffff}
963 {0xffff0201, 0x02030029, 0x80e40000, 0x80e40001, 0x0000002b, 0x0000ffff}
970 {0xffff0201, 0x01000026, 0xf0e40000, 0x0205002d, 0x80e40000, 0x80e40001,
971 0x00000027, 0x0000ffff}
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}
986 {0xffff0201, 0x01000028, 0xb0001000, 0x0000002a, 0x0000002b, 0x0000ffff}
994 {0xffff0201, 0x0200001a, 0xa0e41000, 0xbdaa1000, 0x0000001c,
995 0x0100001e, 0xa0e41000, 0x0000001c, 0x0000ffff}
1002 {0xffff0201, 0x01000026, 0xf0e40000, 0x01000060, 0xb0ff1000,
1003 0x00000027, 0x0000ffff}
1007 exec_tests("ps_2_x", tests
, sizeof(tests
) / sizeof(tests
[0]));
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
[] = {
1019 {0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
1021 /* {*/ /* shader 1 */
1024 {0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
1026 /* {*/ /* shader 2 */
1028 "dcl_position o0\n",
1029 {0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
1031 /* {*/ /* shader 3 */
1033 "dcl_texcoord12 o11\n",
1034 {0xfffe0300, 0x0200001f, 0x800c0005, 0xe00f000b, 0x0000ffff}
1036 /* {*/ /* shader 4 */
1038 "texldl r0, v0, s0\n",
1039 {0xfffe0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
1041 /* {*/ /* shader 5 */
1044 {0xfffe0300, 0x03000001, 0x800f0000, 0xa0e42000, 0xf0e40800, 0x0000ffff}
1046 /* {*/ /* shader 6 */
1048 "mov o[ a0.x + 12 ], r0\n",
1049 {0xfffe0300, 0x03000001, 0xe00f200c, 0xb0000000, 0x80e40000, 0x0000ffff}
1051 /* {*/ /* shader 7 */
1053 "add_sat r0, r0, r1\n",
1054 {0xfffe0300, 0x03000002, 0x801f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
1056 /* {*/ /* shader 8 */
1059 {0xfffe0300, 0x02000001, 0x800f0002, 0x8be40001, 0x0000ffff}
1063 exec_tests("vs_3_0", tests
, sizeof(tests
) / sizeof(tests
[0]));
1066 static void ps_3_0_test(void) {
1067 struct shader_test tests
[] = {
1071 {0xffff0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
1076 {0xffff0300, 0x0200001f, 0x80050003, 0x900f0000, 0x0000ffff}
1081 {0xffff0300, 0x02000001, 0x800f0000, 0x90e41000, 0x0000ffff}
1086 {0xffff0300, 0x02000001, 0x800f0000, 0x90e41001, 0x0000ffff}
1090 "mov r0, v[ aL + 12 ]\n",
1091 {0xffff0300, 0x03000001, 0x800f0000, 0x90e4200c, 0xf0e40800, 0x0000ffff}
1098 {0xffff0300, 0x0200001b, 0xf0e40800, 0xf0e40000, 0x03000001, 0x800f0000,
1099 0x90e42000, 0xf0e40800, 0x0000001d, 0x0000ffff}
1103 "texldl r0, v0, s0\n",
1104 {0xffff0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
1108 exec_tests("ps_3_0", tests
, sizeof(tests
) / sizeof(tests
[0]));
1111 static void failure_test(void) {
1112 const char * tests
[] = {
1113 /* shader 0: instruction modifier not allowed */
1116 "texldd_x2 r0, v1, s2, v3, v4\n",
1117 /* shader 1: coissue not supported in vertex shaders */
1119 "add r0.rgb, r0, r1\n"
1120 "+add r0.a, r0, r2\n",
1121 /* shader 2: coissue not supported in pixel shader version >= 2.0 */
1123 "texld r0, t0, s0\n"
1124 "add r0.rgb, r0, r1\n"
1125 "+add r0.a, r0, v1\n",
1126 /* shader 3: predicates not supported in vertex shader < 2.0 */
1128 "(p0) add r0, r0, v0\n",
1129 /* shader 4: register a0 doesn't exist in pixel shaders */
1131 "mov r0, v[ a0 + 12 ]\n",
1132 /* shader 5: s0 doesn't exist in vs_1_1 */
1135 /* shader 6: aL is a scalar register, no swizzles allowed */
1137 "mov r0, v[ aL.x + 12 ]\n",
1138 /* shader 7: tn doesn't exist in ps_3_0 */
1141 "texldd r0, t1, s2, v3, v4\n",
1142 /* shader 8: two shift modifiers */
1144 "mov_x2_x2 r0, r1\n",
1145 /* shader 9: too many source registers for mov instruction */
1148 /* shader 10: invalid combination of negate and divide modifiers */
1150 "texld r5, -r2_dz\n",
1151 /* shader 11: complement modifier not allowed in >= PS 2 */
1154 /* shader 12: invalid modifier */
1157 /* shader 13: float value in relative addressing */
1159 "mov r2, c[ aL + 3.4 ]\n",
1160 /* shader 14: complement modifier not available in VS */
1163 /* shader 15: _x2 modifier not available in VS */
1166 /* shader 16: _abs modifier not available in < VS 3.0 */
1169 /* shader 17: _x2 modifier not available in >= PS 2.0 */
1172 /* shader 18: wrong swizzle */
1174 "mov r0, r1.abcd\n",
1175 /* shader 19: wrong swizzle */
1177 "mov r0, r1.xyzwx\n",
1178 /* shader 20: wrong swizzle */
1181 /* shader 21: invalid writemask */
1183 "mov r0.xxyz, r1\n",
1184 /* shader 22: register r5 doesn't exist in PS < 1.4 */
1190 LPD3DXBUFFER shader
,messages
;
1192 for(i
= 0; i
< (sizeof(tests
) / sizeof(tests
[0])); i
++) {
1195 hr
= D3DXAssembleShader(tests
[i
], strlen(tests
[i
]),
1196 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1197 &shader
, &messages
);
1198 ok(hr
== D3DXERR_INVALIDDATA
, "Failure test, shader %d: "
1199 "expected D3DXAssembleShader failure with D3DXERR_INVALIDDATA, "
1200 "got 0x%x - %d\n", i
, hr
, hr
& 0x0000FFFF);
1202 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1203 ID3DXBuffer_Release(messages
);
1206 DWORD
*res
= ID3DXBuffer_GetBufferPointer(shader
);
1208 ID3DXBuffer_Release(shader
);
1214 static HRESULT WINAPI
testD3DXInclude_open(ID3DXInclude
*iface
,
1215 D3DXINCLUDE_TYPE include_type
,
1216 LPCSTR filename
, LPCVOID parent_data
,
1217 LPCVOID
*data
, UINT
*bytes
) {
1219 char include
[] = "#define REGISTER r0\nvs.1.1\n";
1221 trace("filename = %s\n",filename
);
1223 buffer
= HeapAlloc(GetProcessHeap(), 0, sizeof(include
));
1224 CopyMemory(buffer
, include
, sizeof(include
));
1226 *bytes
= sizeof(include
);
1230 static HRESULT WINAPI
testD3DXInclude_close(ID3DXInclude
*iface
, LPCVOID data
) {
1231 HeapFree(GetProcessHeap(), 0, (LPVOID
)data
);
1235 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
1236 testD3DXInclude_open
,
1237 testD3DXInclude_close
1240 struct D3DXIncludeImpl
{
1241 const ID3DXIncludeVtbl
*lpVtbl
;
1244 static void assembleshader_test(void) {
1245 const char test1
[] = {
1249 const char testincl
[] = {
1250 "#define REGISTER r0\n"
1253 const char testshader
[] = {
1254 "#include \"incl.vsh\"\n"
1255 "mov REGISTER, v0\n"
1258 LPD3DXBUFFER shader
, messages
;
1259 D3DXMACRO defines
[] = {
1270 struct D3DXIncludeImpl include
;
1271 HRESULT shader_vsh_res
, incl_vsh_res
;
1278 hr
= D3DXAssembleShader(test1
, strlen(test1
),
1279 defines
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1280 &shader
, &messages
);
1281 ok(hr
== D3D_OK
, "pDefines test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1283 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1284 ID3DXBuffer_Release(messages
);
1286 if(shader
) ID3DXBuffer_Release(shader
);
1291 include
.lpVtbl
= &D3DXInclude_Vtbl
;
1292 hr
= D3DXAssembleShader(testshader
, strlen(testshader
),
1293 NULL
, (LPD3DXINCLUDE
)&include
, D3DXSHADER_SKIPVALIDATION
,
1294 &shader
, &messages
);
1295 ok(hr
== D3D_OK
, "pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1297 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1298 ID3DXBuffer_Release(messages
);
1300 if(shader
) ID3DXBuffer_Release(shader
);
1302 shader_vsh_res
= create_file("shader.vsh", testshader
, sizeof(testshader
));
1303 if(SUCCEEDED(shader_vsh_res
)) {
1304 incl_vsh_res
= create_file("incl.vsh", testincl
, sizeof(testincl
));
1305 if(SUCCEEDED(incl_vsh_res
)) {
1306 /* D3DXAssembleShaderFromFile + #include test */
1309 hr
= D3DXAssembleShaderFromFileA("shader.vsh",
1310 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1311 &shader
, &messages
);
1312 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1314 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1315 ID3DXBuffer_Release(messages
);
1317 if(shader
) ID3DXBuffer_Release(shader
);
1318 } else skip("Couldn't create \"incl.vsh\"\n");
1320 /* D3DXAssembleShaderFromFile + pInclude test */
1323 hr
= D3DXAssembleShaderFromFileA("shader.vsh",
1324 NULL
, (LPD3DXINCLUDE
)&include
, D3DXSHADER_SKIPVALIDATION
,
1325 &shader
, &messages
);
1326 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1328 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1329 ID3DXBuffer_Release(messages
);
1331 if(shader
) ID3DXBuffer_Release(shader
);
1332 } else skip("Couldn't create \"shader.vsh\"\n");
1336 /* NULL shader tests */
1339 hr
= D3DXAssembleShader(NULL
, 0,
1340 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1341 &shader
, &messages
);
1342 ok(hr
== D3DXERR_INVALIDDATA
, "NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1344 trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1345 ID3DXBuffer_Release(messages
);
1347 if(shader
) ID3DXBuffer_Release(shader
);
1353 hr
= D3DXAssembleShaderFromFileA("nonexistent.vsh",
1354 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1355 &shader
, &messages
);
1356 ok(hr
== D3DXERR_INVALIDDATA
|| hr
== E_FAIL
, /* I get this on WinXP */
1357 "D3DXAssembleShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
1358 hr
, hr
& 0x0000FFFF);
1360 trace("D3DXAssembleShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1361 ID3DXBuffer_Release(messages
);
1363 if(shader
) ID3DXBuffer_Release(shader
);
1365 /* D3DXAssembleShaderFromResource test */
1368 hr
= D3DXAssembleShaderFromResourceA(NULL
, MAKEINTRESOURCEA(IDB_ASMSHADER
),
1369 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1370 &shader
, &messages
);
1371 ok(hr
== D3D_OK
, "D3DXAssembleShaderFromResource test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1373 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1374 ID3DXBuffer_Release(messages
);
1376 if(shader
) ID3DXBuffer_Release(shader
);
1378 } /* end of todo_wine */
1380 /* D3DXAssembleShaderFromResource with missing shader resource test */
1383 hr
= D3DXAssembleShaderFromResourceA(NULL
, "notexisting",
1384 NULL
, NULL
, D3DXSHADER_SKIPVALIDATION
,
1385 &shader
, &messages
);
1386 ok(hr
== D3DXERR_INVALIDDATA
, "D3DXAssembleShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr
, hr
& 0x0000FFFF);
1388 trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages
));
1389 ID3DXBuffer_Release(messages
);
1391 if(shader
) ID3DXBuffer_Release(shader
);
1394 if(SUCCEEDED(shader_vsh_res
)) {
1395 DeleteFileA("shader.vsh");
1396 if(SUCCEEDED(incl_vsh_res
)) DeleteFileA("incl.vsh");
1402 todo_wine
preproc_test();
1403 todo_wine
ps_1_1_test();
1404 todo_wine
vs_1_1_test();
1405 todo_wine
ps_1_3_test();
1406 todo_wine
ps_1_4_test();
1407 todo_wine
vs_2_0_test();
1408 todo_wine
vs_2_x_test();
1409 todo_wine
ps_2_0_test();
1410 todo_wine
ps_2_x_test();
1412 todo_wine
ps_3_0_test();
1416 assembleshader_test();