ReactOS  0.4.14-dev-358-gbef841c
asmparser.c
Go to the documentation of this file.
1 /*
2  * Direct3D asm shader parser
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2009 Matteo Bruni
6  *
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.
11  *
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.
16  *
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
20  *
21  */
22 
23 #include "wine/debug.h"
24 
25 #include "d3dcompiler_private.h"
26 
28 WINE_DECLARE_DEBUG_CHANNEL(parsed_shader);
29 
30 
31 /* How to map vs 1.0 and 2.0 varyings to 3.0 ones
32  * oTx is mapped to ox, which happens to be an
33  * identical mapping since BWRITERSPR_TEXCRDOUT == BWRITERSPR_OUTPUT
34  * oPos, oFog and point size are mapped to general output regs as well.
35  * the vs 1.x and 2.x parser functions add varying declarations
36  * to the shader, and the 1.x and 2.x output functions check those varyings
37  */
38 #define OT0_REG 0
39 #define OT1_REG 1
40 #define OT2_REG 2
41 #define OT3_REG 3
42 #define OT4_REG 4
43 #define OT5_REG 5
44 #define OT6_REG 6
45 #define OT7_REG 7
46 #define OPOS_REG 8
47 #define OFOG_REG 9
48 #define OFOG_WRITEMASK BWRITERSP_WRITEMASK_0
49 #define OPTS_REG 9
50 #define OPTS_WRITEMASK BWRITERSP_WRITEMASK_1
51 #define OD0_REG 10
52 #define OD1_REG 11
53 
54 /* Input color registers 0-1 are identically mapped */
55 #define C0_VARYING 0
56 #define C1_VARYING 1
57 #define T0_VARYING 2
58 #define T1_VARYING 3
59 #define T2_VARYING 4
60 #define T3_VARYING 5
61 #define T4_VARYING 6
62 #define T5_VARYING 7
63 #define T6_VARYING 8
64 #define T7_VARYING 9
65 
66 /****************************************************************
67  * Common(non-version specific) shader parser control code *
68  ****************************************************************/
69 
70 static void asmparser_end(struct asm_parser *This) {
71  TRACE("Finalizing shader\n");
72 }
73 
74 static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w) {
75  if(!This->shader) return;
76  TRACE("Adding float constant %u at pos %u\n", reg, This->shader->num_cf);
77  TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
78  if(!add_constF(This->shader, reg, x, y, z, w)) {
79  ERR("Out of memory\n");
80  set_parse_status(&This->status, PARSE_ERR);
81  }
82 }
83 
84 static void asmparser_constB(struct asm_parser *This, DWORD reg, BOOL x) {
85  if(!This->shader) return;
86  TRACE("Adding boolean constant %u at pos %u\n", reg, This->shader->num_cb);
87  TRACE_(parsed_shader)("def b%u, %s\n", reg, x ? "true" : "false");
88  if(!add_constB(This->shader, reg, x)) {
89  ERR("Out of memory\n");
90  set_parse_status(&This->status, PARSE_ERR);
91  }
92 }
93 
94 static void asmparser_constI(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w) {
95  if(!This->shader) return;
96  TRACE("Adding integer constant %u at pos %u\n", reg, This->shader->num_ci);
97  TRACE_(parsed_shader)("def i%u, %d, %d, %d, %d\n", reg, x, y, z, w);
98  if(!add_constI(This->shader, reg, x, y, z, w)) {
99  ERR("Out of memory\n");
100  set_parse_status(&This->status, PARSE_ERR);
101  }
102 }
103 
105  const struct shader_reg *reg) {
106  if(!This->shader) return;
107  if(This->shader->type == ST_PIXEL) {
108  asmparser_message(This, "Line %u: Output register declared in a pixel shader\n", This->line_no);
109  set_parse_status(&This->status, PARSE_ERR);
110  }
111  if(!record_declaration(This->shader, usage, num, 0, TRUE, reg->regnum, reg->u.writemask, FALSE)) {
112  ERR("Out of memory\n");
113  set_parse_status(&This->status, PARSE_ERR);
114  }
115 }
116 
118  const struct shader_reg *reg) {
119  asmparser_message(This, "Line %u: Output declaration unsupported in this shader version\n", This->line_no);
120  set_parse_status(&This->status, PARSE_ERR);
121 }
122 
124  DWORD mod, const struct shader_reg *reg) {
125  struct instruction instr;
126 
127  if(!This->shader) return;
128  if(mod != 0 &&
129  (This->shader->version != BWRITERPS_VERSION(3, 0) ||
132  asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no);
133  set_parse_status(&This->status, PARSE_ERR);
134  return;
135  }
136 
137  /* Check register type and modifiers */
138  instr.dstmod = mod;
139  instr.shift = 0;
140  This->funcs->dstreg(This, &instr, reg);
141 
142  if(!record_declaration(This->shader, usage, num, mod, FALSE, reg->regnum, reg->u.writemask, FALSE)) {
143  ERR("Out of memory\n");
144  set_parse_status(&This->status, PARSE_ERR);
145  }
146 }
147 
149  DWORD mod, const struct shader_reg *reg) {
150  struct instruction instr;
151 
152  if(!This->shader) return;
153  instr.dstmod = mod;
154  instr.shift = 0;
155  This->funcs->dstreg(This, &instr, reg);
156  if(!record_declaration(This->shader, usage, num, mod, FALSE, instr.dst.regnum, instr.dst.u.writemask, FALSE)) {
157  ERR("Out of memory\n");
158  set_parse_status(&This->status, PARSE_ERR);
159  }
160 }
161 
163  DWORD usage, DWORD num, DWORD mod, const struct shader_reg *reg)
164 {
165  asmparser_message(This, "Line %u: Input declaration unsupported in this shader version\n", This->line_no);
166  set_parse_status(&This->status, PARSE_ERR);
167 }
168 
169 static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype,
170  DWORD mod, DWORD regnum,
171  unsigned int line_no) {
172  if(!This->shader) return;
173  if(mod != 0 &&
174  (This->shader->version != BWRITERPS_VERSION(3, 0) ||
177  asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no);
178  set_parse_status(&This->status, PARSE_ERR);
179  return;
180  }
181  if(!record_sampler(This->shader, samptype, mod, regnum)) {
182  ERR("Out of memory\n");
183  set_parse_status(&This->status, PARSE_ERR);
184  }
185 }
186 
188  DWORD samptype, DWORD mod, DWORD regnum, unsigned int line_no)
189 {
190  asmparser_message(This, "Line %u: Sampler declaration unsupported in this shader version\n", This->line_no);
191  set_parse_status(&This->status, PARSE_ERR);
192 }
193 
195  const struct shader_reg *dst,
196  const struct src_regs *srcs) {
197  struct instruction *instr;
198 
199  if(!srcs || srcs->count != 3) {
200  asmparser_message(This, "Line %u: sincos (vs 2) has an incorrect number of source registers\n", This->line_no);
201  set_parse_status(&This->status, PARSE_ERR);
202  return;
203  }
204 
205  instr = alloc_instr(3);
206  if(!instr) {
207  ERR("Error allocating memory for the instruction\n");
208  set_parse_status(&This->status, PARSE_ERR);
209  return;
210  }
211 
212  instr->opcode = BWRITERSIO_SINCOS;
213  instr->dstmod = mod;
214  instr->shift = shift;
215  instr->comptype = 0;
216 
217  This->funcs->dstreg(This, instr, dst);
218  This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
219  This->funcs->srcreg(This, instr, 1, &srcs->reg[1]);
220  This->funcs->srcreg(This, instr, 2, &srcs->reg[2]);
221 
222  if(!add_instruction(This->shader, instr)) {
223  ERR("Out of memory\n");
224  set_parse_status(&This->status, PARSE_ERR);
225  }
226 }
227 
229  struct shader_reg ret;
230  switch(reg->type) {
231  case BWRITERSPR_TEXTURE:
232  if(tex_varying) {
233  ret = *reg;
234  ret.type = BWRITERSPR_INPUT;
235  switch(reg->regnum) {
236  case 0: ret.regnum = T0_VARYING; break;
237  case 1: ret.regnum = T1_VARYING; break;
238  case 2: ret.regnum = T2_VARYING; break;
239  case 3: ret.regnum = T3_VARYING; break;
240  case 4: ret.regnum = T4_VARYING; break;
241  case 5: ret.regnum = T5_VARYING; break;
242  case 6: ret.regnum = T6_VARYING; break;
243  case 7: ret.regnum = T7_VARYING; break;
244  default:
245  FIXME("Unexpected TEXTURE register t%u\n", reg->regnum);
246  return *reg;
247  }
248  return ret;
249  } else {
250  ret = *reg;
251  ret.type = BWRITERSPR_TEMP;
252  switch(reg->regnum) {
253  case 0: ret.regnum = T0_REG; break;
254  case 1: ret.regnum = T1_REG; break;
255  case 2: ret.regnum = T2_REG; break;
256  case 3: ret.regnum = T3_REG; break;
257  default:
258  FIXME("Unexpected TEXTURE register t%u\n", reg->regnum);
259  return *reg;
260  }
261  return ret;
262  }
263 
264  /* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
265  to 3.0 ones */
266 
267  default: return *reg;
268  }
269 }
270 
272  const struct shader_reg *dst,
273  const struct src_regs *srcs) {
274  struct instruction *instr;
275 
276  if(srcs) {
277  asmparser_message(This, "Line %u: Source registers in texcoord instruction\n", This->line_no);
278  set_parse_status(&This->status, PARSE_ERR);
279  return;
280  }
281 
282  instr = alloc_instr(1);
283  if(!instr) {
284  ERR("Error allocating memory for the instruction\n");
285  set_parse_status(&This->status, PARSE_ERR);
286  return;
287  }
288 
289  /* texcoord copies the texture coord data into a temporary register-like
290  * readable form. In newer shader models this equals a MOV from v0 to r0,
291  * record it as this.
292  */
293  instr->opcode = BWRITERSIO_MOV;
294  instr->dstmod = mod | BWRITERSPDM_SATURATE; /* texcoord clamps to [0;1] */
295  instr->shift = shift;
296  instr->comptype = 0;
297 
298  This->funcs->dstreg(This, instr, dst);
299  /* The src reg needs special care */
301 
302  if(!add_instruction(This->shader, instr)) {
303  ERR("Out of memory\n");
304  set_parse_status(&This->status, PARSE_ERR);
305  }
306 }
307 
309  const struct shader_reg *dst,
310  const struct src_regs *srcs) {
311  struct instruction *instr;
312 
313  if(!srcs || srcs->count != 1) {
314  asmparser_message(This, "Line %u: Wrong number of source registers in texcrd instruction\n", This->line_no);
315  set_parse_status(&This->status, PARSE_ERR);
316  return;
317  }
318 
319  instr = alloc_instr(1);
320  if(!instr) {
321  ERR("Error allocating memory for the instruction\n");
322  set_parse_status(&This->status, PARSE_ERR);
323  return;
324  }
325 
326  /* The job of texcrd is done by mov in later shader versions */
327  instr->opcode = BWRITERSIO_MOV;
328  instr->dstmod = mod;
329  instr->shift = shift;
330  instr->comptype = 0;
331 
332  This->funcs->dstreg(This, instr, dst);
333  This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
334 
335  if(!add_instruction(This->shader, instr)) {
336  ERR("Out of memory\n");
337  set_parse_status(&This->status, PARSE_ERR);
338  }
339 }
340 
341 static void asmparser_texkill(struct asm_parser *This,
342  const struct shader_reg *dst) {
343  struct instruction *instr = alloc_instr(0);
344 
345  if(!instr) {
346  ERR("Error allocating memory for the instruction\n");
347  set_parse_status(&This->status, PARSE_ERR);
348  return;
349  }
350 
351  instr->opcode = BWRITERSIO_TEXKILL;
352  instr->dstmod = 0;
353  instr->shift = 0;
354  instr->comptype = 0;
355 
356  /* Do not run the dst register through the normal
357  * register conversion. If used with ps_1_0 to ps_1_3
358  * the texture coordinate from that register is used,
359  * not the temporary register value. In ps_1_4 and
360  * ps_2_0 t0 is always a varying and temporaries can
361  * be used with texkill.
362  */
363  instr->dst = map_oldps_register(dst, TRUE);
364  instr->has_dst = TRUE;
365 
366  if(!add_instruction(This->shader, instr)) {
367  ERR("Out of memory\n");
368  set_parse_status(&This->status, PARSE_ERR);
369  }
370 }
371 
373  const struct shader_reg *dst,
374  const struct shader_reg *src0) {
375  struct instruction *instr = alloc_instr(2);
376 
377  if(!instr) {
378  ERR("Error allocating memory for the instruction\n");
379  set_parse_status(&This->status, PARSE_ERR);
380  return;
381  }
382 
383  instr->opcode = BWRITERSIO_TEX;
384  instr->dstmod = mod;
385  instr->shift = shift;
386  instr->comptype = 0;
387  /* The dest register can be mapped normally to a temporary register */
388  This->funcs->dstreg(This, instr, dst);
389  /* Use the src passed as parameter by the specific instruction handler */
390  instr->src[0] = *src0;
391 
392  /* The 2nd source register is the sampler register with the
393  * destination's regnum
394  */
395  ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
396  instr->src[1].type = BWRITERSPR_SAMPLER;
397  instr->src[1].regnum = dst->regnum;
398  instr->src[1].u.swizzle = BWRITERVS_NOSWIZZLE;
399  instr->src[1].srcmod = BWRITERSPSM_NONE;
400  instr->src[1].rel_reg = NULL;
401 
402  if(!add_instruction(This->shader, instr)) {
403  ERR("Out of memory\n");
404  set_parse_status(&This->status, PARSE_ERR);
405  }
406 }
407 
409  const struct shader_reg *dst) {
410  struct shader_reg src;
411 
412  /* The first source register is the varying containing the coordinate */
415 }
416 
418  const struct shader_reg *dst,
419  const struct src_regs *srcs) {
420  struct instruction *instr;
421 
422  if(!srcs || srcs->count != 1) {
423  asmparser_message(This, "Line %u: texld (PS 1.4) has a wrong number of source registers\n", This->line_no);
424  set_parse_status(&This->status, PARSE_ERR);
425  return;
426  }
427 
428  instr = alloc_instr(2);
429  if(!instr) {
430  ERR("Error allocating memory for the instruction\n");
431  set_parse_status(&This->status, PARSE_ERR);
432  return;
433  }
434 
435  /* This code is recording a texld instruction, not tex. However,
436  * texld borrows the opcode of tex
437  */
438  instr->opcode = BWRITERSIO_TEX;
439  instr->dstmod = mod;
440  instr->shift = shift;
441  instr->comptype = 0;
442 
443  This->funcs->dstreg(This, instr, dst);
444  This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
445 
446  /* The 2nd source register is the sampler register with the
447  * destination's regnum
448  */
449  ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
450  instr->src[1].type = BWRITERSPR_SAMPLER;
451  instr->src[1].regnum = dst->regnum;
452  instr->src[1].u.swizzle = BWRITERVS_NOSWIZZLE;
453  instr->src[1].srcmod = BWRITERSPSM_NONE;
454  instr->src[1].rel_reg = NULL;
455 
456  if(!add_instruction(This->shader, instr)) {
457  ERR("Out of memory\n");
458  set_parse_status(&This->status, PARSE_ERR);
459  }
460 }
461 
463  const struct shader_reg *dst,
464  const struct shader_reg *src0) {
465  struct shader_reg src;
466 
467  src = map_oldps_register(src0, FALSE);
468  /* Supply the correct swizzle */
471 }
472 
474  const struct shader_reg *dst,
475  const struct shader_reg *src0) {
476  struct shader_reg src;
477 
478  src = map_oldps_register(src0, FALSE);
479  /* Supply the correct swizzle */
482 }
483 
485  const struct shader_reg *dst,
486  const struct shader_reg *src0) {
487  struct shader_reg src;
488 
489  src = map_oldps_register(src0, FALSE);
490  /* Supply the correct swizzle */
493 }
494 
495 /* Complex pixel shader 1.3 instructions like texm3x3tex are tricky - the
496  * bytecode writer works instruction by instruction, so we can't properly
497  * convert these from/to equivalent ps_3_0 instructions. Then simply keep using
498  * the ps_1_3 opcodes and just adapt the registers in the common fashion (i.e.
499  * go through asmparser_instr).
500  */
501 
502 static void asmparser_instr(struct asm_parser *This, DWORD opcode, DWORD mod, DWORD shift,
503  enum bwriter_comparison_type comp, const struct shader_reg *dst,
504  const struct src_regs *srcs, int expectednsrcs)
505 {
506  struct instruction *instr;
507  unsigned int i;
508  BOOL firstreg = TRUE;
509  unsigned int src_count = srcs ? srcs->count : 0;
510 
511  if(!This->shader) return;
512 
513  TRACE_(parsed_shader)("%s%s%s%s ", debug_print_opcode(opcode),
516  debug_print_comp(comp));
517  if(dst) {
518  TRACE_(parsed_shader)("%s", debug_print_dstreg(dst));
519  firstreg = FALSE;
520  }
521  for(i = 0; i < src_count; i++) {
522  if(!firstreg) TRACE_(parsed_shader)(", ");
523  else firstreg = FALSE;
524  TRACE_(parsed_shader)("%s", debug_print_srcreg(&srcs->reg[i]));
525  }
526  TRACE_(parsed_shader)("\n");
527 
528  /* Check for instructions with different syntaxes in different shader versions */
529  switch(opcode) {
530  case BWRITERSIO_SINCOS:
531  /* The syntax changes between vs 2 and the other shader versions */
532  if(This->shader->version == BWRITERVS_VERSION(2, 0) ||
533  This->shader->version == BWRITERVS_VERSION(2, 1)) {
534  asmparser_sincos(This, mod, shift, dst, srcs);
535  return;
536  }
537  /* Use the default handling */
538  break;
539  case BWRITERSIO_TEXCOORD:
540  /* texcoord/texcrd are two instructions present only in PS <= 1.3 and PS 1.4 respectively */
541  if(This->shader->version == BWRITERPS_VERSION(1, 4))
542  asmparser_texcrd(This, mod, shift, dst, srcs);
543  else asmparser_texcoord(This, mod, shift, dst, srcs);
544  return;
545  case BWRITERSIO_TEX:
546  /* this encodes both the tex PS 1.x instruction and the
547  texld 1.4/2.0+ instruction */
548  if(This->shader->version == BWRITERPS_VERSION(1, 0) ||
549  This->shader->version == BWRITERPS_VERSION(1, 1) ||
550  This->shader->version == BWRITERPS_VERSION(1, 2) ||
551  This->shader->version == BWRITERPS_VERSION(1, 3)) {
553  return;
554  }
555  else if(This->shader->version == BWRITERPS_VERSION(1, 4)) {
556  asmparser_texld14(This, mod, shift, dst, srcs);
557  return;
558  }
559  /* else fallback to the standard behavior */
560  break;
561  }
562 
563  if(src_count != expectednsrcs) {
564  asmparser_message(This, "Line %u: Wrong number of source registers\n", This->line_no);
565  set_parse_status(&This->status, PARSE_ERR);
566  return;
567  }
568 
569  /* Handle PS 1.x instructions, "regularizing" them */
570  switch(opcode) {
571  case BWRITERSIO_TEXKILL:
573  return;
575  asmparser_texreg2ar(This, mod, shift, dst, &srcs->reg[0]);
576  return;
578  asmparser_texreg2gb(This, mod, shift, dst, &srcs->reg[0]);
579  return;
581  asmparser_texreg2rgb(This, mod, shift, dst, &srcs->reg[0]);
582  return;
583  }
584 
585  instr = alloc_instr(src_count);
586  if(!instr) {
587  ERR("Error allocating memory for the instruction\n");
588  set_parse_status(&This->status, PARSE_ERR);
589  return;
590  }
591 
592  instr->opcode = opcode;
593  instr->dstmod = mod;
594  instr->shift = shift;
595  instr->comptype = comp;
596  if(dst) This->funcs->dstreg(This, instr, dst);
597  for(i = 0; i < src_count; i++) {
598  This->funcs->srcreg(This, instr, i, &srcs->reg[i]);
599  }
600 
601  if(!add_instruction(This->shader, instr)) {
602  ERR("Out of memory\n");
603  set_parse_status(&This->status, PARSE_ERR);
604  }
605 }
606 
608  struct shader_reg ret;
609  switch(reg->type) {
610  case BWRITERSPR_RASTOUT:
611  ret = *reg;
612  ret.type = BWRITERSPR_OUTPUT;
613  switch(reg->regnum) {
614  case BWRITERSRO_POSITION:
615  ret.regnum = OPOS_REG;
616  break;
617  case BWRITERSRO_FOG:
618  ret.regnum = OFOG_REG;
619  ret.u.writemask = OFOG_WRITEMASK;
620  break;
622  ret.regnum = OPTS_REG;
623  ret.u.writemask = OPTS_WRITEMASK;
624  break;
625  default:
626  FIXME("Unhandled RASTOUT register %u\n", reg->regnum);
627  return *reg;
628  }
629  return ret;
630 
632  ret = *reg;
633  ret.type = BWRITERSPR_OUTPUT;
634  switch(reg->regnum) {
635  case 0: ret.regnum = OT0_REG; break;
636  case 1: ret.regnum = OT1_REG; break;
637  case 2: ret.regnum = OT2_REG; break;
638  case 3: ret.regnum = OT3_REG; break;
639  case 4: ret.regnum = OT4_REG; break;
640  case 5: ret.regnum = OT5_REG; break;
641  case 6: ret.regnum = OT6_REG; break;
642  case 7: ret.regnum = OT7_REG; break;
643  default:
644  FIXME("Unhandled TEXCRDOUT regnum %u\n", reg->regnum);
645  return *reg;
646  }
647  return ret;
648 
649  case BWRITERSPR_ATTROUT:
650  ret = *reg;
651  ret.type = BWRITERSPR_OUTPUT;
652  switch(reg->regnum) {
653  case 0: ret.regnum = OD0_REG; break;
654  case 1: ret.regnum = OD1_REG; break;
655  default:
656  FIXME("Unhandled ATTROUT regnum %u\n", reg->regnum);
657  return *reg;
658  }
659  return ret;
660 
661  default: return *reg;
662  }
663 }
664 
665 /* Checks for unsupported source modifiers in VS (all versions) or
666  PS 2.0 and newer */
672  srcmod == BWRITERSPSM_DW) {
673  asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
674  This->line_no,
676  set_parse_status(&This->status, PARSE_ERR);
677  }
678 }
679 
680 static void check_abs_srcmod(struct asm_parser *This, DWORD srcmod) {
682  asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
683  This->line_no,
685  set_parse_status(&This->status, PARSE_ERR);
686  }
687 }
688 
689 static void check_loop_swizzle(struct asm_parser *This,
690  const struct shader_reg *src) {
691  if((src->type == BWRITERSPR_LOOP && src->u.swizzle != BWRITERVS_NOSWIZZLE) ||
692  (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
693  src->rel_reg->u.swizzle != BWRITERVS_NOSWIZZLE)) {
694  asmparser_message(This, "Line %u: Swizzle not allowed on aL register\n", This->line_no);
695  set_parse_status(&This->status, PARSE_ERR);
696  }
697 }
698 
700  if(shift != 0) {
701  asmparser_message(This, "Line %u: Shift modifiers not supported in this shader version\n",
702  This->line_no);
703  set_parse_status(&This->status, PARSE_ERR);
704  }
705 }
706 
707 static void check_ps_dstmod(struct asm_parser *This, DWORD dstmod) {
708  if(dstmod == BWRITERSPDM_PARTIALPRECISION ||
709  dstmod == BWRITERSPDM_MSAMPCENTROID) {
710  asmparser_message(This, "Line %u: Instruction modifier %s not supported in this shader version\n",
711  This->line_no,
712  debug_print_dstmod(dstmod));
713  set_parse_status(&This->status, PARSE_ERR);
714  }
715 }
716 
721 };
722 
723 static BOOL check_reg_type(const struct shader_reg *reg,
724  const struct allowed_reg_type *allowed) {
725  unsigned int i = 0;
726 
727  while(allowed[i].type != ~0U) {
728  if(reg->type == allowed[i].type) {
729  if(reg->rel_reg) {
730  if(allowed[i].reladdr)
731  return TRUE; /* The relative addressing register
732  can have a negative value, we
733  can't check the register index */
734  return FALSE;
735  }
736  if(reg->regnum < allowed[i].count) return TRUE;
737  return FALSE;
738  }
739  i++;
740  }
741  return FALSE;
742 }
743 
744 /* Native assembler doesn't do separate checks for src and dst registers */
745 static const struct allowed_reg_type vs_1_reg_allowed[] = {
746  { BWRITERSPR_TEMP, 12, FALSE },
747  { BWRITERSPR_INPUT, 16, FALSE },
748  { BWRITERSPR_CONST, ~0U, TRUE },
749  { BWRITERSPR_ADDR, 1, FALSE },
750  { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
751  { BWRITERSPR_ATTROUT, 2, FALSE },
752  { BWRITERSPR_TEXCRDOUT, 8, FALSE },
753  { ~0U, 0 } /* End tag */
754 };
755 
756 /* struct instruction *asmparser_srcreg
757  *
758  * Records a source register in the instruction and does shader version
759  * specific checks and modifications on it
760  *
761  * Parameters:
762  * This: Shader parser instance
763  * instr: instruction to store the register in
764  * num: Number of source register
765  * src: Pointer to source the register structure. The caller can free
766  * it afterwards
767  */
769  struct instruction *instr, int num,
770  const struct shader_reg *src) {
771  struct shader_reg reg;
772 
774  asmparser_message(This, "Line %u: Source register %s not supported in VS 1\n",
775  This->line_no,
777  set_parse_status(&This->status, PARSE_ERR);
778  }
779  check_legacy_srcmod(This, src->srcmod);
780  check_abs_srcmod(This, src->srcmod);
782  instr->src[num] = reg;
783 }
784 
785 static const struct allowed_reg_type vs_2_reg_allowed[] = {
786  { BWRITERSPR_TEMP, 12, FALSE },
787  { BWRITERSPR_INPUT, 16, FALSE },
788  { BWRITERSPR_CONST, ~0U, TRUE },
789  { BWRITERSPR_ADDR, 1, FALSE },
790  { BWRITERSPR_CONSTBOOL, 16, FALSE },
791  { BWRITERSPR_CONSTINT, 16, FALSE },
792  { BWRITERSPR_LOOP, 1, FALSE },
793  { BWRITERSPR_LABEL, 2048, FALSE },
794  { BWRITERSPR_PREDICATE, 1, FALSE },
795  { BWRITERSPR_RASTOUT, 3, FALSE }, /* oPos, oFog and oPts */
796  { BWRITERSPR_ATTROUT, 2, FALSE },
797  { BWRITERSPR_TEXCRDOUT, 8, FALSE },
798  { ~0U, 0 } /* End tag */
799 };
800 
802  struct instruction *instr, int num,
803  const struct shader_reg *src) {
804  struct shader_reg reg;
805 
807  asmparser_message(This, "Line %u: Source register %s not supported in VS 2\n",
808  This->line_no,
810  set_parse_status(&This->status, PARSE_ERR);
811  }
813  check_legacy_srcmod(This, src->srcmod);
814  check_abs_srcmod(This, src->srcmod);
816  instr->src[num] = reg;
817 }
818 
819 static const struct allowed_reg_type vs_3_reg_allowed[] = {
820  { BWRITERSPR_TEMP, 32, FALSE },
821  { BWRITERSPR_INPUT, 16, TRUE },
822  { BWRITERSPR_CONST, ~0U, TRUE },
823  { BWRITERSPR_ADDR, 1, FALSE },
824  { BWRITERSPR_CONSTBOOL, 16, FALSE },
825  { BWRITERSPR_CONSTINT, 16, FALSE },
826  { BWRITERSPR_LOOP, 1, FALSE },
827  { BWRITERSPR_LABEL, 2048, FALSE },
828  { BWRITERSPR_PREDICATE, 1, FALSE },
829  { BWRITERSPR_SAMPLER, 4, FALSE },
830  { BWRITERSPR_OUTPUT, 12, TRUE },
831  { ~0U, 0 } /* End tag */
832 };
833 
835  struct instruction *instr, int num,
836  const struct shader_reg *src) {
838  asmparser_message(This, "Line %u: Source register %s not supported in VS 3.0\n",
839  This->line_no,
841  set_parse_status(&This->status, PARSE_ERR);
842  }
844  check_legacy_srcmod(This, src->srcmod);
845  instr->src[num] = *src;
846 }
847 
848 static const struct allowed_reg_type ps_1_0123_reg_allowed[] = {
849  { BWRITERSPR_CONST, 8, FALSE },
850  { BWRITERSPR_TEMP, 2, FALSE },
851  { BWRITERSPR_TEXTURE, 4, FALSE },
852  { BWRITERSPR_INPUT, 2, FALSE },
853  { ~0U, 0 } /* End tag */
854 };
855 
857  struct instruction *instr, int num,
858  const struct shader_reg *src) {
859  struct shader_reg reg;
860 
862  asmparser_message(This, "Line %u: Source register %s not supported in <== PS 1.3\n",
863  This->line_no,
865  set_parse_status(&This->status, PARSE_ERR);
866  }
867  check_abs_srcmod(This, src->srcmod);
869  instr->src[num] = reg;
870 }
871 
872 static const struct allowed_reg_type ps_1_4_reg_allowed[] = {
873  { BWRITERSPR_CONST, 8, FALSE },
874  { BWRITERSPR_TEMP, 6, FALSE },
875  { BWRITERSPR_TEXTURE, 6, FALSE },
876  { BWRITERSPR_INPUT, 2, FALSE },
877  { ~0U, 0 } /* End tag */
878 };
879 
881  struct instruction *instr, int num,
882  const struct shader_reg *src) {
883  struct shader_reg reg;
884 
886  asmparser_message(This, "Line %u: Source register %s not supported in PS 1.4\n",
887  This->line_no,
889  set_parse_status(&This->status, PARSE_ERR);
890  }
891  check_abs_srcmod(This, src->srcmod);
893  instr->src[num] = reg;
894 }
895 
896 static const struct allowed_reg_type ps_2_0_reg_allowed[] = {
897  { BWRITERSPR_INPUT, 2, FALSE },
898  { BWRITERSPR_TEMP, 32, FALSE },
899  { BWRITERSPR_CONST, 32, FALSE },
900  { BWRITERSPR_CONSTINT, 16, FALSE },
901  { BWRITERSPR_CONSTBOOL, 16, FALSE },
902  { BWRITERSPR_SAMPLER, 16, FALSE },
903  { BWRITERSPR_TEXTURE, 8, FALSE },
904  { BWRITERSPR_COLOROUT, 4, FALSE },
905  { BWRITERSPR_DEPTHOUT, 1, FALSE },
906  { ~0U, 0 } /* End tag */
907 };
908 
910  struct instruction *instr, int num,
911  const struct shader_reg *src) {
912  struct shader_reg reg;
913 
915  asmparser_message(This, "Line %u: Source register %s not supported in PS 2.0\n",
916  This->line_no,
918  set_parse_status(&This->status, PARSE_ERR);
919  }
920  check_legacy_srcmod(This, src->srcmod);
921  check_abs_srcmod(This, src->srcmod);
923  instr->src[num] = reg;
924 }
925 
926 static const struct allowed_reg_type ps_2_x_reg_allowed[] = {
927  { BWRITERSPR_INPUT, 2, FALSE },
928  { BWRITERSPR_TEMP, 32, FALSE },
929  { BWRITERSPR_CONST, 32, FALSE },
930  { BWRITERSPR_CONSTINT, 16, FALSE },
931  { BWRITERSPR_CONSTBOOL, 16, FALSE },
932  { BWRITERSPR_PREDICATE, 1, FALSE },
933  { BWRITERSPR_SAMPLER, 16, FALSE },
934  { BWRITERSPR_TEXTURE, 8, FALSE },
935  { BWRITERSPR_LABEL, 2048, FALSE },
936  { BWRITERSPR_COLOROUT, 4, FALSE },
937  { BWRITERSPR_DEPTHOUT, 1, FALSE },
938  { ~0U, 0 } /* End tag */
939 };
940 
942  struct instruction *instr, int num,
943  const struct shader_reg *src) {
944  struct shader_reg reg;
945 
947  asmparser_message(This, "Line %u: Source register %s not supported in PS 2.x\n",
948  This->line_no,
950  set_parse_status(&This->status, PARSE_ERR);
951  }
952  check_legacy_srcmod(This, src->srcmod);
953  check_abs_srcmod(This, src->srcmod);
955  instr->src[num] = reg;
956 }
957 
958 static const struct allowed_reg_type ps_3_reg_allowed[] = {
959  { BWRITERSPR_INPUT, 10, TRUE },
960  { BWRITERSPR_TEMP, 32, FALSE },
961  { BWRITERSPR_CONST, 224, FALSE },
962  { BWRITERSPR_CONSTINT, 16, FALSE },
963  { BWRITERSPR_CONSTBOOL, 16, FALSE },
964  { BWRITERSPR_PREDICATE, 1, FALSE },
965  { BWRITERSPR_SAMPLER, 16, FALSE },
966  { BWRITERSPR_MISCTYPE, 2, FALSE }, /* vPos and vFace */
967  { BWRITERSPR_LOOP, 1, FALSE },
968  { BWRITERSPR_LABEL, 2048, FALSE },
969  { BWRITERSPR_COLOROUT, 4, FALSE },
970  { BWRITERSPR_DEPTHOUT, 1, FALSE },
971  { ~0U, 0 } /* End tag */
972 };
973 
975  struct instruction *instr, int num,
976  const struct shader_reg *src) {
978  asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
979  This->line_no,
981  set_parse_status(&This->status, PARSE_ERR);
982  }
984  check_legacy_srcmod(This, src->srcmod);
985  instr->src[num] = *src;
986 }
987 
989  struct instruction *instr,
990  const struct shader_reg *dst) {
991  struct shader_reg reg;
992 
994  asmparser_message(This, "Line %u: Destination register %s not supported in VS 1\n",
995  This->line_no,
997  set_parse_status(&This->status, PARSE_ERR);
998  }
999  check_ps_dstmod(This, instr->dstmod);
1000  check_shift_dstmod(This, instr->shift);
1002  instr->dst = reg;
1003  instr->has_dst = TRUE;
1004 }
1005 
1007  struct instruction *instr,
1008  const struct shader_reg *dst) {
1009  struct shader_reg reg;
1010 
1012  asmparser_message(This, "Line %u: Destination register %s not supported in VS 2.0\n",
1013  This->line_no,
1015  set_parse_status(&This->status, PARSE_ERR);
1016  }
1017  check_ps_dstmod(This, instr->dstmod);
1018  check_shift_dstmod(This, instr->shift);
1020  instr->dst = reg;
1021  instr->has_dst = TRUE;
1022 }
1023 
1025  struct instruction *instr,
1026  const struct shader_reg *dst) {
1028  asmparser_message(This, "Line %u: Destination register %s not supported in VS 3.0\n",
1029  This->line_no,
1031  set_parse_status(&This->status, PARSE_ERR);
1032  }
1033  check_ps_dstmod(This, instr->dstmod);
1034  check_shift_dstmod(This, instr->shift);
1035  instr->dst = *dst;
1036  instr->has_dst = TRUE;
1037 }
1038 
1040  struct instruction *instr,
1041  const struct shader_reg *dst) {
1042  struct shader_reg reg;
1043 
1045  asmparser_message(This, "Line %u: Destination register %s not supported in PS 1\n",
1046  This->line_no,
1048  set_parse_status(&This->status, PARSE_ERR);
1049  }
1051  instr->dst = reg;
1052  instr->has_dst = TRUE;
1053 }
1054 
1056  struct instruction *instr,
1057  const struct shader_reg *dst) {
1058  struct shader_reg reg;
1059 
1061  asmparser_message(This, "Line %u: Destination register %s not supported in PS 1\n",
1062  This->line_no,
1064  set_parse_status(&This->status, PARSE_ERR);
1065  }
1067  instr->dst = reg;
1068  instr->has_dst = TRUE;
1069 }
1070 
1072  struct instruction *instr,
1073  const struct shader_reg *dst) {
1074  struct shader_reg reg;
1075 
1077  asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.0\n",
1078  This->line_no,
1080  set_parse_status(&This->status, PARSE_ERR);
1081  }
1082  check_shift_dstmod(This, instr->shift);
1084  instr->dst = reg;
1085  instr->has_dst = TRUE;
1086 }
1087 
1089  struct instruction *instr,
1090  const struct shader_reg *dst) {
1091  struct shader_reg reg;
1092 
1094  asmparser_message(This, "Line %u: Destination register %s not supported in PS 2.x\n",
1095  This->line_no,
1097  set_parse_status(&This->status, PARSE_ERR);
1098  }
1099  check_shift_dstmod(This, instr->shift);
1101  instr->dst = reg;
1102  instr->has_dst = TRUE;
1103 }
1104 
1106  struct instruction *instr,
1107  const struct shader_reg *dst) {
1109  asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
1110  This->line_no,
1112  set_parse_status(&This->status, PARSE_ERR);
1113  }
1114  check_shift_dstmod(This, instr->shift);
1115  instr->dst = *dst;
1116  instr->has_dst = TRUE;
1117 }
1118 
1120  const struct shader_reg *predicate) {
1121  /* this sets the predicate of the last instruction added to the shader */
1122  if(!This->shader) return;
1123  if(This->shader->num_instrs == 0) ERR("Predicate without an instruction\n");
1124  This->shader->instr[This->shader->num_instrs - 1]->has_predicate = TRUE;
1125  This->shader->instr[This->shader->num_instrs - 1]->predicate = *predicate;
1126 }
1127 
1129  const struct shader_reg *predicate) {
1130  asmparser_message(This, "Line %u: Predicate not supported in < VS 2.0 or PS 2.x\n", This->line_no);
1131  set_parse_status(&This->status, PARSE_ERR);
1132 }
1133 
1135  /* this sets the coissue flag of the last instruction added to the shader */
1136  if(!This->shader) return;
1137  if(This->shader->num_instrs == 0){
1138  asmparser_message(This, "Line %u: Coissue flag on the first shader instruction\n", This->line_no);
1139  set_parse_status(&This->status, PARSE_ERR);
1140  }
1141  This->shader->instr[This->shader->num_instrs-1]->coissue = TRUE;
1142 }
1143 
1145  asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
1146  set_parse_status(&This->status, PARSE_ERR);
1147 }
1148 
1149 static const struct asmparser_backend parser_vs_1 = {
1153 
1156 
1159 
1163 
1164  asmparser_end,
1165 
1167 };
1168 
1169 static const struct asmparser_backend parser_vs_2 = {
1173 
1176 
1179 
1183 
1184  asmparser_end,
1185 
1187 };
1188 
1189 static const struct asmparser_backend parser_vs_3 = {
1193 
1196 
1199 
1203 
1204  asmparser_end,
1205 
1207 };
1208 
1209 static const struct asmparser_backend parser_ps_1_0123 = {
1213 
1216 
1219 
1223 
1224  asmparser_end,
1225 
1227 };
1228 
1229 static const struct asmparser_backend parser_ps_1_4 = {
1233 
1236 
1239 
1243 
1244  asmparser_end,
1245 
1247 };
1248 
1249 static const struct asmparser_backend parser_ps_2 = {
1253 
1256 
1259 
1263 
1264  asmparser_end,
1265 
1267 };
1268 
1269 static const struct asmparser_backend parser_ps_2_x = {
1273 
1276 
1279 
1283 
1284  asmparser_end,
1285 
1287 };
1288 
1289 static const struct asmparser_backend parser_ps_3 = {
1293 
1296 
1299 
1303 
1304  asmparser_end,
1305 
1307 };
1308 
1323 }
1324 
1325 static void gen_oldps_input(struct bwriter_shader *shader, DWORD texcoords) {
1326  switch(texcoords) {
1328  /* fall through */
1330  /* fall through */
1332  /* fall through */
1334  /* fall through */
1336  /* fall through */
1338  /* fall through */
1340  /* fall through */
1342  };
1345 }
1346 
1348  TRACE_(parsed_shader)("vs_1_0\n");
1349 
1350  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1351  if(!ret->shader) {
1352  ERR("Failed to allocate memory for the shader\n");
1353  set_parse_status(&ret->status, PARSE_ERR);
1354  return;
1355  }
1356 
1357  ret->shader->type = ST_VERTEX;
1358  ret->shader->version = BWRITERVS_VERSION(1, 0);
1359  ret->funcs = &parser_vs_1;
1360  gen_oldvs_output(ret->shader);
1361 }
1362 
1364  TRACE_(parsed_shader)("vs_1_1\n");
1365 
1366  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1367  if(!ret->shader) {
1368  ERR("Failed to allocate memory for the shader\n");
1369  set_parse_status(&ret->status, PARSE_ERR);
1370  return;
1371  }
1372 
1373  ret->shader->type = ST_VERTEX;
1374  ret->shader->version = BWRITERVS_VERSION(1, 1);
1375  ret->funcs = &parser_vs_1;
1376  gen_oldvs_output(ret->shader);
1377 }
1378 
1380  TRACE_(parsed_shader)("vs_2_0\n");
1381 
1382  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1383  if(!ret->shader) {
1384  ERR("Failed to allocate memory for the shader\n");
1385  set_parse_status(&ret->status, PARSE_ERR);
1386  return;
1387  }
1388 
1389  ret->shader->type = ST_VERTEX;
1390  ret->shader->version = BWRITERVS_VERSION(2, 0);
1391  ret->funcs = &parser_vs_2;
1392  gen_oldvs_output(ret->shader);
1393 }
1394 
1396  TRACE_(parsed_shader)("vs_2_x\n");
1397 
1398  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1399  if(!ret->shader) {
1400  ERR("Failed to allocate memory for the shader\n");
1401  set_parse_status(&ret->status, PARSE_ERR);
1402  return;
1403  }
1404 
1405  ret->shader->type = ST_VERTEX;
1406  ret->shader->version = BWRITERVS_VERSION(2, 1);
1407  ret->funcs = &parser_vs_2;
1408  gen_oldvs_output(ret->shader);
1409 }
1410 
1412  TRACE_(parsed_shader)("vs_3_0\n");
1413 
1414  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1415  if(!ret->shader) {
1416  ERR("Failed to allocate memory for the shader\n");
1417  set_parse_status(&ret->status, PARSE_ERR);
1418  return;
1419  }
1420 
1421  ret->shader->type = ST_VERTEX;
1422  ret->shader->version = BWRITERVS_VERSION(3, 0);
1423  ret->funcs = &parser_vs_3;
1424 }
1425 
1427  TRACE_(parsed_shader)("ps_1_0\n");
1428 
1429  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1430  if(!ret->shader) {
1431  ERR("Failed to allocate memory for the shader\n");
1432  set_parse_status(&ret->status, PARSE_ERR);
1433  return;
1434  }
1435 
1436  ret->shader->type = ST_PIXEL;
1437  ret->shader->version = BWRITERPS_VERSION(1, 0);
1438  ret->funcs = &parser_ps_1_0123;
1439  gen_oldps_input(ret->shader, 4);
1440 }
1441 
1443  TRACE_(parsed_shader)("ps_1_1\n");
1444 
1445  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1446  if(!ret->shader) {
1447  ERR("Failed to allocate memory for the shader\n");
1448  set_parse_status(&ret->status, PARSE_ERR);
1449  return;
1450  }
1451 
1452  ret->shader->type = ST_PIXEL;
1453  ret->shader->version = BWRITERPS_VERSION(1, 1);
1454  ret->funcs = &parser_ps_1_0123;
1455  gen_oldps_input(ret->shader, 4);
1456 }
1457 
1459  TRACE_(parsed_shader)("ps_1_2\n");
1460 
1461  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1462  if(!ret->shader) {
1463  ERR("Failed to allocate memory for the shader\n");
1464  set_parse_status(&ret->status, PARSE_ERR);
1465  return;
1466  }
1467 
1468  ret->shader->type = ST_PIXEL;
1469  ret->shader->version = BWRITERPS_VERSION(1, 2);
1470  ret->funcs = &parser_ps_1_0123;
1471  gen_oldps_input(ret->shader, 4);
1472 }
1473 
1475  TRACE_(parsed_shader)("ps_1_3\n");
1476 
1477  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1478  if(!ret->shader) {
1479  ERR("Failed to allocate memory for the shader\n");
1480  set_parse_status(&ret->status, PARSE_ERR);
1481  return;
1482  }
1483 
1484  ret->shader->type = ST_PIXEL;
1485  ret->shader->version = BWRITERPS_VERSION(1, 3);
1486  ret->funcs = &parser_ps_1_0123;
1487  gen_oldps_input(ret->shader, 4);
1488 }
1489 
1491  TRACE_(parsed_shader)("ps_1_4\n");
1492 
1493  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1494  if(!ret->shader) {
1495  ERR("Failed to allocate memory for the shader\n");
1496  set_parse_status(&ret->status, PARSE_ERR);
1497  return;
1498  }
1499 
1500  ret->shader->type = ST_PIXEL;
1501  ret->shader->version = BWRITERPS_VERSION(1, 4);
1502  ret->funcs = &parser_ps_1_4;
1503  gen_oldps_input(ret->shader, 6);
1504 }
1505 
1507  TRACE_(parsed_shader)("ps_2_0\n");
1508 
1509  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1510  if(!ret->shader) {
1511  ERR("Failed to allocate memory for the shader\n");
1512  set_parse_status(&ret->status, PARSE_ERR);
1513  return;
1514  }
1515 
1516  ret->shader->type = ST_PIXEL;
1517  ret->shader->version = BWRITERPS_VERSION(2, 0);
1518  ret->funcs = &parser_ps_2;
1519  gen_oldps_input(ret->shader, 8);
1520 }
1521 
1523  TRACE_(parsed_shader)("ps_2_x\n");
1524 
1525  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1526  if(!ret->shader) {
1527  ERR("Failed to allocate memory for the shader\n");
1528  set_parse_status(&ret->status, PARSE_ERR);
1529  return;
1530  }
1531 
1532  ret->shader->type = ST_PIXEL;
1533  ret->shader->version = BWRITERPS_VERSION(2, 1);
1534  ret->funcs = &parser_ps_2_x;
1535  gen_oldps_input(ret->shader, 8);
1536 }
1537 
1539  TRACE_(parsed_shader)("ps_3_0\n");
1540 
1541  ret->shader = d3dcompiler_alloc(sizeof(*ret->shader));
1542  if(!ret->shader) {
1543  ERR("Failed to allocate memory for the shader\n");
1544  set_parse_status(&ret->status, PARSE_ERR);
1545  return;
1546  }
1547 
1548  ret->shader->type = ST_PIXEL;
1549  ret->shader->version = BWRITERPS_VERSION(3, 0);
1550  ret->funcs = &parser_ps_3;
1551 }
#define BWRITERVS_Y_X
BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, DWORD mod, BOOL output, DWORD regnum, DWORD writemask, BOOL builtin)
#define T1_VARYING
Definition: asmparser.c:58
WINE_DEFAULT_DEBUG_CHANNEL(asmshader)
BOOL add_constI(struct bwriter_shader *shader, DWORD reg, INT x, INT y, INT z, INT w)
static void asmparser_srcreg_ps_1_4(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:880
const char * debug_print_opcode(DWORD opcode) DECLSPEC_HIDDEN
Definition: utils.c:416
static void asmparser_texcoord(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct src_regs *srcs)
Definition: asmparser.c:271
static void asmparser_coissue_unsupported(struct asm_parser *This)
Definition: asmparser.c:1144
static void gen_oldps_input(struct bwriter_shader *shader, DWORD texcoords)
Definition: asmparser.c:1325
static void asmparser_constB(struct asm_parser *This, DWORD reg, BOOL x)
Definition: asmparser.c:84
static void asmparser_dcl_input_unsupported(struct asm_parser *This, DWORD usage, DWORD num, DWORD mod, const struct shader_reg *reg)
Definition: asmparser.c:162
#define OT4_REG
Definition: asmparser.c:42
#define TRUE
Definition: types.h:120
#define shift
Definition: input.c:1668
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static void asmparser_dstreg_ps_2_x(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1088
static void asmparser_texhelper(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct shader_reg *src0)
Definition: asmparser.c:372
#define BWRITERSP_WRITEMASK_ALL
const char * debug_print_shift(DWORD shift) DECLSPEC_HIDDEN
Definition: utils.c:178
static const struct allowed_reg_type ps_2_x_reg_allowed[]
Definition: asmparser.c:926
#define OT3_REG
Definition: asmparser.c:41
struct x86_inst instr
static void asmparser_texreg2ar(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct shader_reg *src0)
Definition: asmparser.c:462
static void asmparser_srcreg_vs_1(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:768
static const struct allowed_reg_type ps_1_0123_reg_allowed[]
Definition: asmparser.c:848
bwriter_comparison_type
static void check_legacy_srcmod(struct asm_parser *This, DWORD srcmod)
Definition: asmparser.c:667
#define U(x)
Definition: wordpad.c:44
static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w)
Definition: asmparser.c:74
static void asmparser_texreg2rgb(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct shader_reg *src0)
Definition: asmparser.c:484
void create_vs2x_parser(struct asm_parser *ret)
Definition: asmparser.c:1395
struct instruction * alloc_instr(unsigned int srcs)
void WINAPIV asmparser_message(struct asm_parser *ctx, const char *fmt,...)
Definition: asmshader.tab.c:87
static const struct asmparser_backend parser_ps_1_0123
Definition: asmparser.c:1209
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
BOOL add_constB(struct bwriter_shader *shader, DWORD reg, BOOL x)
#define ZeroMemory
Definition: winbase.h:1642
static void asmparser_predicate_supported(struct asm_parser *This, const struct shader_reg *predicate)
Definition: asmparser.c:1119
#define C1_VARYING
Definition: asmparser.c:56
#define T1_REG
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void asmparser_tex(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst)
Definition: asmparser.c:408
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr)
#define OD1_REG
Definition: asmparser.c:52
void create_ps12_parser(struct asm_parser *ret)
Definition: asmparser.c:1458
#define OPTS_REG
Definition: asmparser.c:49
static void asmparser_dstreg_vs_2(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1006
void create_vs10_parser(struct asm_parser *ret)
Definition: asmparser.c:1347
int32_t INT
Definition: typedefs.h:56
#define OFOG_WRITEMASK
Definition: asmparser.c:48
#define BWRITERVS_Z_Z
static void asmparser_srcreg_ps_1_0123(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:856
static void * d3dcompiler_alloc(SIZE_T size)
void create_ps10_parser(struct asm_parser *ret)
Definition: asmparser.c:1426
#define OT7_REG
Definition: asmparser.c:45
static const struct asmparser_backend parser_ps_2
Definition: asmparser.c:1249
#define OT5_REG
Definition: asmparser.c:43
const char * debug_print_srcmod(DWORD mod) DECLSPEC_HIDDEN
Definition: utils.c:128
#define BWRITERVS_X_X
#define T0_VARYING
Definition: asmparser.c:57
BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD mod, DWORD regnum)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static BOOL check_reg_type(const struct shader_reg *reg, const struct allowed_reg_type *allowed)
Definition: asmparser.c:723
unsigned int BOOL
Definition: ntddk_ex.h:94
static void asmparser_dcl_sampler_unsupported(struct asm_parser *This, DWORD samptype, DWORD mod, DWORD regnum, unsigned int line_no)
Definition: asmparser.c:187
static void asmparser_texkill(struct asm_parser *This, const struct shader_reg *dst)
Definition: asmparser.c:341
#define FIXME(fmt,...)
Definition: debug.h:110
static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num, const struct shader_reg *reg)
Definition: asmparser.c:104
GLdouble GLdouble z
Definition: glext.h:5874
smooth NULL
Definition: ftsmooth.c:416
static void check_abs_srcmod(struct asm_parser *This, DWORD srcmod)
Definition: asmparser.c:680
static void asmparser_srcreg_ps_2(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:909
BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w)
#define T4_VARYING
Definition: asmparser.c:61
static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype, DWORD mod, DWORD regnum, unsigned int line_no)
Definition: asmparser.c:169
static const struct allowed_reg_type ps_3_reg_allowed[]
Definition: asmparser.c:958
#define OPTS_WRITEMASK
Definition: asmparser.c:50
void create_ps30_parser(struct asm_parser *ret)
Definition: asmparser.c:1538
static struct shader_reg map_oldvs_register(const struct shader_reg *reg)
Definition: asmparser.c:607
void create_vs20_parser(struct asm_parser *ret)
Definition: asmparser.c:1379
#define TRACE_(x)
Definition: compat.h:66
GLuint shader
Definition: glext.h:6030
static void asmparser_srcreg_ps_3(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:974
struct shader_reg reg[MAX_SRC_REGS]
#define TRACE(s)
Definition: solgame.cpp:4
#define T0_REG
void create_ps14_parser(struct asm_parser *ret)
Definition: asmparser.c:1490
static void asmparser_dstreg_ps_1_0123(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1039
void create_ps13_parser(struct asm_parser *ret)
Definition: asmparser.c:1474
#define OT6_REG
Definition: asmparser.c:44
static const struct asmparser_backend parser_vs_2
Definition: asmparser.c:1169
static void asmparser_srcreg_vs_2(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:801
#define OFOG_REG
Definition: asmparser.c:47
static void asmparser_texld14(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct src_regs *srcs)
Definition: asmparser.c:417
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static void asmparser_sincos(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct src_regs *srcs)
Definition: asmparser.c:194
static void asmparser_texreg2gb(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct shader_reg *src0)
Definition: asmparser.c:473
const char * debug_print_srcreg(const struct shader_reg *reg) DECLSPEC_HIDDEN
Definition: utils.c:337
#define OT2_REG
Definition: asmparser.c:40
void create_vs11_parser(struct asm_parser *ret)
Definition: asmparser.c:1363
static const struct allowed_reg_type vs_3_reg_allowed[]
Definition: asmparser.c:819
#define C0_VARYING
Definition: asmparser.c:55
void create_ps20_parser(struct asm_parser *ret)
Definition: asmparser.c:1506
static void asmparser_dstreg_vs_3(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1024
const char * debug_print_dstreg(const struct shader_reg *reg) DECLSPEC_HIDDEN
Definition: utils.c:330
static void gen_oldvs_output(struct bwriter_shader *shader)
Definition: asmparser.c:1309
int ret
static void check_loop_swizzle(struct asm_parser *This, const struct shader_reg *src)
Definition: asmparser.c:689
#define T7_VARYING
Definition: asmparser.c:64
void create_vs30_parser(struct asm_parser *ret)
Definition: asmparser.c:1411
static void asmparser_constI(struct asm_parser *This, DWORD reg, INT x, INT y, INT z, INT w)
Definition: asmparser.c:94
static void asmparser_dcl_output_unsupported(struct asm_parser *This, DWORD usage, DWORD num, const struct shader_reg *reg)
Definition: asmparser.c:117
#define OD0_REG
Definition: asmparser.c:51
#define BWRITERVS_X_Y
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
#define BWRITERVS_Z_X
#define T6_VARYING
Definition: asmparser.c:63
static void set_parse_status(enum parse_status *current, enum parse_status update)
static struct shader_reg map_oldps_register(const struct shader_reg *reg, BOOL tex_varying)
Definition: asmparser.c:228
GLenum src
Definition: glext.h:6340
static const struct asmparser_backend parser_ps_1_4
Definition: asmparser.c:1229
static const struct allowed_reg_type ps_1_4_reg_allowed[]
Definition: asmparser.c:872
static void asmparser_instr(struct asm_parser *This, DWORD opcode, DWORD mod, DWORD shift, enum bwriter_comparison_type comp, const struct shader_reg *dst, const struct src_regs *srcs, int expectednsrcs)
Definition: asmparser.c:502
void create_ps2x_parser(struct asm_parser *ret)
Definition: asmparser.c:1522
#define T2_REG
WINE_DECLARE_DEBUG_CHANNEL(parsed_shader)
#define ERR(fmt,...)
Definition: debug.h:109
#define BWRITERVS_NOSWIZZLE
static void asmparser_end(struct asm_parser *This)
Definition: asmparser.c:70
static void asmparser_dstreg_ps_3(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1105
static void asmparser_texcrd(struct asm_parser *This, DWORD mod, DWORD shift, const struct shader_reg *dst, const struct src_regs *srcs)
Definition: asmparser.c:308
#define BWRITERVS_Y_Z
static void asmparser_srcreg_ps_2_x(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:941
static void asmparser_srcreg_vs_3(struct asm_parser *This, struct instruction *instr, int num, const struct shader_reg *src)
Definition: asmparser.c:834
#define BWRITERVS_W_Z
void create_ps11_parser(struct asm_parser *ret)
Definition: asmparser.c:1442
static void asmparser_predicate_unsupported(struct asm_parser *This, const struct shader_reg *predicate)
Definition: asmparser.c:1128
GLenum GLenum dst
Definition: glext.h:6340
#define OPOS_REG
Definition: asmparser.c:46
static void asmparser_coissue_supported(struct asm_parser *This)
Definition: asmparser.c:1134
static const struct allowed_reg_type vs_1_reg_allowed[]
Definition: asmparser.c:745
static int reg
Definition: i386-dis.c:1275
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static const struct allowed_reg_type vs_2_reg_allowed[]
Definition: asmparser.c:785
static const struct asmparser_backend parser_ps_2_x
Definition: asmparser.c:1269
static void asmparser_dstreg_ps_1_4(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1055
#define T3_VARYING
Definition: asmparser.c:60
static const struct asmparser_backend parser_vs_3
Definition: asmparser.c:1189
#define BWRITERVS_Y_Y
#define const
Definition: zconf.h:230
static const struct asmparser_backend parser_ps_3
Definition: asmparser.c:1289
static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num, DWORD mod, const struct shader_reg *reg)
Definition: asmparser.c:123
#define BWRITERPS_VERSION(major, minor)
const char * debug_print_comp(DWORD comp) DECLSPEC_HIDDEN
Definition: utils.c:401
static void asmparser_dcl_input_ps_2(struct asm_parser *This, DWORD usage, DWORD num, DWORD mod, const struct shader_reg *reg)
Definition: asmparser.c:148
static const struct allowed_reg_type ps_2_0_reg_allowed[]
Definition: asmparser.c:896
static void check_ps_dstmod(struct asm_parser *This, DWORD dstmod)
Definition: asmparser.c:707
#define T2_VARYING
Definition: asmparser.c:59
static void asmparser_dstreg_vs_1(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:988
static void asmparser_dstreg_ps_2(struct asm_parser *This, struct instruction *instr, const struct shader_reg *dst)
Definition: asmparser.c:1071
static void check_shift_dstmod(struct asm_parser *This, DWORD shift)
Definition: asmparser.c:699
#define T3_REG
#define BWRITERVS_VERSION(major, minor)
#define T5_VARYING
Definition: asmparser.c:62
#define OT1_REG
Definition: asmparser.c:39
const char * debug_print_dstmod(DWORD mod) DECLSPEC_HIDDEN
Definition: utils.c:153
#define BWRITERVS_X_W
static const struct asmparser_backend parser_vs_1
Definition: asmparser.c:1149
char * src
Definition: disassembler.h:104
#define BWRITERVS_W_X
unsigned int count
static int mod
Definition: i386-dis.c:1273
#define OT0_REG
Definition: asmparser.c:38