winegcc: Import kernel32 and ntdll by default also when building Wine.
[wine/multimedia.git] / dlls / d3dx9_36 / asmparser.c
blob10188a01af5a7b452455ef915337ddf6c49bb4b9
1 /*
2 * Direct3D asm shader parser
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2009 Matteo Bruni
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dx9_36_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
30 WINE_DECLARE_DEBUG_CHANNEL(parsed_shader);
33 /* How to map vs 1.0 and 2.0 varyings to 3.0 ones
34 * oTx is mapped to ox, which happens to be an
35 * identical mapping since BWRITERSPR_TEXCRDOUT == BWRITERSPR_OUTPUT
36 * oPos, oFog and point size are mapped to general output regs as well.
37 * the vs 1.x and 2.x parser functions add varying declarations
38 * to the shader, and the 1.x and 2.x output functions check those varyings
40 #define OT0_REG 0
41 #define OT1_REG 1
42 #define OT2_REG 2
43 #define OT3_REG 3
44 #define OT4_REG 4
45 #define OT5_REG 5
46 #define OT6_REG 6
47 #define OT7_REG 7
48 #define OPOS_REG 8
49 #define OFOG_REG 9
50 #define OFOG_WRITEMASK BWRITERSP_WRITEMASK_0
51 #define OPTS_REG 9
52 #define OPTS_WRITEMASK BWRITERSP_WRITEMASK_1
53 #define OD0_REG 10
54 #define OD1_REG 11
56 /* Input color registers 0-1 are identically mapped */
57 #define C0_VARYING 0
58 #define C1_VARYING 1
59 #define T0_VARYING 2
60 #define T1_VARYING 3
61 #define T2_VARYING 4
62 #define T3_VARYING 5
63 #define T4_VARYING 6
64 #define T5_VARYING 7
65 #define T6_VARYING 8
66 #define T7_VARYING 9
68 /****************************************************************
69 * Common(non-version specific) shader parser control code *
70 ****************************************************************/
72 static void asmparser_end(struct asm_parser *This) {
73 TRACE("Finalizing shader\n");
76 static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w) {
77 if(!This->shader) return;
78 TRACE("Adding float constant %u at pos %u\n", reg, This->shader->num_cf);
79 TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
80 if(!add_constF(This->shader, reg, x, y, z, w)) {
81 ERR("Out of memory\n");
82 set_parse_status(This, PARSE_ERR);
86 static void asmparser_constB(struct asm_parser *This, DWORD reg, BOOL x) {
87 if(!This->shader) return;
88 TRACE("Adding boolean constant %u at pos %u\n", reg, This->shader->num_cb);
89 TRACE_(parsed_shader)("def b%u, %s\n", reg, x ? "true" : "false");
90 if(!add_constB(This->shader, reg, x)) {
91 ERR("Out of memory\n");
92 set_parse_status(This, PARSE_ERR);
96 static void asmparser_constI(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w) {
97 if(!This->shader) return;
98 TRACE("Adding integer constant %u at pos %u\n", reg, This->shader->num_ci);
99 TRACE_(parsed_shader)("def i%u, %d, %d, %d, %d\n", reg, x, y, z, w);
100 if(!add_constI(This->shader, reg, x, y, z, w)) {
101 ERR("Out of memory\n");
102 set_parse_status(This, PARSE_ERR);
106 static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num,
107 const struct shader_reg *reg) {
108 if(!This->shader) return;
109 if(This->shader->type == ST_PIXEL) {
110 asmparser_message(This, "Line %u: Output register declared in a pixel shader\n", This->line_no);
111 set_parse_status(This, PARSE_ERR);
113 if(!record_declaration(This->shader, usage, num, 0, TRUE, reg->regnum, reg->writemask, FALSE)) {
114 ERR("Out of memory\n");
115 set_parse_status(This, PARSE_ERR);
119 static void asmparser_dcl_output_unsupported(struct asm_parser *This, DWORD usage, DWORD num,
120 const struct shader_reg *reg) {
121 asmparser_message(This, "Line %u: Output declaration unsupported in this shader version\n", This->line_no);
122 set_parse_status(This, PARSE_ERR);
125 static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num,
126 DWORD mod, const struct shader_reg *reg) {
127 struct instruction instr;
129 if(!This->shader) return;
130 if(mod != 0 &&
131 (This->shader->version != BWRITERPS_VERSION(3, 0) ||
132 (mod != BWRITERSPDM_MSAMPCENTROID &&
133 mod != BWRITERSPDM_PARTIALPRECISION))) {
134 asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no);
135 set_parse_status(This, PARSE_ERR);
136 return;
139 /* Check register type and modifiers */
140 instr.dstmod = mod;
141 instr.shift = 0;
142 This->funcs->dstreg(This, &instr, reg);
144 if(!record_declaration(This->shader, usage, num, mod, FALSE, reg->regnum, reg->writemask, FALSE)) {
145 ERR("Out of memory\n");
146 set_parse_status(This, PARSE_ERR);
150 static void asmparser_dcl_input_ps_2(struct asm_parser *This, DWORD usage, DWORD num,
151 DWORD mod, const struct shader_reg *reg) {
152 struct instruction instr;
154 if(!This->shader) return;
155 instr.dstmod = mod;
156 instr.shift = 0;
157 This->funcs->dstreg(This, &instr, reg);
158 if(!record_declaration(This->shader, usage, num, mod, FALSE, instr.dst.regnum, instr.dst.writemask, FALSE)) {
159 ERR("Out of memory\n");
160 set_parse_status(This, PARSE_ERR);
164 static void asmparser_dcl_input_unsupported(struct asm_parser *This, DWORD usage, DWORD num,
165 DWORD mod, const struct shader_reg *reg) {
166 asmparser_message(This, "Line %u: Input declaration unsupported in this shader version\n", This->line_no);
167 set_parse_status(This, PARSE_ERR);
170 static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype,
171 DWORD mod, DWORD regnum,
172 unsigned int line_no) {
173 if(!This->shader) return;
174 if(mod != 0 &&
175 (This->shader->version != BWRITERPS_VERSION(3, 0) ||
176 (mod != BWRITERSPDM_MSAMPCENTROID &&
177 mod != BWRITERSPDM_PARTIALPRECISION))) {
178 asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no);
179 set_parse_status(This, PARSE_ERR);
180 return;
182 if(!record_sampler(This->shader, samptype, mod, regnum)) {
183 ERR("Out of memory\n");
184 set_parse_status(This, PARSE_ERR);
188 static void asmparser_dcl_sampler_unsupported(struct asm_parser *This, DWORD samptype,
189 DWORD mod, DWORD regnum,
190 unsigned int line_no) {
191 asmparser_message(This, "Line %u: Sampler declaration unsupported in this shader version\n", This->line_no);
192 set_parse_status(This, PARSE_ERR);
195 static void asmparser_sincos(struct asm_parser *This, DWORD mod, DWORD shift,
196 const struct shader_reg *dst,
197 const struct src_regs *srcs) {
198 struct instruction *instr;
200 if(!srcs || srcs->count != 3) {
201 asmparser_message(This, "Line %u: sincos (vs 2) has an incorrect number of source registers\n", This->line_no);
202 set_parse_status(This, PARSE_ERR);
203 return;
206 instr = alloc_instr(3);
207 if(!instr) {
208 ERR("Error allocating memory for the instruction\n");
209 set_parse_status(This, PARSE_ERR);
210 return;
213 instr->opcode = BWRITERSIO_SINCOS;
214 instr->dstmod = mod;
215 instr->shift = shift;
216 instr->comptype = 0;
218 This->funcs->dstreg(This, instr, dst);
219 This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
220 This->funcs->srcreg(This, instr, 1, &srcs->reg[1]);
221 This->funcs->srcreg(This, instr, 2, &srcs->reg[2]);
223 if(!add_instruction(This->shader, instr)) {
224 ERR("Out of memory\n");
225 set_parse_status(This, PARSE_ERR);
229 static void asmparser_texcrd(struct asm_parser *This, DWORD mod, DWORD shift,
230 const struct shader_reg *dst,
231 const struct src_regs *srcs) {
232 struct instruction *instr;
234 if(!srcs || srcs->count != 1) {
235 asmparser_message(This, "Line %u: Wrong number of source registers in texcrd instruction\n", This->line_no);
236 set_parse_status(This, PARSE_ERR);
237 return;
240 instr = alloc_instr(1);
241 if(!instr) {
242 ERR("Error allocating memory for the instruction\n");
243 set_parse_status(This, PARSE_ERR);
244 return;
247 /* The job of texcrd is done by mov in later shader versions */
248 instr->opcode = BWRITERSIO_MOV;
249 instr->dstmod = mod;
250 instr->shift = shift;
251 instr->comptype = 0;
253 This->funcs->dstreg(This, instr, dst);
254 This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
256 if(!add_instruction(This->shader, instr)) {
257 ERR("Out of memory\n");
258 set_parse_status(This, PARSE_ERR);
262 static void asmparser_texld14(struct asm_parser *This, DWORD mod, DWORD shift,
263 const struct shader_reg *dst,
264 const struct src_regs *srcs) {
265 struct instruction *instr;
267 if(!srcs || srcs->count != 1) {
268 asmparser_message(This, "Line %u: texld (PS 1.4) has a wrong number of source registers\n", This->line_no);
269 set_parse_status(This, PARSE_ERR);
270 return;
273 instr = alloc_instr(2);
274 if(!instr) {
275 ERR("Error allocating memory for the instruction\n");
276 set_parse_status(This, PARSE_ERR);
277 return;
280 /* This code is recording a texld instruction, not tex. However,
281 * texld borrows the opcode of tex
283 instr->opcode = BWRITERSIO_TEX;
284 instr->dstmod = mod;
285 instr->shift = shift;
286 instr->comptype = 0;
288 This->funcs->dstreg(This, instr, dst);
289 This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
291 /* The 2nd source register is the sampler register with the
292 * destination's regnum
294 ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
295 instr->src[1].type = BWRITERSPR_SAMPLER;
296 instr->src[1].regnum = dst->regnum;
297 instr->src[1].swizzle = BWRITERVS_NOSWIZZLE;
298 instr->src[1].srcmod = BWRITERSPSM_NONE;
299 instr->src[1].rel_reg = NULL;
301 if(!add_instruction(This->shader, instr)) {
302 ERR("Out of memory\n");
303 set_parse_status(This, PARSE_ERR);
307 static void asmparser_instr(struct asm_parser *This, DWORD opcode,
308 DWORD mod, DWORD shift,
309 BWRITER_COMPARISON_TYPE comp,
310 const struct shader_reg *dst,
311 const struct src_regs *srcs, int expectednsrcs) {
312 struct instruction *instr;
313 unsigned int i;
314 BOOL firstreg = TRUE;
315 unsigned int src_count = srcs ? srcs->count : 0;
317 if(!This->shader) return;
319 TRACE_(parsed_shader)("%s%s%s%s ", debug_print_opcode(opcode),
320 debug_print_dstmod(mod),
321 debug_print_shift(shift),
322 debug_print_comp(comp));
323 if(dst) {
324 TRACE_(parsed_shader)("%s", debug_print_dstreg(dst));
325 firstreg = FALSE;
327 for(i = 0; i < src_count; i++) {
328 if(!firstreg) TRACE_(parsed_shader)(", ");
329 else firstreg = FALSE;
330 TRACE_(parsed_shader)("%s", debug_print_srcreg(&srcs->reg[i]));
332 TRACE_(parsed_shader)("\n");
334 /* Check for instructions with different syntaxes in different shader versio
335 ns */
336 switch(opcode) {
337 case BWRITERSIO_SINCOS:
338 /* The syntax changes between vs 2 and the other shader versions */
339 if(This->shader->version == BWRITERVS_VERSION(2, 0) ||
340 This->shader->version == BWRITERVS_VERSION(2, 1)) {
341 asmparser_sincos(This, mod, shift, dst, srcs);
342 return;
344 /* Use the default handling */
345 break;
346 case BWRITERSIO_TEXCOORD:
347 /* texcoord/texcrd are two instructions present only in PS <= 1.3 and PS 1.4 respectively */
348 asmparser_texcrd(This, mod, shift, dst, srcs);
349 return;
350 case BWRITERSIO_TEX:
351 /* this encodes both the tex PS 1.x instruction and the
352 texld 1.4/2.0+ instruction */
353 if(This->shader->version == BWRITERPS_VERSION(1, 4)) {
354 asmparser_texld14(This, mod, shift, dst, srcs);
355 return;
357 /* else fallback to the standard behavior */
358 break;
361 if(src_count != expectednsrcs) {
362 asmparser_message(This, "Line %u: Wrong number of source registers\n", This->line_no);
363 set_parse_status(This, PARSE_ERR);
364 return;
367 instr = alloc_instr(src_count);
368 if(!instr) {
369 ERR("Error allocating memory for the instruction\n");
370 set_parse_status(This, PARSE_ERR);
371 return;
374 instr->opcode = opcode;
375 instr->dstmod = mod;
376 instr->shift = shift;
377 instr->comptype = comp;
378 if(dst) This->funcs->dstreg(This, instr, dst);
379 for(i = 0; i < src_count; i++) {
380 This->funcs->srcreg(This, instr, i, &srcs->reg[i]);
383 if(!add_instruction(This->shader, instr)) {
384 ERR("Out of memory\n");
385 set_parse_status(This, PARSE_ERR);
389 static struct shader_reg map_oldvs_register(const struct shader_reg *reg) {
390 struct shader_reg ret;
391 switch(reg->type) {
392 case BWRITERSPR_RASTOUT:
393 ret = *reg;
394 ret.type = BWRITERSPR_OUTPUT;
395 switch(reg->regnum) {
396 case BWRITERSRO_POSITION:
397 ret.regnum = OPOS_REG;
398 break;
399 case BWRITERSRO_FOG:
400 ret.regnum = OFOG_REG;
401 ret.writemask = OFOG_WRITEMASK;
402 break;
403 case BWRITERSRO_POINT_SIZE:
404 ret.regnum = OPTS_REG;
405 ret.writemask = OPTS_WRITEMASK;
406 break;
407 default:
408 FIXME("Unhandled RASTOUT register %u\n", reg->regnum);
409 return *reg;
411 return ret;
413 case BWRITERSPR_TEXCRDOUT:
414 ret = *reg;
415 ret.type = BWRITERSPR_OUTPUT;
416 switch(reg->regnum) {
417 case 0: ret.regnum = OT0_REG; break;
418 case 1: ret.regnum = OT1_REG; break;
419 case 2: ret.regnum = OT2_REG; break;
420 case 3: ret.regnum = OT3_REG; break;
421 case 4: ret.regnum = OT4_REG; break;
422 case 5: ret.regnum = OT5_REG; break;
423 case 6: ret.regnum = OT6_REG; break;
424 case 7: ret.regnum = OT7_REG; break;
425 default:
426 FIXME("Unhandled TEXCRDOUT regnum %u\n", reg->regnum);
427 return *reg;
429 return ret;
431 case BWRITERSPR_ATTROUT:
432 ret = *reg;
433 ret.type = BWRITERSPR_OUTPUT;
434 switch(reg->regnum) {
435 case 0: ret.regnum = OD0_REG; break;
436 case 1: ret.regnum = OD1_REG; break;
437 default:
438 FIXME("Unhandled ATTROUT regnum %u\n", reg->regnum);
439 return *reg;
441 return ret;
443 default: return *reg;
447 static struct shader_reg map_oldps_register(const struct shader_reg *reg, BOOL tex_varying) {
448 struct shader_reg ret;
449 switch(reg->type) {
450 case BWRITERSPR_TEXTURE:
451 if(tex_varying) {
452 ret = *reg;
453 ret.type = BWRITERSPR_INPUT;
454 switch(reg->regnum) {
455 case 0: ret.regnum = T0_VARYING; break;
456 case 1: ret.regnum = T1_VARYING; break;
457 case 2: ret.regnum = T2_VARYING; break;
458 case 3: ret.regnum = T3_VARYING; break;
459 case 4: ret.regnum = T4_VARYING; break;
460 case 5: ret.regnum = T5_VARYING; break;
461 case 6: ret.regnum = T6_VARYING; break;
462 case 7: ret.regnum = T7_VARYING; break;
463 default:
464 FIXME("Unexpected TEXTURE register t%u\n", reg->regnum);
465 return *reg;
467 return ret;
468 } else {
469 FIXME("TODO: ps_1_x texture register mapping\n");
470 return *reg;
473 /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
474 to 3.0 ones */
476 default: return *reg;
480 /* Checks for unsupported source modifiers in VS (all versions) or
481 PS 2.0 and newer */
482 static void check_legacy_srcmod(struct asm_parser *This, DWORD srcmod) {
483 if(srcmod == BWRITERSPSM_BIAS || srcmod == BWRITERSPSM_BIASNEG ||
484 srcmod == BWRITERSPSM_SIGN || srcmod == BWRITERSPSM_SIGNNEG ||
485 srcmod == BWRITERSPSM_COMP || srcmod == BWRITERSPSM_X2 ||
486 srcmod == BWRITERSPSM_X2NEG || srcmod == BWRITERSPSM_DZ ||
487 srcmod == BWRITERSPSM_DW) {
488 asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
489 This->line_no,
490 debug_print_srcmod(srcmod));
491 set_parse_status(This, PARSE_ERR);
495 static void check_abs_srcmod(struct asm_parser *This, DWORD srcmod) {
496 if(srcmod == BWRITERSPSM_ABS || srcmod == BWRITERSPSM_ABSNEG) {
497 asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
498 This->line_no,
499 debug_print_srcmod(srcmod));
500 set_parse_status(This, PARSE_ERR);
504 static void check_loop_swizzle(struct asm_parser *This,
505 const struct shader_reg *src) {
506 if((src->type == BWRITERSPR_LOOP && src->swizzle != BWRITERVS_NOSWIZZLE) ||
507 (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
508 src->rel_reg->swizzle != BWRITERVS_NOSWIZZLE)) {
509 asmparser_message(This, "Line %u: Swizzle not allowed on aL register\n", This->line_no);
510 set_parse_status(This, PARSE_ERR);
514 static void check_shift_dstmod(struct asm_parser *This, DWORD shift) {
515 if(shift != 0) {
516 asmparser_message(This, "Line %u: Shift modifiers not supported in this shader version\n",
517 This->line_no);
518 set_parse_status(This, PARSE_ERR);
522 static void check_ps_dstmod(struct asm_parser *This, DWORD dstmod) {
523 if(dstmod == BWRITERSPDM_PARTIALPRECISION ||
524 dstmod == BWRITERSPDM_MSAMPCENTROID) {
525 asmparser_message(This, "Line %u: Instruction modifier %s not supported in this shader version\n",
526 This->line_no,
527 debug_print_dstmod(dstmod));
528 set_parse_status(This, PARSE_ERR);
532 struct allowed_reg_type {
533 DWORD type;
534 DWORD count;
535 BOOL reladdr;
538 static BOOL check_reg_type(const struct shader_reg *reg,
539 const struct allowed_reg_type *allowed) {
540 unsigned int i = 0;
542 while(allowed[i].type != ~0U) {
543 if(reg->type == allowed[i].type) {
544 if(reg->rel_reg) {
545 if(allowed[i].reladdr)
546 return TRUE; /* The relative addressing register
547 can have a negative value, we
548 can't check the register index */
549 return FALSE;
551 if(reg->regnum < allowed[i].count) return TRUE;
552 return FALSE;
554 i++;
556 return FALSE;
559 /* Native assembler doesn't do separate checks for src and dst registers */
560 static const struct allowed_reg_type vs_1_reg_allowed[] = {
561 { BWRITERSPR_TEMP, 12, FALSE },
562 { BWRITERSPR_INPUT, 16, FALSE },
563 { BWRITERSPR_CONST, ~0U, TRUE },
564 { BWRITERSPR_ADDR, 1, FALSE },
565 { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
566 { BWRITERSPR_ATTROUT, 2, FALSE },
567 { BWRITERSPR_TEXCRDOUT, 8, FALSE },
568 { ~0U, 0 } /* End tag */
571 /* struct instruction *asmparser_srcreg
573 * Records a source register in the instruction and does shader version
574 * specific checks and modifications on it
576 * Parameters:
577 * This: Shader parser instance
578 * instr: instruction to store the register in
579 * num: Number of source register
580 * src: Pointer to source the register structure. The caller can free
581 * it afterwards
583 static void asmparser_srcreg_vs_1(struct asm_parser *This,
584 struct instruction *instr, int num,
585 const struct shader_reg *src) {
586 struct shader_reg reg;
588 if(!check_reg_type(src, vs_1_reg_allowed)) {
589 asmparser_message(This, "Line %u: Source register %s not supported in VS 1\n",
590 This->line_no,
591 debug_print_srcreg(src));
592 set_parse_status(This, PARSE_ERR);
594 check_legacy_srcmod(This, src->srcmod);
595 check_abs_srcmod(This, src->srcmod);
596 reg = map_oldvs_register(src);
597 memcpy(&instr->src[num], &reg, sizeof(reg));
600 static const struct allowed_reg_type vs_2_reg_allowed[] = {
601 { BWRITERSPR_TEMP, 12, FALSE },
602 { BWRITERSPR_INPUT, 16, FALSE },
603 { BWRITERSPR_CONST, ~0U, TRUE },
604 { BWRITERSPR_ADDR, 1, FALSE },
605 { BWRITERSPR_CONSTBOOL, 16, FALSE },
606 { BWRITERSPR_CONSTINT, 16, FALSE },
607 { BWRITERSPR_LOOP, 1, FALSE },
608 { BWRITERSPR_LABEL, 2048, FALSE },
609 { BWRITERSPR_PREDICATE, 1, FALSE },
610 { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
611 { BWRITERSPR_ATTROUT, 2, FALSE },
612 { BWRITERSPR_TEXCRDOUT, 8, FALSE },
613 { ~0U, 0 } /* End tag */
616 static void asmparser_srcreg_vs_2(struct asm_parser *This,
617 struct instruction *instr, int num,
618 const struct shader_reg *src) {
619 struct shader_reg reg;
621 if(!check_reg_type(src, vs_2_reg_allowed)) {
622 asmparser_message(This, "Line %u: Source register %s not supported in VS 2\n",
623 This->line_no,
624 debug_print_srcreg(src));
625 set_parse_status(This, PARSE_ERR);
627 check_loop_swizzle(This, src);
628 check_legacy_srcmod(This, src->srcmod);
629 check_abs_srcmod(This, src->srcmod);
630 reg = map_oldvs_register(src);
631 memcpy(&instr->src[num], &reg, sizeof(reg));
634 static const struct allowed_reg_type vs_3_reg_allowed[] = {
635 { BWRITERSPR_TEMP, 32, FALSE },
636 { BWRITERSPR_INPUT, 16, TRUE },
637 { BWRITERSPR_CONST, ~0U, TRUE },
638 { BWRITERSPR_ADDR, 1, FALSE },
639 { BWRITERSPR_CONSTBOOL, 16, FALSE },
640 { BWRITERSPR_CONSTINT, 16, FALSE },
641 { BWRITERSPR_LOOP, 1, FALSE },
642 { BWRITERSPR_LABEL, 2048, FALSE },
643 { BWRITERSPR_PREDICATE, 1, FALSE },
644 { BWRITERSPR_SAMPLER, 4, FALSE },
645 { BWRITERSPR_OUTPUT, 12, TRUE },
646 { ~0U, 0 } /* End tag */
649 static void asmparser_srcreg_vs_3(struct asm_parser *This,
650 struct instruction *instr, int num,
651 const struct shader_reg *src) {
652 if(!check_reg_type(src, vs_3_reg_allowed)) {
653 asmparser_message(This, "Line %u: Source register %s not supported in VS 3.0\n",
654 This->line_no,
655 debug_print_srcreg(src));
656 set_parse_status(This, PARSE_ERR);
658 check_loop_swizzle(This, src);
659 check_legacy_srcmod(This, src->srcmod);
660 memcpy(&instr->src[num], src, sizeof(*src));
663 static const struct allowed_reg_type ps_1_4_reg_allowed[] = {
664 { BWRITERSPR_CONST, 8, FALSE },
665 { BWRITERSPR_TEMP, 6, FALSE },
666 { BWRITERSPR_TEXTURE, 6, FALSE },
667 { BWRITERSPR_INPUT, 2, FALSE },
668 { ~0U, 0 } /* End tag */
671 static void asmparser_srcreg_ps_1_4(struct asm_parser *This,
672 struct instruction *instr, int num,
673 const struct shader_reg *src) {
674 struct shader_reg reg;
676 if(!check_reg_type(src, ps_1_4_reg_allowed)) {
677 asmparser_message(This, "Line %u: Source register %s not supported in PS 1.4\n",
678 This->line_no,
679 debug_print_srcreg(src));
680 set_parse_status(This, PARSE_ERR);
682 check_abs_srcmod(This, src->srcmod);
683 reg = map_oldps_register(src, TRUE);
684 memcpy(&instr->src[num], &reg, sizeof(reg));
687 static const struct allowed_reg_type ps_2_0_reg_allowed[] = {
688 { BWRITERSPR_INPUT, 2, FALSE },
689 { BWRITERSPR_TEMP, 32, FALSE },
690 { BWRITERSPR_CONST, 32, FALSE },
691 { BWRITERSPR_CONSTINT, 16, FALSE },
692 { BWRITERSPR_CONSTBOOL, 16, FALSE },
693 { BWRITERSPR_SAMPLER, 16, FALSE },
694 { BWRITERSPR_TEXTURE, 8, FALSE },
695 { BWRITERSPR_COLOROUT, 4, FALSE },
696 { BWRITERSPR_DEPTHOUT, 1, FALSE },
697 { ~0U, 0 } /* End tag */
700 static void asmparser_srcreg_ps_2(struct asm_parser *This,
701 struct instruction *instr, int num,
702 const struct shader_reg *src) {
703 struct shader_reg reg;
705 if(!check_reg_type(src, ps_2_0_reg_allowed)) {
706 asmparser_message(This, "Line %u: Source register %s not supported in PS 2.0\n",
707 This->line_no,
708 debug_print_srcreg(src));
709 set_parse_status(This, PARSE_ERR);
711 check_legacy_srcmod(This, src->srcmod);
712 check_abs_srcmod(This, src->srcmod);
713 reg = map_oldps_register(src, TRUE);
714 memcpy(&instr->src[num], &reg, sizeof(reg));
717 static const struct allowed_reg_type ps_2_x_reg_allowed[] = {
718 { BWRITERSPR_INPUT, 2, FALSE },
719 { BWRITERSPR_TEMP, 32, FALSE },
720 { BWRITERSPR_CONST, 32, FALSE },
721 { BWRITERSPR_CONSTINT, 16, FALSE },
722 { BWRITERSPR_CONSTBOOL, 16, FALSE },
723 { BWRITERSPR_PREDICATE, 1, FALSE },
724 { BWRITERSPR_SAMPLER, 16, FALSE },
725 { BWRITERSPR_TEXTURE, 8, FALSE },
726 { BWRITERSPR_LABEL, 2048, FALSE },
727 { BWRITERSPR_COLOROUT, 4, FALSE },
728 { BWRITERSPR_DEPTHOUT, 1, FALSE },
729 { ~0U, 0 } /* End tag */
732 static void asmparser_srcreg_ps_2_x(struct asm_parser *This,
733 struct instruction *instr, int num,
734 const struct shader_reg *src) {
735 struct shader_reg reg;
737 if(!check_reg_type(src, ps_2_x_reg_allowed)) {
738 asmparser_message(This, "Line %u: Source register %s not supported in PS 2.x\n",
739 This->line_no,
740 debug_print_srcreg(src));
741 set_parse_status(This, PARSE_ERR);
743 check_legacy_srcmod(This, src->srcmod);
744 check_abs_srcmod(This, src->srcmod);
745 reg = map_oldps_register(src, TRUE);
746 memcpy(&instr->src[num], &reg, sizeof(reg));
749 static const struct allowed_reg_type ps_3_reg_allowed[] = {
750 { BWRITERSPR_INPUT, 10, TRUE },
751 { BWRITERSPR_TEMP, 32, FALSE },
752 { BWRITERSPR_CONST, 224, FALSE },
753 { BWRITERSPR_CONSTINT, 16, FALSE },
754 { BWRITERSPR_CONSTBOOL, 16, FALSE },
755 { BWRITERSPR_PREDICATE, 1, FALSE },
756 { BWRITERSPR_SAMPLER, 16, FALSE },
757 { BWRITERSPR_MISCTYPE, 2, FALSE }, /* vPos and vFace */
758 { BWRITERSPR_LOOP, 1, FALSE },
759 { BWRITERSPR_LABEL, 2048, FALSE },
760 { BWRITERSPR_COLOROUT, 4, FALSE },
761 { BWRITERSPR_DEPTHOUT, 1, FALSE },
762 { ~0U, 0 } /* End tag */
765 static void asmparser_srcreg_ps_3(struct asm_parser *This,
766 struct instruction *instr, int num,
767 const struct shader_reg *src) {
768 if(!check_reg_type(src, ps_3_reg_allowed)) {
769 asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
770 This->line_no,
771 debug_print_srcreg(src));
772 set_parse_status(This, PARSE_ERR);
774 check_loop_swizzle(This, src);
775 check_legacy_srcmod(This, src->srcmod);
776 memcpy(&instr->src[num], src, sizeof(*src));
779 static void asmparser_dstreg_vs_1(struct asm_parser *This,
780 struct instruction *instr,
781 const struct shader_reg *dst) {
782 struct shader_reg reg;
784 if(!check_reg_type(dst, vs_1_reg_allowed)) {
785 asmparser_message(This, "Line %u: Destination register %s not supported in VS 1\n",
786 This->line_no,
787 debug_print_dstreg(dst));
788 set_parse_status(This, PARSE_ERR);
790 check_ps_dstmod(This, instr->dstmod);
791 check_shift_dstmod(This, instr->shift);
792 reg = map_oldvs_register(dst);
793 memcpy(&instr->dst, &reg, sizeof(reg));
794 instr->has_dst = TRUE;
797 static void asmparser_dstreg_vs_2(struct asm_parser *This,
798 struct instruction *instr,
799 const struct shader_reg *dst) {
800 struct shader_reg reg;
802 if(!check_reg_type(dst, vs_2_reg_allowed)) {
803 asmparser_message(This, "Line %u: Destination register %s not supported in VS 2.0\n",
804 This->line_no,
805 debug_print_dstreg(dst));
806 set_parse_status(This, PARSE_ERR);
808 check_ps_dstmod(This, instr->dstmod);
809 check_shift_dstmod(This, instr->shift);
810 reg = map_oldvs_register(dst);
811 memcpy(&instr->dst, &reg, sizeof(reg));
812 instr->has_dst = TRUE;
815 static void asmparser_dstreg_vs_3(struct asm_parser *This,
816 struct instruction *instr,
817 const struct shader_reg *dst) {
818 if(!check_reg_type(dst, vs_3_reg_allowed)) {
819 asmparser_message(This, "Line %u: Destination register %s not supported in VS 3.0\n",
820 This->line_no,
821 debug_print_dstreg(dst));
822 set_parse_status(This, PARSE_ERR);
824 check_ps_dstmod(This, instr->dstmod);
825 check_shift_dstmod(This, instr->shift);
826 memcpy(&instr->dst, dst, sizeof(*dst));
827 instr->has_dst = TRUE;
830 static void asmparser_dstreg_ps_1_4(struct asm_parser *This,
831 struct instruction *instr,
832 const struct shader_reg *dst) {
833 struct shader_reg reg;
835 if(!check_reg_type(dst, ps_1_4_reg_allowed)) {
836 asmparser_message(This, "Line %u: Destination register %s not supported in PS 1\n",
837 This->line_no,
838 debug_print_dstreg(dst));
839 set_parse_status(This, PARSE_ERR);
841 reg = map_oldps_register(dst, FALSE);
842 memcpy(&instr->dst, &reg, sizeof(reg));
843 instr->has_dst = TRUE;
846 static void asmparser_dstreg_ps_2(struct asm_parser *This,
847 struct instruction *instr,
848 const struct shader_reg *dst) {
849 struct shader_reg reg;
851 if(!check_reg_type(dst, ps_2_0_reg_allowed)) {
852 asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.0\n",
853 This->line_no,
854 debug_print_dstreg(dst));
855 set_parse_status(This, PARSE_ERR);
857 check_shift_dstmod(This, instr->shift);
858 reg = map_oldps_register(dst, TRUE);
859 memcpy(&instr->dst, &reg, sizeof(reg));
860 instr->has_dst = TRUE;
863 static void asmparser_dstreg_ps_2_x(struct asm_parser *This,
864 struct instruction *instr,
865 const struct shader_reg *dst) {
866 struct shader_reg reg;
868 if(!check_reg_type(dst, ps_2_x_reg_allowed)) {
869 asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.x\n",
870 This->line_no,
871 debug_print_dstreg(dst));
872 set_parse_status(This, PARSE_ERR);
874 check_shift_dstmod(This, instr->shift);
875 reg = map_oldps_register(dst, TRUE);
876 memcpy(&instr->dst, &reg, sizeof(reg));
877 instr->has_dst = TRUE;
880 static void asmparser_dstreg_ps_3(struct asm_parser *This,
881 struct instruction *instr,
882 const struct shader_reg *dst) {
883 if(!check_reg_type(dst, ps_3_reg_allowed)) {
884 asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
885 This->line_no,
886 debug_print_dstreg(dst));
887 set_parse_status(This, PARSE_ERR);
889 check_shift_dstmod(This, instr->shift);
890 memcpy(&instr->dst, dst, sizeof(*dst));
891 instr->has_dst = TRUE;
894 static void asmparser_predicate_supported(struct asm_parser *This,
895 const struct shader_reg *predicate) {
896 /* this sets the predicate of the last instruction added to the shader */
897 if(!This->shader) return;
898 if(This->shader->num_instrs == 0) ERR("Predicate without an instruction\n");
899 This->shader->instr[This->shader->num_instrs - 1]->has_predicate = TRUE;
900 memcpy(&This->shader->instr[This->shader->num_instrs - 1]->predicate, predicate, sizeof(*predicate));
903 static void asmparser_predicate_unsupported(struct asm_parser *This,
904 const struct shader_reg *predicate) {
905 asmparser_message(This, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This->line_no);
906 set_parse_status(This, PARSE_ERR);
909 static void asmparser_coissue_supported(struct asm_parser *This) {
910 /* this sets the coissue flag of the last instruction added to the shader */
911 if(!This->shader) return;
912 if(This->shader->num_instrs == 0){
913 asmparser_message(This, "Line %u: Coissue flag on the first shader instruction\n", This->line_no);
914 set_parse_status(This, PARSE_ERR);
916 This->shader->instr[This->shader->num_instrs-1]->coissue = TRUE;
919 static void asmparser_coissue_unsupported(struct asm_parser *This) {
920 asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
921 set_parse_status(This, PARSE_ERR);
924 static const struct asmparser_backend parser_vs_1 = {
925 asmparser_constF,
926 asmparser_constI,
927 asmparser_constB,
929 asmparser_dstreg_vs_1,
930 asmparser_srcreg_vs_1,
932 asmparser_predicate_unsupported,
933 asmparser_coissue_unsupported,
935 asmparser_dcl_output_unsupported,
936 asmparser_dcl_input,
937 asmparser_dcl_sampler_unsupported,
939 asmparser_end,
941 asmparser_instr,
944 static const struct asmparser_backend parser_vs_2 = {
945 asmparser_constF,
946 asmparser_constI,
947 asmparser_constB,
949 asmparser_dstreg_vs_2,
950 asmparser_srcreg_vs_2,
952 asmparser_predicate_supported,
953 asmparser_coissue_unsupported,
955 asmparser_dcl_output_unsupported,
956 asmparser_dcl_input,
957 asmparser_dcl_sampler_unsupported,
959 asmparser_end,
961 asmparser_instr,
964 static const struct asmparser_backend parser_vs_3 = {
965 asmparser_constF,
966 asmparser_constI,
967 asmparser_constB,
969 asmparser_dstreg_vs_3,
970 asmparser_srcreg_vs_3,
972 asmparser_predicate_supported,
973 asmparser_coissue_unsupported,
975 asmparser_dcl_output,
976 asmparser_dcl_input,
977 asmparser_dcl_sampler,
979 asmparser_end,
981 asmparser_instr,
984 static const struct asmparser_backend parser_ps_1_4 = {
985 asmparser_constF,
986 asmparser_constI,
987 asmparser_constB,
989 asmparser_dstreg_ps_1_4,
990 asmparser_srcreg_ps_1_4,
992 asmparser_predicate_unsupported,
993 asmparser_coissue_supported,
995 asmparser_dcl_output_unsupported,
996 asmparser_dcl_input_unsupported,
997 asmparser_dcl_sampler_unsupported,
999 asmparser_end,
1001 asmparser_instr,
1004 static const struct asmparser_backend parser_ps_2 = {
1005 asmparser_constF,
1006 asmparser_constI,
1007 asmparser_constB,
1009 asmparser_dstreg_ps_2,
1010 asmparser_srcreg_ps_2,
1012 asmparser_predicate_unsupported,
1013 asmparser_coissue_unsupported,
1015 asmparser_dcl_output_unsupported,
1016 asmparser_dcl_input_ps_2,
1017 asmparser_dcl_sampler,
1019 asmparser_end,
1021 asmparser_instr,
1024 static const struct asmparser_backend parser_ps_2_x = {
1025 asmparser_constF,
1026 asmparser_constI,
1027 asmparser_constB,
1029 asmparser_dstreg_ps_2_x,
1030 asmparser_srcreg_ps_2_x,
1032 asmparser_predicate_supported,
1033 asmparser_coissue_unsupported,
1035 asmparser_dcl_output_unsupported,
1036 asmparser_dcl_input_ps_2,
1037 asmparser_dcl_sampler,
1039 asmparser_end,
1041 asmparser_instr,
1044 static const struct asmparser_backend parser_ps_3 = {
1045 asmparser_constF,
1046 asmparser_constI,
1047 asmparser_constB,
1049 asmparser_dstreg_ps_3,
1050 asmparser_srcreg_ps_3,
1052 asmparser_predicate_supported,
1053 asmparser_coissue_unsupported,
1055 asmparser_dcl_output_unsupported,
1056 asmparser_dcl_input,
1057 asmparser_dcl_sampler,
1059 asmparser_end,
1061 asmparser_instr,
1064 static void gen_oldvs_output(struct bwriter_shader *shader) {
1065 record_declaration(shader, BWRITERDECLUSAGE_POSITION, 0, 0, TRUE, OPOS_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1066 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, TRUE, OT0_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1067 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, TRUE, OT1_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1068 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, TRUE, OT2_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1069 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, TRUE, OT3_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1070 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, TRUE, OT4_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1071 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, TRUE, OT5_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1072 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, TRUE, OT6_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1073 record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, TRUE, OT7_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1074 record_declaration(shader, BWRITERDECLUSAGE_FOG, 0, 0, TRUE, OFOG_REG, OFOG_WRITEMASK, TRUE);
1075 record_declaration(shader, BWRITERDECLUSAGE_PSIZE, 0, 0, TRUE, OPTS_REG, OPTS_WRITEMASK, TRUE);
1076 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, TRUE, OD0_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1077 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, TRUE, OD1_REG, BWRITERSP_WRITEMASK_ALL, TRUE);
1080 static void gen_oldps_input(struct bwriter_shader *shader, DWORD texcoords) {
1081 switch(texcoords) {
1082 case 8: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 7, 0, FALSE, T7_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1083 case 7: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 6, 0, FALSE, T6_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1084 case 6: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 5, 0, FALSE, T5_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1085 case 5: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 4, 0, FALSE, T4_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1086 case 4: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 3, 0, FALSE, T3_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1087 case 3: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 2, 0, FALSE, T2_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1088 case 2: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 1, 0, FALSE, T1_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1089 case 1: record_declaration(shader, BWRITERDECLUSAGE_TEXCOORD, 0, 0, FALSE, T0_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1091 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 0, 0, FALSE, C0_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1092 record_declaration(shader, BWRITERDECLUSAGE_COLOR, 1, 0, FALSE, C1_VARYING, BWRITERSP_WRITEMASK_ALL, TRUE);
1095 void create_vs10_parser(struct asm_parser *ret) {
1096 TRACE_(parsed_shader)("vs_1_0\n");
1098 ret->shader = asm_alloc(sizeof(*ret->shader));
1099 if(!ret->shader) {
1100 ERR("Failed to allocate memory for the shader\n");
1101 set_parse_status(ret, PARSE_ERR);
1102 return;
1105 ret->shader->type = ST_VERTEX;
1106 ret->shader->version = BWRITERVS_VERSION(1, 0);
1107 ret->funcs = &parser_vs_1;
1108 gen_oldvs_output(ret->shader);
1111 void create_vs11_parser(struct asm_parser *ret) {
1112 TRACE_(parsed_shader)("vs_1_1\n");
1114 ret->shader = asm_alloc(sizeof(*ret->shader));
1115 if(!ret->shader) {
1116 ERR("Failed to allocate memory for the shader\n");
1117 set_parse_status(ret, PARSE_ERR);
1118 return;
1121 ret->shader->type = ST_VERTEX;
1122 ret->shader->version = BWRITERVS_VERSION(1, 1);
1123 ret->funcs = &parser_vs_1;
1124 gen_oldvs_output(ret->shader);
1127 void create_vs20_parser(struct asm_parser *ret) {
1128 TRACE_(parsed_shader)("vs_2_0\n");
1130 ret->shader = asm_alloc(sizeof(*ret->shader));
1131 if(!ret->shader) {
1132 ERR("Failed to allocate memory for the shader\n");
1133 set_parse_status(ret, PARSE_ERR);
1134 return;
1137 ret->shader->type = ST_VERTEX;
1138 ret->shader->version = BWRITERVS_VERSION(2, 0);
1139 ret->funcs = &parser_vs_2;
1140 gen_oldvs_output(ret->shader);
1143 void create_vs2x_parser(struct asm_parser *ret) {
1144 TRACE_(parsed_shader)("vs_2_x\n");
1146 ret->shader = asm_alloc(sizeof(*ret->shader));
1147 if(!ret->shader) {
1148 ERR("Failed to allocate memory for the shader\n");
1149 set_parse_status(ret, PARSE_ERR);
1150 return;
1153 ret->shader->type = ST_VERTEX;
1154 ret->shader->version = BWRITERVS_VERSION(2, 1);
1155 ret->funcs = &parser_vs_2;
1156 gen_oldvs_output(ret->shader);
1159 void create_vs30_parser(struct asm_parser *ret) {
1160 TRACE_(parsed_shader)("vs_3_0\n");
1162 ret->shader = asm_alloc(sizeof(*ret->shader));
1163 if(!ret->shader) {
1164 ERR("Failed to allocate memory for the shader\n");
1165 set_parse_status(ret, PARSE_ERR);
1166 return;
1169 ret->shader->type = ST_VERTEX;
1170 ret->shader->version = BWRITERVS_VERSION(3, 0);
1171 ret->funcs = &parser_vs_3;
1174 void create_ps14_parser(struct asm_parser *ret) {
1175 TRACE_(parsed_shader)("ps_1_4\n");
1177 ret->shader = asm_alloc(sizeof(*ret->shader));
1178 if(!ret->shader) {
1179 ERR("Failed to allocate memory for the shader\n");
1180 set_parse_status(ret, PARSE_ERR);
1181 return;
1184 ret->shader->type = ST_PIXEL;
1185 ret->shader->version = BWRITERPS_VERSION(1, 4);
1186 ret->funcs = &parser_ps_1_4;
1187 gen_oldps_input(ret->shader, 6);
1190 void create_ps20_parser(struct asm_parser *ret) {
1191 TRACE_(parsed_shader)("ps_2_0\n");
1193 ret->shader = asm_alloc(sizeof(*ret->shader));
1194 if(!ret->shader) {
1195 ERR("Failed to allocate memory for the shader\n");
1196 set_parse_status(ret, PARSE_ERR);
1197 return;
1200 ret->shader->type = ST_PIXEL;
1201 ret->shader->version = BWRITERPS_VERSION(2, 0);
1202 ret->funcs = &parser_ps_2;
1203 gen_oldps_input(ret->shader, 8);
1206 void create_ps2x_parser(struct asm_parser *ret) {
1207 TRACE_(parsed_shader)("ps_2_x\n");
1209 ret->shader = asm_alloc(sizeof(*ret->shader));
1210 if(!ret->shader) {
1211 ERR("Failed to allocate memory for the shader\n");
1212 set_parse_status(ret, PARSE_ERR);
1213 return;
1216 ret->shader->type = ST_PIXEL;
1217 ret->shader->version = BWRITERPS_VERSION(2, 1);
1218 ret->funcs = &parser_ps_2_x;
1219 gen_oldps_input(ret->shader, 8);
1222 void create_ps30_parser(struct asm_parser *ret) {
1223 TRACE_(parsed_shader)("ps_3_0\n");
1225 ret->shader = asm_alloc(sizeof(*ret->shader));
1226 if(!ret->shader) {
1227 ERR("Failed to allocate memory for the shader\n");
1228 set_parse_status(ret, PARSE_ERR);
1229 return;
1232 ret->shader->type = ST_PIXEL;
1233 ret->shader->version = BWRITERPS_VERSION(3, 0);
1234 ret->funcs = &parser_ps_3;