ReactOS  0.4.14-dev-342-gdc047f9
bytecodewriter.c
Go to the documentation of this file.
1 /*
2  * Direct3D bytecode output functions
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 "d3d9types.h"
26 #include "d3dcompiler_private.h"
27 
28 WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter);
29 
30 /****************************************************************
31  * General assembler shader construction helper routines follow *
32  ****************************************************************/
33 /* struct instruction *alloc_instr
34  *
35  * Allocates a new instruction structure with srcs registers
36  *
37  * Parameters:
38  * srcs: Number of source registers to allocate
39  *
40  * Returns:
41  * A pointer to the allocated instruction structure
42  * NULL in case of an allocation failure
43  */
44 struct instruction *alloc_instr(unsigned int srcs) {
45  struct instruction *ret = d3dcompiler_alloc(sizeof(*ret));
46  if(!ret) {
47  ERR("Failed to allocate memory for an instruction structure\n");
48  return NULL;
49  }
50 
51  if(srcs) {
52  ret->src = d3dcompiler_alloc(srcs * sizeof(*ret->src));
53  if(!ret->src) {
54  ERR("Failed to allocate memory for instruction registers\n");
56  return NULL;
57  }
58  ret->num_srcs = srcs;
59  }
60  return ret;
61 }
62 
63 /* void add_instruction
64  *
65  * Adds a new instruction to the shader's instructions array and grows the instruction array
66  * if needed.
67  *
68  * The function does NOT copy the instruction structure. Make sure not to release the
69  * instruction or any of its substructures like registers.
70  *
71  * Parameters:
72  * shader: Shader to add the instruction to
73  * instr: Instruction to add to the shader
74  */
76  struct instruction **new_instructions;
77 
78  if(!shader) return FALSE;
79 
80  if(shader->instr_alloc_size == 0) {
81  shader->instr = d3dcompiler_alloc(sizeof(*shader->instr) * INSTRARRAY_INITIAL_SIZE);
82  if(!shader->instr) {
83  ERR("Failed to allocate the shader instruction array\n");
84  return FALSE;
85  }
86  shader->instr_alloc_size = INSTRARRAY_INITIAL_SIZE;
87  } else if(shader->instr_alloc_size == shader->num_instrs) {
88  new_instructions = d3dcompiler_realloc(shader->instr,
89  sizeof(*shader->instr) * (shader->instr_alloc_size) * 2);
90  if(!new_instructions) {
91  ERR("Failed to grow the shader instruction array\n");
92  return FALSE;
93  }
94  shader->instr = new_instructions;
95  shader->instr_alloc_size = shader->instr_alloc_size * 2;
96  } else if(shader->num_instrs > shader->instr_alloc_size) {
97  ERR("More instructions than allocated. This should not happen\n");
98  return FALSE;
99  }
100 
101  shader->instr[shader->num_instrs] = instr;
102  shader->num_instrs++;
103  return TRUE;
104 }
105 
106 BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w) {
107  struct constant *newconst;
108 
109  if(shader->num_cf) {
110  struct constant **newarray;
111  newarray = d3dcompiler_realloc(shader->constF,
112  sizeof(*shader->constF) * (shader->num_cf + 1));
113  if(!newarray) {
114  ERR("Failed to grow the constants array\n");
115  return FALSE;
116  }
117  shader->constF = newarray;
118  } else {
119  shader->constF = d3dcompiler_alloc(sizeof(*shader->constF));
120  if(!shader->constF) {
121  ERR("Failed to allocate the constants array\n");
122  return FALSE;
123  }
124  }
125 
126  newconst = d3dcompiler_alloc(sizeof(*newconst));
127  if(!newconst) {
128  ERR("Failed to allocate a new constant\n");
129  return FALSE;
130  }
131  newconst->regnum = reg;
132  newconst->value[0].f = x;
133  newconst->value[1].f = y;
134  newconst->value[2].f = z;
135  newconst->value[3].f = w;
136  shader->constF[shader->num_cf] = newconst;
137 
138  shader->num_cf++;
139  return TRUE;
140 }
141 
143  struct constant *newconst;
144 
145  if(shader->num_ci) {
146  struct constant **newarray;
147  newarray = d3dcompiler_realloc(shader->constI,
148  sizeof(*shader->constI) * (shader->num_ci + 1));
149  if(!newarray) {
150  ERR("Failed to grow the constants array\n");
151  return FALSE;
152  }
153  shader->constI = newarray;
154  } else {
155  shader->constI = d3dcompiler_alloc(sizeof(*shader->constI));
156  if(!shader->constI) {
157  ERR("Failed to allocate the constants array\n");
158  return FALSE;
159  }
160  }
161 
162  newconst = d3dcompiler_alloc(sizeof(*newconst));
163  if(!newconst) {
164  ERR("Failed to allocate a new constant\n");
165  return FALSE;
166  }
167  newconst->regnum = reg;
168  newconst->value[0].i = x;
169  newconst->value[1].i = y;
170  newconst->value[2].i = z;
171  newconst->value[3].i = w;
172  shader->constI[shader->num_ci] = newconst;
173 
174  shader->num_ci++;
175  return TRUE;
176 }
177 
179  struct constant *newconst;
180 
181  if(shader->num_cb) {
182  struct constant **newarray;
183  newarray = d3dcompiler_realloc(shader->constB,
184  sizeof(*shader->constB) * (shader->num_cb + 1));
185  if(!newarray) {
186  ERR("Failed to grow the constants array\n");
187  return FALSE;
188  }
189  shader->constB = newarray;
190  } else {
191  shader->constB = d3dcompiler_alloc(sizeof(*shader->constB));
192  if(!shader->constB) {
193  ERR("Failed to allocate the constants array\n");
194  return FALSE;
195  }
196  }
197 
198  newconst = d3dcompiler_alloc(sizeof(*newconst));
199  if(!newconst) {
200  ERR("Failed to allocate a new constant\n");
201  return FALSE;
202  }
203  newconst->regnum = reg;
204  newconst->value[0].b = x;
205  shader->constB[shader->num_cb] = newconst;
206 
207  shader->num_cb++;
208  return TRUE;
209 }
210 
213  DWORD regnum, DWORD writemask, BOOL builtin) {
214  unsigned int *num;
215  struct declaration **decl;
216  unsigned int i;
217 
218  if(!shader) return FALSE;
219 
220  if(output) {
221  num = &shader->num_outputs;
222  decl = &shader->outputs;
223  } else {
224  num = &shader->num_inputs;
225  decl = &shader->inputs;
226  }
227 
228  if(*num == 0) {
229  *decl = d3dcompiler_alloc(sizeof(**decl));
230  if(!*decl) {
231  ERR("Error allocating declarations array\n");
232  return FALSE;
233  }
234  } else {
235  struct declaration *newdecl;
236  for(i = 0; i < *num; i++) {
237  if((*decl)[i].regnum == regnum && ((*decl)[i].writemask & writemask)) {
238  WARN("Declaration of register %u already exists, writemask match 0x%x\n",
239  regnum, (*decl)[i].writemask & writemask);
240  }
241  }
242 
243  newdecl = d3dcompiler_realloc(*decl,
244  sizeof(**decl) * ((*num) + 1));
245  if(!newdecl) {
246  ERR("Error reallocating declarations array\n");
247  return FALSE;
248  }
249  *decl = newdecl;
250  }
251  (*decl)[*num].usage = usage;
252  (*decl)[*num].usage_idx = usage_idx;
253  (*decl)[*num].regnum = regnum;
254  (*decl)[*num].mod = mod;
255  (*decl)[*num].writemask = writemask;
256  (*decl)[*num].builtin = builtin;
257  (*num)++;
258 
259  return TRUE;
260 }
261 
263  unsigned int i;
264 
265  if(!shader) return FALSE;
266 
267  if(shader->num_samplers == 0) {
268  shader->samplers = d3dcompiler_alloc(sizeof(*shader->samplers));
269  if(!shader->samplers) {
270  ERR("Error allocating samplers array\n");
271  return FALSE;
272  }
273  } else {
274  struct samplerdecl *newarray;
275 
276  for(i = 0; i < shader->num_samplers; i++) {
277  if(shader->samplers[i].regnum == regnum) {
278  WARN("Sampler %u already declared\n", regnum);
279  /* This is not an error as far as the assembler is concerned.
280  * Direct3D might refuse to load the compiled shader though
281  */
282  }
283  }
284 
285  newarray = d3dcompiler_realloc(shader->samplers,
286  sizeof(*shader->samplers) * (shader->num_samplers + 1));
287  if(!newarray) {
288  ERR("Error reallocating samplers array\n");
289  return FALSE;
290  }
291  shader->samplers = newarray;
292  }
293 
294  shader->samplers[shader->num_samplers].type = samptype;
295  shader->samplers[shader->num_samplers].mod = mod;
296  shader->samplers[shader->num_samplers].regnum = regnum;
297  shader->num_samplers++;
298  return TRUE;
299 }
300 
301 
302 /* shader bytecode buffer manipulation functions.
303  * allocate_buffer creates a new buffer structure, put_dword adds a new
304  * DWORD to the buffer. In the rare case of a memory allocation failure
305  * when trying to grow the buffer a flag is set in the buffer to mark it
306  * invalid. This avoids return value checking and passing in many places
307  */
308 static struct bytecode_buffer *allocate_buffer(void) {
309  struct bytecode_buffer *ret;
310 
311  ret = d3dcompiler_alloc(sizeof(*ret));
312  if(!ret) return NULL;
313 
314  ret->alloc_size = BYTECODEBUFFER_INITIAL_SIZE;
315  ret->data = d3dcompiler_alloc(sizeof(DWORD) * ret->alloc_size);
316  if(!ret->data) {
318  return NULL;
319  }
320  ret->state = S_OK;
321  return ret;
322 }
323 
324 static void put_dword(struct bytecode_buffer *buffer, DWORD value) {
325  if(FAILED(buffer->state)) return;
326 
327  if(buffer->alloc_size == buffer->size) {
328  DWORD *newarray;
329  buffer->alloc_size *= 2;
330  newarray = d3dcompiler_realloc(buffer->data,
331  sizeof(DWORD) * buffer->alloc_size);
332  if(!newarray) {
333  ERR("Failed to grow the buffer data memory\n");
334  buffer->state = E_OUTOFMEMORY;
335  return;
336  }
337  buffer->data = newarray;
338  }
339  buffer->data[buffer->size++] = value;
340 }
341 
342 /* bwriter -> d3d9 conversion functions. */
343 static DWORD d3d9_swizzle(DWORD bwriter_swizzle)
344 {
345  /* Currently a NOP, but this allows changing the internal definitions
346  * without side effects. */
347  DWORD ret = 0;
348 
349  if ((bwriter_swizzle & BWRITERVS_X_X) == BWRITERVS_X_X) ret |= D3DVS_X_X;
350  if ((bwriter_swizzle & BWRITERVS_X_Y) == BWRITERVS_X_Y) ret |= D3DVS_X_Y;
351  if ((bwriter_swizzle & BWRITERVS_X_Z) == BWRITERVS_X_Z) ret |= D3DVS_X_Z;
352  if ((bwriter_swizzle & BWRITERVS_X_W) == BWRITERVS_X_W) ret |= D3DVS_X_W;
353 
354  if ((bwriter_swizzle & BWRITERVS_Y_X) == BWRITERVS_Y_X) ret |= D3DVS_Y_X;
355  if ((bwriter_swizzle & BWRITERVS_Y_Y) == BWRITERVS_Y_Y) ret |= D3DVS_Y_Y;
356  if ((bwriter_swizzle & BWRITERVS_Y_Z) == BWRITERVS_Y_Z) ret |= D3DVS_Y_Z;
357  if ((bwriter_swizzle & BWRITERVS_Y_W) == BWRITERVS_Y_W) ret |= D3DVS_Y_W;
358 
359  if ((bwriter_swizzle & BWRITERVS_Z_X) == BWRITERVS_Z_X) ret |= D3DVS_Z_X;
360  if ((bwriter_swizzle & BWRITERVS_Z_Y) == BWRITERVS_Z_Y) ret |= D3DVS_Z_Y;
361  if ((bwriter_swizzle & BWRITERVS_Z_Z) == BWRITERVS_Z_Z) ret |= D3DVS_Z_Z;
362  if ((bwriter_swizzle & BWRITERVS_Z_W) == BWRITERVS_Z_W) ret |= D3DVS_Z_W;
363 
364  if ((bwriter_swizzle & BWRITERVS_W_X) == BWRITERVS_W_X) ret |= D3DVS_W_X;
365  if ((bwriter_swizzle & BWRITERVS_W_Y) == BWRITERVS_W_Y) ret |= D3DVS_W_Y;
366  if ((bwriter_swizzle & BWRITERVS_W_Z) == BWRITERVS_W_Z) ret |= D3DVS_W_Z;
367  if ((bwriter_swizzle & BWRITERVS_W_W) == BWRITERVS_W_W) ret |= D3DVS_W_W;
368 
369  return ret;
370 }
371 
372 static DWORD d3d9_writemask(DWORD bwriter_writemask)
373 {
374  DWORD ret = 0;
375 
376  if (bwriter_writemask & BWRITERSP_WRITEMASK_0) ret |= D3DSP_WRITEMASK_0;
377  if (bwriter_writemask & BWRITERSP_WRITEMASK_1) ret |= D3DSP_WRITEMASK_1;
378  if (bwriter_writemask & BWRITERSP_WRITEMASK_2) ret |= D3DSP_WRITEMASK_2;
379  if (bwriter_writemask & BWRITERSP_WRITEMASK_3) ret |= D3DSP_WRITEMASK_3;
380 
381  return ret;
382 }
383 
384 static DWORD d3d9_srcmod(DWORD bwriter_srcmod)
385 {
386  switch (bwriter_srcmod)
387  {
388  case BWRITERSPSM_NONE: return D3DSPSM_NONE;
389  case BWRITERSPSM_NEG: return D3DSPSM_NEG;
390  case BWRITERSPSM_BIAS: return D3DSPSM_BIAS;
392  case BWRITERSPSM_SIGN: return D3DSPSM_SIGN;
394  case BWRITERSPSM_COMP: return D3DSPSM_COMP;
395  case BWRITERSPSM_X2: return D3DSPSM_X2;
396  case BWRITERSPSM_X2NEG: return D3DSPSM_X2NEG;
397  case BWRITERSPSM_DZ: return D3DSPSM_DZ;
398  case BWRITERSPSM_DW: return D3DSPSM_DW;
399  case BWRITERSPSM_ABS: return D3DSPSM_ABS;
400  case BWRITERSPSM_ABSNEG: return D3DSPSM_ABSNEG;
401  case BWRITERSPSM_NOT: return D3DSPSM_NOT;
402  default:
403  FIXME("Unhandled BWRITERSPSM token %#x.\n", bwriter_srcmod);
404  return 0;
405  }
406 }
407 
408 static DWORD d3d9_dstmod(DWORD bwriter_mod)
409 {
410  DWORD ret = 0;
411 
412  if (bwriter_mod & BWRITERSPDM_SATURATE) ret |= D3DSPDM_SATURATE;
415 
416  return ret;
417 }
418 
419 static DWORD d3d9_comparetype(DWORD asmshader_comparetype)
420 {
421  switch (asmshader_comparetype)
422  {
423  case BWRITER_COMPARISON_GT: return D3DSPC_GT;
424  case BWRITER_COMPARISON_EQ: return D3DSPC_EQ;
425  case BWRITER_COMPARISON_GE: return D3DSPC_GE;
426  case BWRITER_COMPARISON_LT: return D3DSPC_LT;
427  case BWRITER_COMPARISON_NE: return D3DSPC_NE;
428  case BWRITER_COMPARISON_LE: return D3DSPC_LE;
429  default:
430  FIXME("Unexpected BWRITER_COMPARISON type %#x.\n", asmshader_comparetype);
431  return 0;
432  }
433 }
434 
435 static DWORD d3d9_sampler(DWORD bwriter_sampler)
436 {
437  if (bwriter_sampler == BWRITERSTT_UNKNOWN) return D3DSTT_UNKNOWN;
438  if (bwriter_sampler == BWRITERSTT_1D) return D3DSTT_1D;
439  if (bwriter_sampler == BWRITERSTT_2D) return D3DSTT_2D;
440  if (bwriter_sampler == BWRITERSTT_CUBE) return D3DSTT_CUBE;
441  if (bwriter_sampler == BWRITERSTT_VOLUME) return D3DSTT_VOLUME;
442  FIXME("Unexpected BWRITERSAMPLER_TEXTURE_TYPE type %#x.\n", bwriter_sampler);
443 
444  return 0;
445 }
446 
447 static DWORD d3d9_register(DWORD bwriter_register)
448 {
449  if (bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
450  if (bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;
451  if (bwriter_register == BWRITERSPR_CONST) return D3DSPR_CONST;
452  if (bwriter_register == BWRITERSPR_ADDR) return D3DSPR_ADDR;
453  if (bwriter_register == BWRITERSPR_TEXTURE) return D3DSPR_TEXTURE;
454  if (bwriter_register == BWRITERSPR_RASTOUT) return D3DSPR_RASTOUT;
455  if (bwriter_register == BWRITERSPR_ATTROUT) return D3DSPR_ATTROUT;
456  if (bwriter_register == BWRITERSPR_TEXCRDOUT) return D3DSPR_TEXCRDOUT;
457  if (bwriter_register == BWRITERSPR_OUTPUT) return D3DSPR_OUTPUT;
458  if (bwriter_register == BWRITERSPR_CONSTINT) return D3DSPR_CONSTINT;
459  if (bwriter_register == BWRITERSPR_COLOROUT) return D3DSPR_COLOROUT;
460  if (bwriter_register == BWRITERSPR_DEPTHOUT) return D3DSPR_DEPTHOUT;
461  if (bwriter_register == BWRITERSPR_SAMPLER) return D3DSPR_SAMPLER;
462  if (bwriter_register == BWRITERSPR_CONSTBOOL) return D3DSPR_CONSTBOOL;
463  if (bwriter_register == BWRITERSPR_LOOP) return D3DSPR_LOOP;
464  if (bwriter_register == BWRITERSPR_MISCTYPE) return D3DSPR_MISCTYPE;
465  if (bwriter_register == BWRITERSPR_LABEL) return D3DSPR_LABEL;
466  if (bwriter_register == BWRITERSPR_PREDICATE) return D3DSPR_PREDICATE;
467 
468  FIXME("Unexpected BWRITERSPR %#x.\n", bwriter_register);
469  return ~0U;
470 }
471 
472 static DWORD d3d9_opcode(DWORD bwriter_opcode)
473 {
474  switch (bwriter_opcode)
475  {
476  case BWRITERSIO_NOP: return D3DSIO_NOP;
477  case BWRITERSIO_MOV: return D3DSIO_MOV;
478  case BWRITERSIO_ADD: return D3DSIO_ADD;
479  case BWRITERSIO_SUB: return D3DSIO_SUB;
480  case BWRITERSIO_MAD: return D3DSIO_MAD;
481  case BWRITERSIO_MUL: return D3DSIO_MUL;
482  case BWRITERSIO_RCP: return D3DSIO_RCP;
483  case BWRITERSIO_RSQ: return D3DSIO_RSQ;
484  case BWRITERSIO_DP3: return D3DSIO_DP3;
485  case BWRITERSIO_DP4: return D3DSIO_DP4;
486  case BWRITERSIO_MIN: return D3DSIO_MIN;
487  case BWRITERSIO_MAX: return D3DSIO_MAX;
488  case BWRITERSIO_SLT: return D3DSIO_SLT;
489  case BWRITERSIO_SGE: return D3DSIO_SGE;
490  case BWRITERSIO_EXP: return D3DSIO_EXP;
491  case BWRITERSIO_LOG: return D3DSIO_LOG;
492  case BWRITERSIO_LIT: return D3DSIO_LIT;
493  case BWRITERSIO_DST: return D3DSIO_DST;
494  case BWRITERSIO_LRP: return D3DSIO_LRP;
495  case BWRITERSIO_FRC: return D3DSIO_FRC;
496  case BWRITERSIO_M4x4: return D3DSIO_M4x4;
497  case BWRITERSIO_M4x3: return D3DSIO_M4x3;
498  case BWRITERSIO_M3x4: return D3DSIO_M3x4;
499  case BWRITERSIO_M3x3: return D3DSIO_M3x3;
500  case BWRITERSIO_M3x2: return D3DSIO_M3x2;
501  case BWRITERSIO_CALL: return D3DSIO_CALL;
502  case BWRITERSIO_CALLNZ: return D3DSIO_CALLNZ;
503  case BWRITERSIO_LOOP: return D3DSIO_LOOP;
504  case BWRITERSIO_RET: return D3DSIO_RET;
505  case BWRITERSIO_ENDLOOP: return D3DSIO_ENDLOOP;
506  case BWRITERSIO_LABEL: return D3DSIO_LABEL;
507  case BWRITERSIO_DCL: return D3DSIO_DCL;
508  case BWRITERSIO_POW: return D3DSIO_POW;
509  case BWRITERSIO_CRS: return D3DSIO_CRS;
510  case BWRITERSIO_SGN: return D3DSIO_SGN;
511  case BWRITERSIO_ABS: return D3DSIO_ABS;
512  case BWRITERSIO_NRM: return D3DSIO_NRM;
513  case BWRITERSIO_SINCOS: return D3DSIO_SINCOS;
514  case BWRITERSIO_REP: return D3DSIO_REP;
515  case BWRITERSIO_ENDREP: return D3DSIO_ENDREP;
516  case BWRITERSIO_IF: return D3DSIO_IF;
517  case BWRITERSIO_IFC: return D3DSIO_IFC;
518  case BWRITERSIO_ELSE: return D3DSIO_ELSE;
519  case BWRITERSIO_ENDIF: return D3DSIO_ENDIF;
520  case BWRITERSIO_BREAK: return D3DSIO_BREAK;
521  case BWRITERSIO_BREAKC: return D3DSIO_BREAKC;
522  case BWRITERSIO_MOVA: return D3DSIO_MOVA;
523  case BWRITERSIO_DEFB: return D3DSIO_DEFB;
524  case BWRITERSIO_DEFI: return D3DSIO_DEFI;
525 
527  case BWRITERSIO_TEXKILL: return D3DSIO_TEXKILL;
528  case BWRITERSIO_TEX: return D3DSIO_TEX;
529  case BWRITERSIO_TEXBEM: return D3DSIO_TEXBEM;
530  case BWRITERSIO_TEXBEML: return D3DSIO_TEXBEML;
539  case BWRITERSIO_EXPP: return D3DSIO_EXPP;
540  case BWRITERSIO_LOGP: return D3DSIO_LOGP;
541  case BWRITERSIO_CND: return D3DSIO_CND;
542  case BWRITERSIO_DEF: return D3DSIO_DEF;
546  case BWRITERSIO_TEXDP3: return D3DSIO_TEXDP3;
547  case BWRITERSIO_TEXM3x3: return D3DSIO_TEXM3x3;
549  case BWRITERSIO_CMP: return D3DSIO_CMP;
550  case BWRITERSIO_BEM: return D3DSIO_BEM;
551  case BWRITERSIO_DP2ADD: return D3DSIO_DP2ADD;
552  case BWRITERSIO_DSX: return D3DSIO_DSX;
553  case BWRITERSIO_DSY: return D3DSIO_DSY;
554  case BWRITERSIO_TEXLDD: return D3DSIO_TEXLDD;
555  case BWRITERSIO_SETP: return D3DSIO_SETP;
556  case BWRITERSIO_TEXLDL: return D3DSIO_TEXLDL;
557  case BWRITERSIO_BREAKP: return D3DSIO_BREAKP;
558 
559  case BWRITERSIO_PHASE: return D3DSIO_PHASE;
560  case BWRITERSIO_COMMENT: return D3DSIO_COMMENT;
561  case BWRITERSIO_END: return D3DSIO_END;
562 
565 
566  default:
567  FIXME("Unhandled BWRITERSIO token %#x.\n", bwriter_opcode);
568  return ~0U;
569  }
570 }
571 
573 {
576  (num & D3DSP_REGNUM_MASK); /* No shift */
577 }
578 
579 /******************************************************
580  * Implementation of the writer functions starts here *
581  ******************************************************/
582 static void write_declarations(struct bc_writer *This,
583  struct bytecode_buffer *buffer, BOOL len,
584  const struct declaration *decls, unsigned int num, DWORD type) {
585  DWORD i;
587  DWORD token;
588  struct shader_reg reg;
589 
590  ZeroMemory(&reg, sizeof(reg));
591 
592  if(len) {
594  }
595 
596  for(i = 0; i < num; i++) {
597  if(decls[i].builtin) continue;
598 
599  /* Write the DCL instruction */
601 
602  /* Write the usage and index */
603  token = (1u << 31); /* Bit 31 of non-instruction opcodes is 1 */
607 
608  /* Write the dest register */
609  reg.type = type;
610  reg.regnum = decls[i].regnum;
611  reg.u.writemask = decls[i].writemask;
612  This->funcs->dstreg(This, &reg, buffer, 0, decls[i].mod);
613  }
614 }
615 
616 static void write_const(struct constant **consts, int num, DWORD opcode, DWORD reg_type, struct bytecode_buffer *buffer, BOOL len) {
617  int i;
618  DWORD instr_def = opcode;
619  const DWORD reg = (1u << 31) | d3dsp_register( reg_type, 0 ) | D3DSP_WRITEMASK_ALL;
620 
621  if(len) {
622  if(opcode == D3DSIO_DEFB)
624  else
626  }
627 
628  for(i = 0; i < num; i++) {
629  /* Write the DEF instruction */
631 
632  put_dword(buffer, reg | (consts[i]->regnum & D3DSP_REGNUM_MASK));
633  put_dword(buffer, consts[i]->value[0].d);
634  if(opcode != D3DSIO_DEFB) {
635  put_dword(buffer, consts[i]->value[1].d);
636  put_dword(buffer, consts[i]->value[2].d);
637  put_dword(buffer, consts[i]->value[3].d);
638  }
639  }
640 }
641 
642 static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
643  write_const(shader->constF, shader->num_cf, D3DSIO_DEF, D3DSPR_CONST, buffer, len);
644 }
645 
646 /* This function looks for VS 1/2 registers mapping to VS 3 output registers */
648  DWORD i;
650 
651  for(i = 0; i < shader->num_outputs; i++) {
652  if(!shader->outputs[i].builtin) continue;
653 
654  usage = shader->outputs[i].usage;
655  usage_idx = shader->outputs[i].usage_idx;
656  writemask = shader->outputs[i].writemask;
657  regnum = shader->outputs[i].regnum;
658 
659  switch(usage) {
662  if(usage_idx > 0) {
663  WARN("dcl_position%u not supported in sm 1/2 shaders\n", usage_idx);
664  return E_INVALIDARG;
665  }
666  TRACE("o%u is oPos\n", regnum);
667  This->oPos_regnum = regnum;
668  break;
669 
671  if(usage_idx > 1) {
672  WARN("dcl_color%u not supported in sm 1/2 shaders\n", usage_idx);
673  return E_INVALIDARG;
674  }
676  WARN("Only WRITEMASK_ALL is supported on color in sm 1/2\n");
677  return E_INVALIDARG;
678  }
679  TRACE("o%u is oD%u\n", regnum, usage_idx);
680  This->oD_regnum[usage_idx] = regnum;
681  break;
682 
684  if(usage_idx >= 8) {
685  WARN("dcl_color%u not supported in sm 1/2 shaders\n", usage_idx);
686  return E_INVALIDARG;
687  }
692  WARN("Partial writemasks not supported on texture coordinates in sm 1 and 2\n");
693  return E_INVALIDARG;
694  }
695  TRACE("o%u is oT%u\n", regnum, usage_idx);
696  This->oT_regnum[usage_idx] = regnum;
697  break;
698 
700  if(usage_idx > 0) {
701  WARN("dcl_psize%u not supported in sm 1/2 shaders\n", usage_idx);
702  return E_INVALIDARG;
703  }
704  TRACE("o%u writemask 0x%08x is oPts\n", regnum, writemask);
705  This->oPts_regnum = regnum;
706  This->oPts_mask = writemask;
707  break;
708 
710  if(usage_idx > 0) {
711  WARN("dcl_fog%u not supported in sm 1 shaders\n", usage_idx);
712  return E_INVALIDARG;
713  }
716  WARN("Unsupported fog writemask\n");
717  return E_INVALIDARG;
718  }
719  TRACE("o%u writemask 0x%08x is oFog\n", regnum, writemask);
720  This->oFog_regnum = regnum;
721  This->oFog_mask = writemask;
722  break;
723 
724  default:
725  WARN("Varying type %u is not supported in shader model 1.x\n", usage);
726  return E_INVALIDARG;
727  }
728  }
729 
730  return S_OK;
731 }
732 
733 static void vs_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
734  HRESULT hr;
735 
736  if(shader->num_ci || shader->num_cb) {
737  WARN("Int and bool constants are not supported in shader model 1 shaders\n");
738  WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
739  This->state = E_INVALIDARG;
740  return;
741  }
742 
744  if(FAILED(hr)) {
745  This->state = hr;
746  return;
747  }
748 
751 }
752 
754  const struct bwriter_shader *shader,
755  DWORD texcoords) {
756  DWORD i;
758 
759  This->v_regnum[0] = -1; This->v_regnum[1] = -1;
760  for(i = 0; i < 8; i++) This->t_regnum[i] = -1;
761 
762  for(i = 0; i < shader->num_inputs; i++) {
763  if(!shader->inputs[i].builtin) continue;
764 
765  usage = shader->inputs[i].usage;
766  usage_idx = shader->inputs[i].usage_idx;
767  writemask = shader->inputs[i].writemask;
768  regnum = shader->inputs[i].regnum;
769 
770  switch(usage) {
772  if(usage_idx > 1) {
773  WARN("dcl_color%u not supported in sm 1 shaders\n", usage_idx);
774  return E_INVALIDARG;
775  }
777  WARN("Only WRITEMASK_ALL is supported on color in sm 1\n");
778  return E_INVALIDARG;
779  }
780  TRACE("v%u is v%u\n", regnum, usage_idx);
781  This->v_regnum[usage_idx] = regnum;
782  break;
783 
785  if(usage_idx > texcoords) {
786  WARN("dcl_texcoord%u not supported in this shader version\n", usage_idx);
787  return E_INVALIDARG;
788  }
793  WARN("Partial writemasks not supported on texture coordinates in sm 1 and 2\n");
794  } else {
796  }
797  TRACE("v%u is t%u\n", regnum, usage_idx);
798  This->t_regnum[usage_idx] = regnum;
799  break;
800 
801  default:
802  WARN("Varying type %u is not supported in shader model 1.x\n", usage);
803  return E_INVALIDARG;
804  }
805  }
806 
807  return S_OK;
808 }
809 
810 static void ps_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
811  HRESULT hr;
812 
813  /* First check the constants and varyings, and complain if unsupported things are used */
814  if(shader->num_ci || shader->num_cb) {
815  WARN("Int and bool constants are not supported in shader model 1 shaders\n");
816  WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
817  This->state = E_INVALIDARG;
818  return;
819  }
820 
822  if(FAILED(hr)) {
823  This->state = hr;
824  return;
825  }
826 
828 }
829 
830 static void ps_1_4_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
831  HRESULT hr;
832 
833  /* First check the constants and varyings, and complain if unsupported things are used */
834  if(shader->num_ci || shader->num_cb) {
835  WARN("Int and bool constants are not supported in shader model 1 shaders\n");
836  WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
837  This->state = E_INVALIDARG;
838  return;
839  }
841  if(FAILED(hr)) {
842  This->state = hr;
843  return;
844  }
845 
847 }
848 
849 static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
851 }
852 
853 static DWORD map_vs_output(struct bc_writer *This, DWORD regnum, DWORD mask, DWORD *has_components) {
854  DWORD i;
855 
856  *has_components = TRUE;
857  if(regnum == This->oPos_regnum) {
859  }
860  if(regnum == This->oFog_regnum && mask == This->oFog_mask) {
861  *has_components = FALSE;
863  }
864  if(regnum == This->oPts_regnum && mask == This->oPts_mask) {
865  *has_components = FALSE;
867  }
868  for(i = 0; i < 2; i++) {
869  if(regnum == This->oD_regnum[i]) {
870  return d3dsp_register( D3DSPR_ATTROUT, i );
871  }
872  }
873  for(i = 0; i < 8; i++) {
874  if(regnum == This->oT_regnum[i]) {
875  return d3dsp_register( D3DSPR_TEXCRDOUT, i );
876  }
877  }
878 
879  /* The varying must be undeclared - if an unsupported varying was declared,
880  * the vs_find_builtin_varyings function would have caught it and this code
881  * would not run */
882  WARN("Undeclared varying %u\n", regnum);
883  This->state = E_INVALIDARG;
884  return -1;
885 }
886 
887 static void vs_12_dstreg(struct bc_writer *This, const struct shader_reg *reg,
888  struct bytecode_buffer *buffer,
889  DWORD shift, DWORD mod) {
890  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
891  DWORD has_wmask;
892 
893  if(reg->rel_reg) {
894  WARN("Relative addressing not supported for destination registers\n");
895  This->state = E_INVALIDARG;
896  return;
897  }
898 
899  switch(reg->type) {
900  case BWRITERSPR_OUTPUT:
901  token |= map_vs_output(This, reg->regnum, reg->u.writemask, &has_wmask);
902  break;
903 
904  case BWRITERSPR_RASTOUT:
905  case BWRITERSPR_ATTROUT:
906  /* These registers are mapped to input and output regs. They can be encoded in the bytecode,
907  * but are unexpected. If we hit this path it might be due to an error.
908  */
909  FIXME("Unexpected register type %u\n", reg->type);
910  /* drop through */
911  case BWRITERSPR_INPUT:
912  case BWRITERSPR_TEMP:
913  case BWRITERSPR_CONST:
914  token |= d3dsp_register( reg->type, reg->regnum );
915  has_wmask = TRUE;
916  break;
917 
918  case BWRITERSPR_ADDR:
919  if(reg->regnum != 0) {
920  WARN("Only a0 exists\n");
921  This->state = E_INVALIDARG;
922  return;
923  }
925  has_wmask = TRUE;
926  break;
927 
929  if(This->version != BWRITERVS_VERSION(2, 1)){
930  WARN("Predicate register is allowed only in vs_2_x\n");
931  This->state = E_INVALIDARG;
932  return;
933  }
934  if(reg->regnum != 0) {
935  WARN("Only predicate register p0 exists\n");
936  This->state = E_INVALIDARG;
937  return;
938  }
940  has_wmask = TRUE;
941  break;
942 
943  default:
944  WARN("Invalid register type for 1.x-2.x vertex shader\n");
945  This->state = E_INVALIDARG;
946  return;
947  }
948 
949  /* strictly speaking there are no modifiers in vs_2_0 and vs_1_x, but they can be written
950  * into the bytecode and since the compiler doesn't do such checks write them
951  * (the checks are done by the undocumented shader validator)
952  */
954  token |= d3d9_dstmod(mod);
955 
956  if(has_wmask) {
957  token |= d3d9_writemask(reg->u.writemask);
958  }
960 }
961 
962 static void vs_1_x_srcreg(struct bc_writer *This, const struct shader_reg *reg,
963  struct bytecode_buffer *buffer) {
964  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
965  DWORD has_swizzle;
966  DWORD component;
967 
968  switch(reg->type) {
969  case BWRITERSPR_OUTPUT:
970  /* Map the swizzle to a writemask, the format expected
971  by map_vs_output
972  */
973  switch(reg->u.swizzle) {
974  case BWRITERVS_SWIZZLE_X:
975  component = BWRITERSP_WRITEMASK_0;
976  break;
977  case BWRITERVS_SWIZZLE_Y:
978  component = BWRITERSP_WRITEMASK_1;
979  break;
980  case BWRITERVS_SWIZZLE_Z:
981  component = BWRITERSP_WRITEMASK_2;
982  break;
983  case BWRITERVS_SWIZZLE_W:
984  component = BWRITERSP_WRITEMASK_3;
985  break;
986  default:
987  component = 0;
988  }
989  token |= map_vs_output(This, reg->regnum, component, &has_swizzle);
990  break;
991 
992  case BWRITERSPR_RASTOUT:
993  case BWRITERSPR_ATTROUT:
994  /* These registers are mapped to input and output regs. They can be encoded in the bytecode,
995  * but are unexpected. If we hit this path it might be due to an error.
996  */
997  FIXME("Unexpected register type %u\n", reg->type);
998  /* drop through */
999  case BWRITERSPR_INPUT:
1000  case BWRITERSPR_TEMP:
1001  case BWRITERSPR_CONST:
1002  case BWRITERSPR_ADDR:
1003  token |= d3dsp_register( reg->type, reg->regnum );
1004  if(reg->rel_reg) {
1005  if(reg->rel_reg->type != BWRITERSPR_ADDR ||
1006  reg->rel_reg->regnum != 0 ||
1007  reg->rel_reg->u.swizzle != BWRITERVS_SWIZZLE_X) {
1008  WARN("Relative addressing in vs_1_x is only allowed with a0.x\n");
1009  This->state = E_INVALIDARG;
1010  return;
1011  }
1013  }
1014  break;
1015 
1016  default:
1017  WARN("Invalid register type for 1.x vshader\n");
1018  This->state = E_INVALIDARG;
1019  return;
1020  }
1021 
1022  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1023 
1024  token |= d3d9_srcmod(reg->srcmod);
1026 }
1027 
1028 static void write_srcregs(struct bc_writer *This, const struct instruction *instr,
1029  struct bytecode_buffer *buffer){
1030  unsigned int i;
1031  if(instr->has_predicate){
1032  This->funcs->srcreg(This, &instr->predicate, buffer);
1033  }
1034  for(i = 0; i < instr->num_srcs; i++){
1035  This->funcs->srcreg(This, &instr->src[i], buffer);
1036  }
1037 }
1038 
1039 static DWORD map_ps13_temp(struct bc_writer *This, const struct shader_reg *reg) {
1040  if(reg->regnum == T0_REG) {
1041  return d3dsp_register( D3DSPR_TEXTURE, 0 );
1042  } else if(reg->regnum == T1_REG) {
1043  return d3dsp_register( D3DSPR_TEXTURE, 1 );
1044  } else if(reg->regnum == T2_REG) {
1045  return d3dsp_register( D3DSPR_TEXTURE, 2 );
1046  } else if(reg->regnum == T3_REG) {
1047  return d3dsp_register( D3DSPR_TEXTURE, 3 );
1048  } else {
1049  return d3dsp_register( D3DSPR_TEMP, reg->regnum );
1050  }
1051 }
1052 
1054  const struct shader_reg *reg) {
1055  DWORD i;
1056  /* Map color interpolators */
1057  for(i = 0; i < 2; i++) {
1058  if(reg->regnum == This->v_regnum[i]) {
1059  return d3dsp_register( D3DSPR_INPUT, i );
1060  }
1061  }
1062  for(i = 0; i < 8; i++) {
1063  if(reg->regnum == This->t_regnum[i]) {
1064  return d3dsp_register( D3DSPR_TEXTURE, i );
1065  }
1066  }
1067 
1068  WARN("Invalid ps 1/2 varying\n");
1069  This->state = E_INVALIDARG;
1070  return 0;
1071 }
1072 
1073 static void ps_1_0123_srcreg(struct bc_writer *This, const struct shader_reg *reg,
1074  struct bytecode_buffer *buffer) {
1075  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1076  if(reg->rel_reg) {
1077  WARN("Relative addressing not supported in <= ps_3_0\n");
1078  This->state = E_INVALIDARG;
1079  return;
1080  }
1081 
1082  switch(reg->type) {
1083  case BWRITERSPR_INPUT:
1084  token |= map_ps_input(This, reg);
1085  break;
1086 
1087  /* Take care about the texture temporaries. There's a problem: They aren't
1088  * declared anywhere, so we can only hardcode the values that are used
1089  * to map ps_1_3 shaders to the common shader structure
1090  */
1091  case BWRITERSPR_TEMP:
1092  token |= map_ps13_temp(This, reg);
1093  break;
1094 
1095  case BWRITERSPR_CONST: /* Can be mapped 1:1 */
1096  token |= d3dsp_register( reg->type, reg->regnum );
1097  break;
1098 
1099  default:
1100  WARN("Invalid register type for <= ps_1_3 shader\n");
1101  This->state = E_INVALIDARG;
1102  return;
1103  }
1104 
1105  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1106 
1107  if(reg->srcmod == BWRITERSPSM_DZ || reg->srcmod == BWRITERSPSM_DW ||
1108  reg->srcmod == BWRITERSPSM_ABS || reg->srcmod == BWRITERSPSM_ABSNEG ||
1109  reg->srcmod == BWRITERSPSM_NOT) {
1110  WARN("Invalid source modifier %u for <= ps_1_3\n", reg->srcmod);
1111  This->state = E_INVALIDARG;
1112  return;
1113  }
1114  token |= d3d9_srcmod(reg->srcmod);
1116 }
1117 
1118 static void ps_1_0123_dstreg(struct bc_writer *This, const struct shader_reg *reg,
1119  struct bytecode_buffer *buffer,
1120  DWORD shift, DWORD mod) {
1121  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1122 
1123  if(reg->rel_reg) {
1124  WARN("Relative addressing not supported for destination registers\n");
1125  This->state = E_INVALIDARG;
1126  return;
1127  }
1128 
1129  switch(reg->type) {
1130  case BWRITERSPR_TEMP:
1131  token |= map_ps13_temp(This, reg);
1132  break;
1133 
1134  /* texkill uses the input register as a destination parameter */
1135  case BWRITERSPR_INPUT:
1136  token |= map_ps_input(This, reg);
1137  break;
1138 
1139  default:
1140  WARN("Invalid dest register type for 1.x pshader\n");
1141  This->state = E_INVALIDARG;
1142  return;
1143  }
1144 
1146  token |= d3d9_dstmod(mod);
1147 
1148  token |= d3d9_writemask(reg->u.writemask);
1150 }
1151 
1152 /* The length of an instruction consists of the destination register (if any),
1153  * the number of source registers, the number of address registers used for
1154  * indirect addressing, and optionally the predicate register
1155  */
1156 static DWORD instrlen(const struct instruction *instr, unsigned int srcs, unsigned int dsts) {
1157  unsigned int i;
1158  DWORD ret = srcs + dsts + (instr->has_predicate ? 1 : 0);
1159 
1160  if(dsts){
1161  if(instr->dst.rel_reg) ret++;
1162  }
1163  for(i = 0; i < srcs; i++) {
1164  if(instr->src[i].rel_reg) ret++;
1165  }
1166  return ret;
1167 }
1168 
1169 static void sm_1_x_opcode(struct bc_writer *This,
1170  const struct instruction *instr,
1171  DWORD token, struct bytecode_buffer *buffer) {
1172  /* In sm_1_x instruction length isn't encoded */
1173  if(instr->coissue){
1174  token |= D3DSI_COISSUE;
1175  }
1177 }
1178 
1179 static void instr_handler(struct bc_writer *This,
1180  const struct instruction *instr,
1181  struct bytecode_buffer *buffer) {
1182  DWORD token = d3d9_opcode(instr->opcode);
1183 
1184  This->funcs->opcode(This, instr, token, buffer);
1185  if(instr->has_dst) This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1187 }
1188 
1189 static const struct instr_handler_table vs_1_x_handlers[] = {
1216 
1217  {BWRITERSIO_END, NULL}, /* Sentinel value, it signals
1218  the end of the list */
1219 };
1220 
1221 static const struct bytecode_backend vs_1_x_backend = {
1222  vs_1_x_header,
1223  end,
1224  vs_1_x_srcreg,
1225  vs_12_dstreg,
1226  sm_1_x_opcode,
1228 };
1229 
1231  const struct instruction *instr,
1232  struct bytecode_buffer *buffer) {
1233  DWORD idx;
1234  struct shader_reg reg;
1235  DWORD swizzlemask;
1236 
1237  if(instr->src[1].type != BWRITERSPR_SAMPLER ||
1238  instr->src[1].regnum > 3) {
1239  WARN("Unsupported sampler type %u regnum %u\n",
1240  instr->src[1].type, instr->src[1].regnum);
1241  This->state = E_INVALIDARG;
1242  return;
1243  } else if(instr->dst.type != BWRITERSPR_TEMP) {
1244  WARN("Can only sample into a temp register\n");
1245  This->state = E_INVALIDARG;
1246  return;
1247  }
1248 
1249  idx = instr->src[1].regnum;
1250  if((idx == 0 && instr->dst.regnum != T0_REG) ||
1251  (idx == 1 && instr->dst.regnum != T1_REG) ||
1252  (idx == 2 && instr->dst.regnum != T2_REG) ||
1253  (idx == 3 && instr->dst.regnum != T3_REG)) {
1254  WARN("Sampling from sampler s%u to register r%u is not possible in ps_1_x\n",
1255  idx, instr->dst.regnum);
1256  This->state = E_INVALIDARG;
1257  return;
1258  }
1259  if(instr->src[0].type == BWRITERSPR_INPUT) {
1260  /* A simple non-dependent read tex instruction */
1261  if(instr->src[0].regnum != This->t_regnum[idx]) {
1262  WARN("Cannot sample from s%u with texture address data from interpolator %u\n",
1263  idx, instr->src[0].regnum);
1264  This->state = E_INVALIDARG;
1265  return;
1266  }
1267  This->funcs->opcode(This, instr, D3DSIO_TEX & D3DSI_OPCODE_MASK, buffer);
1268 
1269  /* map the temp dstreg to the ps_1_3 texture temporary register */
1270  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1271  } else if(instr->src[0].type == BWRITERSPR_TEMP) {
1272 
1273  swizzlemask = (3 << BWRITERVS_SWIZZLE_SHIFT) |
1274  (3 << (BWRITERVS_SWIZZLE_SHIFT + 2)) |
1275  (3 << (BWRITERVS_SWIZZLE_SHIFT + 4));
1276  if((instr->src[0].u.swizzle & swizzlemask) == (BWRITERVS_X_X | BWRITERVS_Y_Y | BWRITERVS_Z_Z)) {
1277  TRACE("writing texreg2rgb\n");
1279  } else if(instr->src[0].u.swizzle == (BWRITERVS_X_W | BWRITERVS_Y_X | BWRITERVS_Z_X | BWRITERVS_W_X)) {
1280  TRACE("writing texreg2ar\n");
1281  This->funcs->opcode(This, instr, D3DSIO_TEXREG2AR & D3DSI_OPCODE_MASK, buffer);
1282  } else if(instr->src[0].u.swizzle == (BWRITERVS_X_Y | BWRITERVS_Y_Z | BWRITERVS_Z_Z | BWRITERVS_W_Z)) {
1283  TRACE("writing texreg2gb\n");
1284  This->funcs->opcode(This, instr, D3DSIO_TEXREG2GB & D3DSI_OPCODE_MASK, buffer);
1285  } else {
1286  WARN("Unsupported src addr swizzle in dependent texld: 0x%08x\n", instr->src[0].u.swizzle);
1287  This->state = E_INVALIDARG;
1288  return;
1289  }
1290 
1291  /* Dst and src reg can be mapped normally. Both registers are temporary registers in the
1292  * source shader and have to be mapped to the temporary form of the texture registers. However,
1293  * the src reg doesn't have a swizzle
1294  */
1295  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1296  reg = instr->src[0];
1297  reg.u.swizzle = BWRITERVS_NOSWIZZLE;
1298  This->funcs->srcreg(This, &reg, buffer);
1299  } else {
1300  WARN("Invalid address data source register\n");
1301  This->state = E_INVALIDARG;
1302  return;
1303  }
1304 }
1305 
1306 static void instr_ps_1_0123_mov(struct bc_writer *This,
1307  const struct instruction *instr,
1308  struct bytecode_buffer *buffer) {
1310 
1311  if(instr->dst.type == BWRITERSPR_TEMP && instr->src[0].type == BWRITERSPR_INPUT) {
1312  if((instr->dst.regnum == T0_REG && instr->src[0].regnum == This->t_regnum[0]) ||
1313  (instr->dst.regnum == T1_REG && instr->src[0].regnum == This->t_regnum[1]) ||
1314  (instr->dst.regnum == T2_REG && instr->src[0].regnum == This->t_regnum[2]) ||
1315  (instr->dst.regnum == T3_REG && instr->src[0].regnum == This->t_regnum[3])) {
1316  if(instr->dstmod & BWRITERSPDM_SATURATE) {
1317  This->funcs->opcode(This, instr, D3DSIO_TEXCOORD & D3DSI_OPCODE_MASK, buffer);
1318  /* Remove the SATURATE flag, it's implicit to the instruction */
1319  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod & (~BWRITERSPDM_SATURATE));
1320  return;
1321  } else {
1322  WARN("A varying -> temp copy is only supported with the SATURATE modifier in <=ps_1_3\n");
1323  This->state = E_INVALIDARG;
1324  return;
1325  }
1326  } else if(instr->src[0].regnum == This->v_regnum[0] ||
1327  instr->src[0].regnum == This->v_regnum[1]) {
1328  /* Handled by the normal mov below. Just drop out of the if condition */
1329  } else {
1330  WARN("Unsupported varying -> temp mov in <= ps_1_3\n");
1331  This->state = E_INVALIDARG;
1332  return;
1333  }
1334  }
1335 
1336  This->funcs->opcode(This, instr, token, buffer);
1337  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1338  This->funcs->srcreg(This, &instr->src[0], buffer);
1339 }
1340 
1341 static const struct instr_handler_table ps_1_0123_handlers[] = {
1351 
1352  /* pshader instructions */
1369  {BWRITERSIO_END, NULL},
1370 };
1371 
1372 static const struct bytecode_backend ps_1_0123_backend = {
1373  ps_1_x_header,
1374  end,
1377  sm_1_x_opcode,
1379 };
1380 
1381 static void ps_1_4_srcreg(struct bc_writer *This, const struct shader_reg *reg,
1382  struct bytecode_buffer *buffer) {
1383  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1384  if(reg->rel_reg) {
1385  WARN("Relative addressing not supported in <= ps_3_0\n");
1386  This->state = E_INVALIDARG;
1387  return;
1388  }
1389 
1390  switch(reg->type) {
1391  case BWRITERSPR_INPUT:
1392  token |= map_ps_input(This, reg);
1393  break;
1394 
1395  /* Can be mapped 1:1 */
1396  case BWRITERSPR_TEMP:
1397  case BWRITERSPR_CONST:
1398  token |= d3dsp_register( reg->type, reg->regnum );
1399  break;
1400 
1401  default:
1402  WARN("Invalid register type for ps_1_4 shader\n");
1403  This->state = E_INVALIDARG;
1404  return;
1405  }
1406 
1407  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1408 
1409  if(reg->srcmod == BWRITERSPSM_ABS || reg->srcmod == BWRITERSPSM_ABSNEG ||
1410  reg->srcmod == BWRITERSPSM_NOT) {
1411  WARN("Invalid source modifier %u for ps_1_4\n", reg->srcmod);
1412  This->state = E_INVALIDARG;
1413  return;
1414  }
1415  token |= d3d9_srcmod(reg->srcmod);
1417 }
1418 
1419 static void ps_1_4_dstreg(struct bc_writer *This, const struct shader_reg *reg,
1420  struct bytecode_buffer *buffer,
1421  DWORD shift, DWORD mod) {
1422  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1423 
1424  if(reg->rel_reg) {
1425  WARN("Relative addressing not supported for destination registers\n");
1426  This->state = E_INVALIDARG;
1427  return;
1428  }
1429 
1430  switch(reg->type) {
1431  case BWRITERSPR_TEMP: /* 1:1 mapping */
1432  token |= d3dsp_register( reg->type, reg->regnum );
1433  break;
1434 
1435  /* For texkill */
1436  case BWRITERSPR_INPUT:
1437  token |= map_ps_input(This, reg);
1438  break;
1439 
1440  default:
1441  WARN("Invalid dest register type for 1.x pshader\n");
1442  This->state = E_INVALIDARG;
1443  return;
1444  }
1445 
1447  token |= d3d9_dstmod(mod);
1448 
1449  token |= d3d9_writemask(reg->u.writemask);
1451 }
1452 
1453 static void instr_ps_1_4_mov(struct bc_writer *This,
1454  const struct instruction *instr,
1455  struct bytecode_buffer *buffer) {
1457 
1458  if(instr->dst.type == BWRITERSPR_TEMP && instr->src[0].type == BWRITERSPR_INPUT) {
1459  if(instr->src[0].regnum == This->t_regnum[0] ||
1460  instr->src[0].regnum == This->t_regnum[1] ||
1461  instr->src[0].regnum == This->t_regnum[2] ||
1462  instr->src[0].regnum == This->t_regnum[3] ||
1463  instr->src[0].regnum == This->t_regnum[4] ||
1464  instr->src[0].regnum == This->t_regnum[5]) {
1465  /* Similar to a regular mov, but a different opcode */
1467  } else if(instr->src[0].regnum == This->v_regnum[0] ||
1468  instr->src[0].regnum == This->v_regnum[1]) {
1469  /* Handled by the normal mov below. Just drop out of the if condition */
1470  } else {
1471  WARN("Unsupported varying -> temp mov in ps_1_4\n");
1472  This->state = E_INVALIDARG;
1473  return;
1474  }
1475  }
1476 
1477  This->funcs->opcode(This, instr, token, buffer);
1478  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1479  This->funcs->srcreg(This, &instr->src[0], buffer);
1480 }
1481 
1482 static void instr_ps_1_4_texld(struct bc_writer *This,
1483  const struct instruction *instr,
1484  struct bytecode_buffer *buffer) {
1485  if(instr->src[1].type != BWRITERSPR_SAMPLER ||
1486  instr->src[1].regnum > 5) {
1487  WARN("Unsupported sampler type %u regnum %u\n",
1488  instr->src[1].type, instr->src[1].regnum);
1489  This->state = E_INVALIDARG;
1490  return;
1491  } else if(instr->dst.type != BWRITERSPR_TEMP) {
1492  WARN("Can only sample into a temp register\n");
1493  This->state = E_INVALIDARG;
1494  return;
1495  }
1496 
1497  if(instr->src[1].regnum != instr->dst.regnum) {
1498  WARN("Sampling from sampler s%u to register r%u is not possible in ps_1_4\n",
1499  instr->src[1].regnum, instr->dst.regnum);
1500  This->state = E_INVALIDARG;
1501  return;
1502  }
1503 
1504  This->funcs->opcode(This, instr, D3DSIO_TEX & D3DSI_OPCODE_MASK, buffer);
1505  This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
1506  This->funcs->srcreg(This, &instr->src[0], buffer);
1507 }
1508 
1509 static const struct instr_handler_table ps_1_4_handlers[] = {
1519 
1520  /* pshader instructions */
1527 
1529  {BWRITERSIO_END, NULL},
1530 };
1531 
1532 static const struct bytecode_backend ps_1_4_backend = {
1533  ps_1_4_header,
1534  end,
1535  ps_1_4_srcreg,
1536  ps_1_4_dstreg,
1537  sm_1_x_opcode,
1539 };
1540 
1541 static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
1543 }
1544 
1545 static void write_constI(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
1547 }
1548 
1549 static void vs_2_header(struct bc_writer *This,
1550  const struct bwriter_shader *shader,
1551  struct bytecode_buffer *buffer) {
1552  HRESULT hr;
1553 
1555  if(FAILED(hr)) {
1556  This->state = hr;
1557  return;
1558  }
1559 
1560  write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT);
1564 }
1565 
1566 static void vs_2_srcreg(struct bc_writer *This,
1567  const struct shader_reg *reg,
1568  struct bytecode_buffer *buffer) {
1569  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1570  DWORD has_swizzle;
1571  DWORD component;
1572  DWORD d3d9reg;
1573 
1574  switch(reg->type) {
1575  case BWRITERSPR_OUTPUT:
1576  /* Map the swizzle to a writemask, the format expected
1577  by map_vs_output
1578  */
1579  switch(reg->u.swizzle) {
1580  case BWRITERVS_SWIZZLE_X:
1581  component = BWRITERSP_WRITEMASK_0;
1582  break;
1583  case BWRITERVS_SWIZZLE_Y:
1584  component = BWRITERSP_WRITEMASK_1;
1585  break;
1586  case BWRITERVS_SWIZZLE_Z:
1587  component = BWRITERSP_WRITEMASK_2;
1588  break;
1589  case BWRITERVS_SWIZZLE_W:
1590  component = BWRITERSP_WRITEMASK_3;
1591  break;
1592  default:
1593  component = 0;
1594  }
1595  token |= map_vs_output(This, reg->regnum, component, &has_swizzle);
1596  break;
1597 
1598  case BWRITERSPR_RASTOUT:
1599  case BWRITERSPR_ATTROUT:
1600  /* These registers are mapped to input and output regs. They can be encoded in the bytecode,
1601  * but are unexpected. If we hit this path it might be due to an error.
1602  */
1603  FIXME("Unexpected register type %u\n", reg->type);
1604  /* drop through */
1605  case BWRITERSPR_INPUT:
1606  case BWRITERSPR_TEMP:
1607  case BWRITERSPR_CONST:
1608  case BWRITERSPR_ADDR:
1609  case BWRITERSPR_CONSTINT:
1610  case BWRITERSPR_CONSTBOOL:
1611  case BWRITERSPR_LABEL:
1612  d3d9reg = d3d9_register(reg->type);
1613  token |= d3dsp_register( d3d9reg, reg->regnum );
1614  break;
1615 
1616  case BWRITERSPR_LOOP:
1617  if(reg->regnum != 0) {
1618  WARN("Only regnum 0 is supported for the loop index register in vs_2_0\n");
1619  This->state = E_INVALIDARG;
1620  return;
1621  }
1622  token |= d3dsp_register( D3DSPR_LOOP, 0 );
1623  break;
1624 
1625  case BWRITERSPR_PREDICATE:
1626  if(This->version != BWRITERVS_VERSION(2, 1)){
1627  WARN("Predicate register is allowed only in vs_2_x\n");
1628  This->state = E_INVALIDARG;
1629  return;
1630  }
1631  if(reg->regnum > 0) {
1632  WARN("Only predicate register 0 is supported\n");
1633  This->state = E_INVALIDARG;
1634  return;
1635  }
1637  break;
1638 
1639  default:
1640  WARN("Invalid register type for 2.0 vshader\n");
1641  This->state = E_INVALIDARG;
1642  return;
1643  }
1644 
1645  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1646 
1647  token |= d3d9_srcmod(reg->srcmod);
1648 
1649  if(reg->rel_reg)
1651 
1653 
1654  /* vs_2_0 and newer write the register containing the index explicitly in the
1655  * binary code
1656  */
1658  vs_2_srcreg(This, reg->rel_reg, buffer);
1659 }
1660 
1661 static void sm_2_opcode(struct bc_writer *This,
1662  const struct instruction *instr,
1663  DWORD token, struct bytecode_buffer *buffer) {
1664  /* From sm 2 onwards instruction length is encoded in the opcode field */
1665  int dsts = instr->has_dst ? 1 : 0;
1666  token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
1667  if(instr->comptype)
1668  token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
1669  if(instr->has_predicate)
1672 }
1673 
1674 static const struct instr_handler_table vs_2_0_handlers[] = {
1709 
1721 
1722  {BWRITERSIO_END, NULL},
1723 };
1724 
1725 static const struct bytecode_backend vs_2_0_backend = {
1726  vs_2_header,
1727  end,
1728  vs_2_srcreg,
1729  vs_12_dstreg,
1730  sm_2_opcode,
1732 };
1733 
1734 static const struct instr_handler_table vs_2_x_handlers[] = {
1769 
1784 
1787 
1788  {BWRITERSIO_END, NULL},
1789 };
1790 
1791 static const struct bytecode_backend vs_2_x_backend = {
1792  vs_2_header,
1793  end,
1794  vs_2_srcreg,
1795  vs_12_dstreg,
1796  sm_2_opcode,
1798 };
1799 
1800 static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
1801  DWORD i;
1803  DWORD token;
1804  const DWORD reg = (1u << 31) | d3dsp_register( D3DSPR_SAMPLER, 0 ) | D3DSP_WRITEMASK_ALL;
1805 
1806  for(i = 0; i < shader->num_samplers; i++) {
1807  /* Write the DCL instruction */
1809  token = (1u << 31);
1810  /* Already shifted */
1811  token |= (d3d9_sampler(shader->samplers[i].type)) & D3DSP_TEXTURETYPE_MASK;
1813  token = reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK);
1814  token |= d3d9_dstmod(shader->samplers[i].mod);
1816  }
1817 }
1818 
1819 static void ps_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
1821  if(FAILED(hr)) {
1822  This->state = hr;
1823  return;
1824  }
1825 
1826  write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT);
1831 }
1832 
1833 static void ps_2_srcreg(struct bc_writer *This,
1834  const struct shader_reg *reg,
1835  struct bytecode_buffer *buffer) {
1836  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1837  DWORD d3d9reg;
1838  if(reg->rel_reg) {
1839  WARN("Relative addressing not supported in <= ps_3_0\n");
1840  This->state = E_INVALIDARG;
1841  return;
1842  }
1843 
1844  switch(reg->type) {
1845  case BWRITERSPR_INPUT:
1846  token |= map_ps_input(This, reg);
1847  break;
1848 
1849  /* Can be mapped 1:1 */
1850  case BWRITERSPR_TEMP:
1851  case BWRITERSPR_CONST:
1852  case BWRITERSPR_COLOROUT:
1853  case BWRITERSPR_CONSTBOOL:
1854  case BWRITERSPR_CONSTINT:
1855  case BWRITERSPR_SAMPLER:
1856  case BWRITERSPR_LABEL:
1857  case BWRITERSPR_DEPTHOUT:
1858  d3d9reg = d3d9_register(reg->type);
1859  token |= d3dsp_register( d3d9reg, reg->regnum );
1860  break;
1861 
1862  case BWRITERSPR_PREDICATE:
1863  if(This->version != BWRITERPS_VERSION(2, 1)){
1864  WARN("Predicate register not supported in ps_2_0\n");
1865  This->state = E_INVALIDARG;
1866  }
1867  if(reg->regnum) {
1868  WARN("Predicate register with regnum %u not supported\n",
1869  reg->regnum);
1870  This->state = E_INVALIDARG;
1871  }
1873  break;
1874 
1875  default:
1876  WARN("Invalid register type for ps_2_0 shader\n");
1877  This->state = E_INVALIDARG;
1878  return;
1879  }
1880 
1881  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1882 
1883  token |= d3d9_srcmod(reg->srcmod);
1885 }
1886 
1887 static void ps_2_0_dstreg(struct bc_writer *This,
1888  const struct shader_reg *reg,
1889  struct bytecode_buffer *buffer,
1890  DWORD shift, DWORD mod) {
1891  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
1892  DWORD d3d9reg;
1893 
1894  if(reg->rel_reg) {
1895  WARN("Relative addressing not supported for destination registers\n");
1896  This->state = E_INVALIDARG;
1897  return;
1898  }
1899 
1900  switch(reg->type) {
1901  case BWRITERSPR_TEMP: /* 1:1 mapping */
1902  case BWRITERSPR_COLOROUT:
1903  case BWRITERSPR_DEPTHOUT:
1904  d3d9reg = d3d9_register(reg->type);
1905  token |= d3dsp_register( d3d9reg, reg->regnum );
1906  break;
1907 
1908  case BWRITERSPR_PREDICATE:
1909  if(This->version != BWRITERPS_VERSION(2, 1)){
1910  WARN("Predicate register not supported in ps_2_0\n");
1911  This->state = E_INVALIDARG;
1912  }
1913  token |= d3dsp_register( D3DSPR_PREDICATE, reg->regnum );
1914  break;
1915 
1916  /* texkill uses the input register as a destination parameter */
1917  case BWRITERSPR_INPUT:
1918  token |= map_ps_input(This, reg);
1919  break;
1920 
1921  default:
1922  WARN("Invalid dest register type for 2.x pshader\n");
1923  This->state = E_INVALIDARG;
1924  return;
1925  }
1926 
1928  token |= d3d9_dstmod(mod);
1929 
1930  token |= d3d9_writemask(reg->u.writemask);
1932 }
1933 
1934 static const struct instr_handler_table ps_2_0_handlers[] = {
1965 
1970 
1971  {BWRITERSIO_END, NULL},
1972 };
1973 
1974 static const struct bytecode_backend ps_2_0_backend = {
1975  ps_2_header,
1976  end,
1977  ps_2_srcreg,
1978  ps_2_0_dstreg,
1979  sm_2_opcode,
1981 };
1982 
1983 static const struct instr_handler_table ps_2_x_handlers[] = {
2014 
2027 
2034 
2037 
2039 
2040  {BWRITERSIO_END, NULL},
2041 };
2042 
2043 static const struct bytecode_backend ps_2_x_backend = {
2044  ps_2_header,
2045  end,
2046  ps_2_srcreg,
2047  ps_2_0_dstreg,
2048  sm_2_opcode,
2050 };
2051 
2052 static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
2053  write_declarations(This, buffer, TRUE, shader->inputs, shader->num_inputs, BWRITERSPR_INPUT);
2054  write_declarations(This, buffer, TRUE, shader->outputs, shader->num_outputs, BWRITERSPR_OUTPUT);
2059 }
2060 
2061 static void sm_3_srcreg(struct bc_writer *This,
2062  const struct shader_reg *reg,
2063  struct bytecode_buffer *buffer) {
2064  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
2065  DWORD d3d9reg;
2066 
2067  d3d9reg = d3d9_register(reg->type);
2068  token |= d3dsp_register( d3d9reg, reg->regnum );
2069  token |= d3d9_swizzle(reg->u.swizzle) & D3DVS_SWIZZLE_MASK;
2070  token |= d3d9_srcmod(reg->srcmod);
2071 
2072  if(reg->rel_reg) {
2073  if(reg->type == BWRITERSPR_CONST && This->version == BWRITERPS_VERSION(3, 0)) {
2074  WARN("c%u[...] is unsupported in ps_3_0\n", reg->regnum);
2075  This->state = E_INVALIDARG;
2076  return;
2077  }
2078  if(((reg->rel_reg->type == BWRITERSPR_ADDR && This->version == BWRITERVS_VERSION(3, 0)) ||
2079  reg->rel_reg->type == BWRITERSPR_LOOP) &&
2080  reg->rel_reg->regnum == 0) {
2082  } else {
2083  WARN("Unsupported relative addressing register\n");
2084  This->state = E_INVALIDARG;
2085  return;
2086  }
2087  }
2088 
2090 
2091  /* vs_2_0 and newer write the register containing the index explicitly in the
2092  * binary code
2093  */
2095  sm_3_srcreg(This, reg->rel_reg, buffer);
2096  }
2097 }
2098 
2099 static void sm_3_dstreg(struct bc_writer *This,
2100  const struct shader_reg *reg,
2101  struct bytecode_buffer *buffer,
2102  DWORD shift, DWORD mod) {
2103  DWORD token = (1u << 31); /* Bit 31 of registers is 1 */
2104  DWORD d3d9reg;
2105 
2106  if(reg->rel_reg) {
2107  if(This->version == BWRITERVS_VERSION(3, 0) &&
2108  reg->type == BWRITERSPR_OUTPUT) {
2110  } else {
2111  WARN("Relative addressing not supported for this shader type or register type\n");
2112  This->state = E_INVALIDARG;
2113  return;
2114  }
2115  }
2116 
2117  d3d9reg = d3d9_register(reg->type);
2118  token |= d3dsp_register( d3d9reg, reg->regnum );
2119  token |= d3d9_dstmod(mod);
2120  token |= d3d9_writemask(reg->u.writemask);
2122 
2123  /* vs_2_0 and newer write the register containing the index explicitly in the
2124  * binary code
2125  */
2127  sm_3_srcreg(This, reg->rel_reg, buffer);
2128  }
2129 }
2130 
2131 static const struct instr_handler_table vs_3_handlers[] = {
2166 
2181 
2185 
2186  {BWRITERSIO_END, NULL},
2187 };
2188 
2189 static const struct bytecode_backend vs_3_backend = {
2190  sm_3_header,
2191  end,
2192  sm_3_srcreg,
2193  sm_3_dstreg,
2194  sm_2_opcode,
2196 };
2197 
2198 static const struct instr_handler_table ps_3_handlers[] = {
2229 
2244 
2248 
2256 
2257  {BWRITERSIO_END, NULL},
2258 };
2259 
2260 static const struct bytecode_backend ps_3_backend = {
2261  sm_3_header,
2262  end,
2263  sm_3_srcreg,
2264  sm_3_dstreg,
2265  sm_2_opcode,
2267 };
2268 
2269 static void init_vs10_dx9_writer(struct bc_writer *writer) {
2270  TRACE("Creating DirectX9 vertex shader 1.0 writer\n");
2271  writer->funcs = &vs_1_x_backend;
2272 }
2273 
2274 static void init_vs11_dx9_writer(struct bc_writer *writer) {
2275  TRACE("Creating DirectX9 vertex shader 1.1 writer\n");
2276  writer->funcs = &vs_1_x_backend;
2277 }
2278 
2279 static void init_vs20_dx9_writer(struct bc_writer *writer) {
2280  TRACE("Creating DirectX9 vertex shader 2.0 writer\n");
2281  writer->funcs = &vs_2_0_backend;
2282 }
2283 
2284 static void init_vs2x_dx9_writer(struct bc_writer *writer) {
2285  TRACE("Creating DirectX9 vertex shader 2.x writer\n");
2286  writer->funcs = &vs_2_x_backend;
2287 }
2288 
2289 static void init_vs30_dx9_writer(struct bc_writer *writer) {
2290  TRACE("Creating DirectX9 vertex shader 3.0 writer\n");
2291  writer->funcs = &vs_3_backend;
2292 }
2293 
2294 static void init_ps10_dx9_writer(struct bc_writer *writer) {
2295  TRACE("Creating DirectX9 pixel shader 1.0 writer\n");
2296  writer->funcs = &ps_1_0123_backend;
2297 }
2298 
2299 static void init_ps11_dx9_writer(struct bc_writer *writer) {
2300  TRACE("Creating DirectX9 pixel shader 1.1 writer\n");
2301  writer->funcs = &ps_1_0123_backend;
2302 }
2303 
2304 static void init_ps12_dx9_writer(struct bc_writer *writer) {
2305  TRACE("Creating DirectX9 pixel shader 1.2 writer\n");
2306  writer->funcs = &ps_1_0123_backend;
2307 }
2308 
2309 static void init_ps13_dx9_writer(struct bc_writer *writer) {
2310  TRACE("Creating DirectX9 pixel shader 1.3 writer\n");
2311  writer->funcs = &ps_1_0123_backend;
2312 }
2313 
2314 static void init_ps14_dx9_writer(struct bc_writer *writer) {
2315  TRACE("Creating DirectX9 pixel shader 1.4 writer\n");
2316  writer->funcs = &ps_1_4_backend;
2317 }
2318 
2319 static void init_ps20_dx9_writer(struct bc_writer *writer) {
2320  TRACE("Creating DirectX9 pixel shader 2.0 writer\n");
2321  writer->funcs = &ps_2_0_backend;
2322 }
2323 
2324 static void init_ps2x_dx9_writer(struct bc_writer *writer) {
2325  TRACE("Creating DirectX9 pixel shader 2.x writer\n");
2326  writer->funcs = &ps_2_x_backend;
2327 }
2328 
2329 static void init_ps30_dx9_writer(struct bc_writer *writer) {
2330  TRACE("Creating DirectX9 pixel shader 3.0 writer\n");
2331  writer->funcs = &ps_3_backend;
2332 }
2333 
2334 static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
2335  struct bc_writer *ret = d3dcompiler_alloc(sizeof(*ret));
2336 
2337  if(!ret) {
2338  WARN("Failed to allocate a bytecode writer instance\n");
2339  return NULL;
2340  }
2341 
2342  switch(version) {
2343  case BWRITERVS_VERSION(1, 0):
2344  if(dxversion != 9) {
2345  WARN("Unsupported dxversion for vertex shader 1.0 requested: %u\n", dxversion);
2346  goto fail;
2347  }
2349  break;
2350  case BWRITERVS_VERSION(1, 1):
2351  if(dxversion != 9) {
2352  WARN("Unsupported dxversion for vertex shader 1.1 requested: %u\n", dxversion);
2353  goto fail;
2354  }
2356  break;
2357  case BWRITERVS_VERSION(2, 0):
2358  if(dxversion != 9) {
2359  WARN("Unsupported dxversion for vertex shader 2.0 requested: %u\n", dxversion);
2360  goto fail;
2361  }
2363  break;
2364  case BWRITERVS_VERSION(2, 1):
2365  if(dxversion != 9) {
2366  WARN("Unsupported dxversion for vertex shader 2.x requested: %u\n", dxversion);
2367  goto fail;
2368  }
2370  break;
2371  case BWRITERVS_VERSION(3, 0):
2372  if(dxversion != 9) {
2373  WARN("Unsupported dxversion for vertex shader 3.0 requested: %u\n", dxversion);
2374  goto fail;
2375  }
2377  break;
2378 
2379  case BWRITERPS_VERSION(1, 0):
2380  if(dxversion != 9) {
2381  WARN("Unsupported dxversion for pixel shader 1.0 requested: %u\n", dxversion);
2382  goto fail;
2383  }
2385  break;
2386  case BWRITERPS_VERSION(1, 1):
2387  if(dxversion != 9) {
2388  WARN("Unsupported dxversion for pixel shader 1.1 requested: %u\n", dxversion);
2389  goto fail;
2390  }
2392  break;
2393  case BWRITERPS_VERSION(1, 2):
2394  if(dxversion != 9) {
2395  WARN("Unsupported dxversion for pixel shader 1.2 requested: %u\n", dxversion);
2396  goto fail;
2397  }
2399  break;
2400  case BWRITERPS_VERSION(1, 3):
2401  if(dxversion != 9) {
2402  WARN("Unsupported dxversion for pixel shader 1.3 requested: %u\n", dxversion);
2403  goto fail;
2404  }
2406  break;
2407  case BWRITERPS_VERSION(1, 4):
2408  if(dxversion != 9) {
2409  WARN("Unsupported dxversion for pixel shader 1.4 requested: %u\n", dxversion);
2410  goto fail;
2411  }
2413  break;
2414 
2415  case BWRITERPS_VERSION(2, 0):
2416  if(dxversion != 9) {
2417  WARN("Unsupported dxversion for pixel shader 2.0 requested: %u\n", dxversion);
2418  goto fail;
2419  }
2421  break;
2422 
2423  case BWRITERPS_VERSION(2, 1):
2424  if(dxversion != 9) {
2425  WARN("Unsupported dxversion for pixel shader 2.x requested: %u\n", dxversion);
2426  goto fail;
2427  }
2429  break;
2430 
2431  case BWRITERPS_VERSION(3, 0):
2432  if(dxversion != 9) {
2433  WARN("Unsupported dxversion for pixel shader 3.0 requested: %u\n", dxversion);
2434  goto fail;
2435  }
2437  break;
2438 
2439  default:
2440  WARN("Unexpected shader version requested: %08x\n", version);
2441  goto fail;
2442  }
2443  ret->version = version;
2444  return ret;
2445 
2446 fail:
2448  return NULL;
2449 }
2450 
2451 static HRESULT call_instr_handler(struct bc_writer *writer,
2452  const struct instruction *instr,
2453  struct bytecode_buffer *buffer) {
2454  DWORD i=0;
2455 
2456  while(writer->funcs->instructions[i].opcode != BWRITERSIO_END) {
2457  if(instr->opcode == writer->funcs->instructions[i].opcode) {
2458  if(!writer->funcs->instructions[i].func) {
2459  WARN("Opcode %u not supported by this profile\n", instr->opcode);
2460  return E_INVALIDARG;
2461  }
2462  writer->funcs->instructions[i].func(writer, instr, buffer);
2463  return S_OK;
2464  }
2465  i++;
2466  }
2467 
2468  FIXME("Unhandled instruction %u - %s\n", instr->opcode,
2469  debug_print_opcode(instr->opcode));
2470  return E_INVALIDARG;
2471 }
2472 
2474 {
2475  struct bc_writer *writer;
2476  struct bytecode_buffer *buffer = NULL;
2477  HRESULT hr;
2478  unsigned int i;
2479 
2480  if(!shader){
2481  ERR("NULL shader structure, aborting\n");
2482  return E_FAIL;
2483  }
2484  writer = create_writer(shader->version, dxversion);
2485  *result = NULL;
2486 
2487  if(!writer) {
2488  WARN("Could not create a bytecode writer instance. Either unsupported version\n");
2489  WARN("or out of memory\n");
2490  hr = E_FAIL;
2491  goto error;
2492  }
2493 
2494  buffer = allocate_buffer();
2495  if(!buffer) {
2496  WARN("Failed to allocate a buffer for the shader bytecode\n");
2497  hr = E_FAIL;
2498  goto error;
2499  }
2500 
2501  /* Write shader type and version */
2502  put_dword(buffer, shader->version);
2503 
2504  writer->funcs->header(writer, shader, buffer);
2505  if(FAILED(writer->state)) {
2506  hr = writer->state;
2507  goto error;
2508  }
2509 
2510  for(i = 0; i < shader->num_instrs; i++) {
2511  hr = call_instr_handler(writer, shader->instr[i], buffer);
2512  if(FAILED(hr)) {
2513  goto error;
2514  }
2515  }
2516 
2517  if(FAILED(writer->state)) {
2518  hr = writer->state;
2519  goto error;
2520  }
2521 
2522  writer->funcs->end(writer, shader, buffer);
2523 
2524  if(FAILED(buffer->state)) {
2525  hr = buffer->state;
2526  goto error;
2527  }
2528 
2529  *size = buffer->size * sizeof(DWORD);
2530  *result = buffer->data;
2531  buffer->data = NULL;
2532  hr = S_OK;
2533 
2534 error:
2535  if(buffer) {
2536  d3dcompiler_free(buffer->data);
2538  }
2539  d3dcompiler_free(writer);
2540  return hr;
2541 }
2542 
2544  unsigned int i, j;
2545 
2546  TRACE("Deleting shader %p\n", shader);
2547 
2548  for(i = 0; i < shader->num_cf; i++) {
2549  d3dcompiler_free(shader->constF[i]);
2550  }
2551  d3dcompiler_free(shader->constF);
2552  for(i = 0; i < shader->num_ci; i++) {
2553  d3dcompiler_free(shader->constI[i]);
2554  }
2555  d3dcompiler_free(shader->constI);
2556  for(i = 0; i < shader->num_cb; i++) {
2557  d3dcompiler_free(shader->constB[i]);
2558  }
2559  d3dcompiler_free(shader->constB);
2560 
2561  d3dcompiler_free(shader->inputs);
2562  d3dcompiler_free(shader->outputs);
2563  d3dcompiler_free(shader->samplers);
2564 
2565  for(i = 0; i < shader->num_instrs; i++) {
2566  for(j = 0; j < shader->instr[i]->num_srcs; j++) {
2567  d3dcompiler_free(shader->instr[i]->src[j].rel_reg);
2568  }
2569  d3dcompiler_free(shader->instr[i]->src);
2570  d3dcompiler_free(shader->instr[i]->dst.rel_reg);
2571  d3dcompiler_free(shader->instr[i]);
2572  }
2573  d3dcompiler_free(shader->instr);
2574 
2576 }
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 * u
Definition: glfuncs.h:240
#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)
static const struct instr_handler_table ps_3_handlers[]
#define BWRITERVS_W_Y
#define BWRITERSP_WRITEMASK_1
static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
BOOL add_constI(struct bwriter_shader *shader, DWORD reg, INT x, INT y, INT z, INT w)
#define D3DSP_REGTYPE_MASK2
Definition: d3d9types.h:508
#define BWRITERVS_SWIZZLE_SHIFT
const char * debug_print_opcode(DWORD opcode) DECLSPEC_HIDDEN
Definition: utils.c:416
static DWORD map_ps_input(struct bc_writer *This, const struct shader_reg *reg)
#define TRUE
Definition: types.h:120
static void * d3dcompiler_realloc(void *ptr, SIZE_T size)
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define shift
Definition: input.c:1668
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static void instr_ps_1_4_texld(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
#define D3DVS_Z_Y
Definition: d3d8types.h:442
static void sm_3_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void init_ps2x_dx9_writer(struct bc_writer *writer)
static DWORD map_ps13_temp(struct bc_writer *This, const struct shader_reg *reg)
#define BWRITERSP_WRITEMASK_ALL
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
static const struct bytecode_backend ps_1_0123_backend
union constant::@229 value[4]
struct x86_inst instr
static void init_vs30_dx9_writer(struct bc_writer *writer)
static DWORD d3d9_sampler(DWORD bwriter_sampler)
#define D3DVS_X_Y
Definition: d3d8types.h:432
static void init_ps11_dx9_writer(struct bc_writer *writer)
static void init_vs20_dx9_writer(struct bc_writer *writer)
static HRESULT call_instr_handler(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
WINE_DEFAULT_DEBUG_CHANNEL(bytecodewriter)
static void init_vs10_dx9_writer(struct bc_writer *writer)
#define BYTECODEBUFFER_INITIAL_SIZE
#define WARN(fmt,...)
Definition: debug.h:111
#define U(x)
Definition: wordpad.c:44
static void ps_1_0123_dstreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer, DWORD shift, DWORD mod)
static BOOL d3dcompiler_free(void *ptr)
#define D3DSP_DCL_USAGEINDEX_SHIFT
Definition: d3d9types.h:463
static void ps_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void write_const(struct constant **consts, int num, DWORD opcode, DWORD reg_type, struct bytecode_buffer *buffer, BOOL len)
struct instruction * alloc_instr(unsigned int srcs)
static const struct instr_handler_table vs_2_x_handlers[]
#define D3DVS_Y_Z
Definition: d3d8types.h:438
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
GLuint buffer
Definition: glext.h:5915
#define T1_REG
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static DWORD d3d9_writemask(DWORD bwriter_writemask)
#define D3DVS_Y_X
Definition: d3d8types.h:436
static struct bytecode_buffer * allocate_buffer(void)
static void instr_ps_1_0123_mov(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr)
static void sm_3_dstreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer, DWORD shift, DWORD mod)
static void write_declarations(struct bc_writer *This, struct bytecode_buffer *buffer, BOOL len, const struct declaration *decls, unsigned int num, DWORD type)
static DWORD d3d9_dstmod(DWORD bwriter_mod)
#define BWRITERVS_SWIZZLE_Z
#define E_FAIL
Definition: ddrawi.h:102
#define D3DSHADER_INSTRUCTION_PREDICATED
Definition: d3d9types.h:452
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
#define D3DSP_WRITEMASK_ALL
Definition: d3d8types.h:378
#define BWRITERVS_Z_Z
static const struct bytecode_backend ps_3_backend
#define D3DVS_Z_W
Definition: d3d8types.h:444
static void * d3dcompiler_alloc(SIZE_T size)
static DWORD d3d9_swizzle(DWORD bwriter_swizzle)
static const struct bytecode_backend vs_2_x_backend
static void write_srcregs(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
static struct bc_writer * create_writer(DWORD version, DWORD dxversion)
#define D3DSP_REGTYPE_SHIFT
Definition: d3d8types.h:394
#define D3DVS_W_Z
Definition: d3d8types.h:448
static const struct bytecode_backend vs_2_0_backend
#define D3DSP_WRITEMASK_2
Definition: d3d8types.h:376
static void ps_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
#define D3DVS_ADDRESSMODE_MASK
Definition: d3d8types.h:417
#define BWRITERVS_X_X
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
GLenum GLint GLuint mask
Definition: glext.h:6028
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static void init_ps13_dx9_writer(struct bc_writer *writer)
#define D3DVS_Y_W
Definition: d3d8types.h:439
#define BWRITERVS_W_W
unsigned int BOOL
Definition: ntddk_ex.h:94
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 token
Definition: glfuncs.h:210
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
#define D3DVS_SWIZZLE_MASK
Definition: d3d8types.h:426
#define FIXME(fmt,...)
Definition: debug.h:110
unsigned int idx
Definition: utils.c:41
#define E_INVALIDARG
Definition: ddrawi.h:101
GLdouble GLdouble z
Definition: glext.h:5874
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
static const struct bytecode_backend vs_1_x_backend
static DWORD d3d9_comparetype(DWORD asmshader_comparetype)
#define D3DVS_W_W
Definition: d3d8types.h:449
static DWORD d3d9_register(DWORD bwriter_register)
#define D3DVS_X_Z
Definition: d3d8types.h:433
BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w)
static const struct instr_handler_table ps_2_x_handlers[]
#define D3DVS_W_Y
Definition: d3d8types.h:447
#define D3DVS_Z_Z
Definition: d3d8types.h:443
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 GLint GLint j
Definition: glfuncs.h:250
static void ps_1_4_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void init_ps30_dx9_writer(struct bc_writer *writer)
static void init_ps20_dx9_writer(struct bc_writer *writer)
#define D3DSP_WRITEMASK_0
Definition: d3d8types.h:374
GLuint shader
Definition: glext.h:6030
static void vs_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define d
Definition: ke_i.h:81
static void init_ps12_dx9_writer(struct bc_writer *writer)
#define T0_REG
static DWORD d3d9_opcode(DWORD bwriter_opcode)
HRESULT SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result, DWORD *size)
#define D3DSP_DCL_USAGE_SHIFT
Definition: d3d9types.h:460
static const struct instr_handler_table ps_1_0123_handlers[]
LONG HRESULT
Definition: typedefs.h:77
#define BWRITERVS_Z_Y
static void init_ps10_dx9_writer(struct bc_writer *writer)
#define D3DVS_Y_Y
Definition: d3d8types.h:437
#define D3DSI_TEXLD_PROJECT
Definition: d3d9types.h:454
#define D3DSP_DSTSHIFT_SHIFT
Definition: d3d8types.h:390
static const struct instr_handler_table ps_1_4_handlers[]
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static DWORD instrlen(const struct instruction *instr, unsigned int srcs, unsigned int dsts)
#define D3DSP_DCL_USAGE_MASK
Definition: d3d9types.h:461
static const struct instr_handler_table vs_2_0_handlers[]
static void vs_12_dstreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer, DWORD shift, DWORD mod)
static void ps_2_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
#define D3DSP_DSTSHIFT_MASK
Definition: d3d8types.h:391
int ret
static void sm_2_opcode(struct bc_writer *This, const struct instruction *instr, DWORD token, struct bytecode_buffer *buffer)
#define BWRITERSP_WRITEMASK_3
#define D3DVS_Z_X
Definition: d3d8types.h:441
static void instr_handler(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
static const struct bytecode_backend ps_2_0_backend
#define BWRITERSP_WRITEMASK_2
#define BWRITERVS_X_Y
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
#define BWRITERVS_Z_X
GLenum GLsizei len
Definition: glext.h:6722
enum _D3DSHADER_PARAM_REGISTER_TYPE D3DSHADER_PARAM_REGISTER_TYPE
void SlDeleteShader(struct bwriter_shader *shader)
static void put_dword(struct bytecode_buffer *buffer, DWORD value)
#define BWRITERVS_SWIZZLE_X
static void ps_1_0123_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static HRESULT vs_find_builtin_varyings(struct bc_writer *This, const struct bwriter_shader *shader)
#define D3DSI_COISSUE
Definition: d3d8types.h:371
GLsizei const GLfloat * value
Definition: glext.h:6069
BYTE usage_idx
static void write_constI(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
static void init_vs11_dx9_writer(struct bc_writer *writer)
static const struct instr_handler_table vs_1_x_handlers[]
#define T2_REG
#define D3DSP_WRITEMASK_3
Definition: d3d8types.h:377
static int instr_def(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps)
Definition: shader.c:2275
#define ERR(fmt,...)
Definition: debug.h:109
static void ps_2_0_dstreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer, DWORD shift, DWORD mod)
#define BWRITERVS_NOSWIZZLE
static const struct bytecode_backend ps_1_4_backend
#define BWRITERVS_Y_Z
#define S_OK
Definition: intsafe.h:59
static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void ps_1_4_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static const struct bytecode_backend vs_3_backend
#define BWRITERVS_W_Z
static void init_ps14_dx9_writer(struct bc_writer *writer)
#define D3DSP_REGNUM_MASK
Definition: d3d9types.h:479
#define D3DVS_W_X
Definition: d3d8types.h:446
static const struct instr_handler_table vs_3_handlers[]
static void init_vs2x_dx9_writer(struct bc_writer *writer)
#define D3DVS_X_X
Definition: d3d8types.h:431
static void instr_ps_1_4_mov(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
static int reg
Definition: i386-dis.c:1275
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define INSTRARRAY_INITIAL_SIZE
#define BWRITERVS_Z_W
static HRESULT find_ps_builtin_semantics(struct bc_writer *This, const struct bwriter_shader *shader, DWORD texcoords)
#define D3DSP_TEXTURETYPE_MASK
Definition: d3d9types.h:467
static DWORD map_vs_output(struct bc_writer *This, DWORD regnum, DWORD mask, DWORD *has_components)
static DWORD d3d9_srcmod(DWORD bwriter_srcmod)
#define BWRITERSP_WRITEMASK_0
#define BWRITERVS_Y_Y
#define D3DSI_OPCODE_MASK
Definition: d3d8types.h:306
static DWORD d3dsp_register(D3DSHADER_PARAM_REGISTER_TYPE type, DWORD num)
static void vs_1_x_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
#define BWRITERPS_VERSION(major, minor)
static int instr_dcl(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps)
Definition: shader.c:2284
#define D3DSP_WRITEMASK_1
Definition: d3d8types.h:375
#define BWRITERVS_X_Z
#define BWRITERVS_Y_W
#define D3DSI_INSTLENGTH_SHIFT
Definition: d3d9types.h:354
#define D3DSP_REGTYPE_SHIFT2
Definition: d3d9types.h:506
static void vs_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
#define D3DSP_DCL_USAGEINDEX_MASK
Definition: d3d9types.h:464
#define T3_REG
#define BWRITERVS_VERSION(major, minor)
#define BWRITERVS_SWIZZLE_Y
GLuint64EXT * result
Definition: glext.h:11304
static const struct instr_handler_table ps_2_0_handlers[]
#define D3DVS_X_W
Definition: d3d8types.h:434
type_t * reg_type(type_t *type, const char *name, struct namespace *namespace, int t)
Definition: parser.tab.c:5992
#define BWRITERVS_X_W
const struct bytecode_backend * funcs
static void sm_1_x_opcode(struct bc_writer *This, const struct instruction *instr, DWORD token, struct bytecode_buffer *buffer)
static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
#define D3DSI_TEXLD_BIAS
Definition: d3d9types.h:455
static void instr_ps_1_0123_texld(struct bc_writer *This, const struct instruction *instr, struct bytecode_buffer *buffer)
#define BWRITERVS_SWIZZLE_W
char * src
Definition: disassembler.h:104
#define BWRITERVS_W_X
#define D3DSP_REGTYPE_MASK
Definition: d3d8types.h:395
static int mod
Definition: i386-dis.c:1273
static void vs_2_srcreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void ps_1_4_dstreg(struct bc_writer *This, const struct shader_reg *reg, struct bytecode_buffer *buffer, DWORD shift, DWORD mod)
static const struct bytecode_backend ps_2_x_backend