ReactOS 0.4.17-dev-966-gf06eace
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
29
30static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
31{
32 unsigned int max_capacity, new_capacity;
33 void *new_elements;
34
35 if (count <= *capacity)
36 return TRUE;
37
38 max_capacity = ~0u / size;
39 if (count > max_capacity)
40 return FALSE;
41
42 new_capacity = max(8, *capacity);
43 while (new_capacity < count && new_capacity <= max_capacity / 2)
44 new_capacity *= 2;
45 if (new_capacity < count)
46 new_capacity = count;
47
48 if (!(new_elements = realloc(*elements, new_capacity * size)))
49 {
50 ERR("Failed to allocate memory.\n");
51 return FALSE;
52 }
53
54 *elements = new_elements;
55 *capacity = new_capacity;
56 return TRUE;
57}
58
59/****************************************************************
60 * General assembler shader construction helper routines follow *
61 ****************************************************************/
62/* struct instruction *alloc_instr
63 *
64 * Allocates a new instruction structure with srcs registers
65 *
66 * Parameters:
67 * srcs: Number of source registers to allocate
68 *
69 * Returns:
70 * A pointer to the allocated instruction structure
71 * NULL in case of an allocation failure
72 */
73struct instruction *alloc_instr(unsigned int srcs) {
74 struct instruction *ret = calloc(1, sizeof(*ret));
75 if(!ret) {
76 ERR("Failed to allocate memory for an instruction structure\n");
77 return NULL;
78 }
79
80 if(srcs) {
81 ret->src = calloc(1, srcs * sizeof(*ret->src));
82 if(!ret->src) {
83 ERR("Failed to allocate memory for instruction registers\n");
84 free(ret);
85 return NULL;
86 }
87 ret->num_srcs = srcs;
88 }
89 return ret;
90}
91
92/* void add_instruction
93 *
94 * Adds a new instruction to the shader's instructions array and grows the instruction array
95 * if needed.
96 *
97 * The function does NOT copy the instruction structure. Make sure not to release the
98 * instruction or any of its substructures like registers.
99 *
100 * Parameters:
101 * shader: Shader to add the instruction to
102 * instr: Instruction to add to the shader
103 */
105 if(!shader) return FALSE;
106
107 if (!array_reserve((void **)&shader->instr, &shader->instr_alloc_size,
108 shader->num_instrs + 1, sizeof(*shader->instr)))
109 return FALSE;
110
111 shader->instr[shader->num_instrs] = instr;
112 shader->num_instrs++;
113 return TRUE;
114}
115
116BOOL add_constF(struct bwriter_shader *shader, uint32_t reg, float x, float y, float z, float w)
117{
118 struct constant *newconst;
119
120 if (shader->num_cf)
121 {
122 struct constant **newarray;
123 newarray = realloc(shader->constF, sizeof(*shader->constF) * (shader->num_cf + 1));
124 if (!newarray)
125 {
126 ERR("Failed to grow the constants array\n");
127 return FALSE;
128 }
129 shader->constF = newarray;
130 }
131 else
132 {
133 shader->constF = calloc(1, sizeof(*shader->constF));
134 if (!shader->constF)
135 {
136 ERR("Failed to allocate the constants array\n");
137 return FALSE;
138 }
139 }
140
141 newconst = calloc(1, sizeof(*newconst));
142 if (!newconst)
143 {
144 ERR("Failed to allocate a new constant\n");
145 return FALSE;
146 }
147 newconst->regnum = reg;
148 newconst->value[0].f = x;
149 newconst->value[1].f = y;
150 newconst->value[2].f = z;
151 newconst->value[3].f = w;
152 shader->constF[shader->num_cf] = newconst;
153
154 shader->num_cf++;
155 return TRUE;
156}
157
158BOOL add_constI(struct bwriter_shader *shader, uint32_t reg, int x, int y, int z, int w)
159{
160 struct constant *newconst;
161
162 if (shader->num_ci)
163 {
164 struct constant **newarray;
165 newarray = realloc(shader->constI, sizeof(*shader->constI) * (shader->num_ci + 1));
166 if (!newarray)
167 {
168 ERR("Failed to grow the constants array\n");
169 return FALSE;
170 }
171 shader->constI = newarray;
172 }
173 else
174 {
175 shader->constI = calloc(1, sizeof(*shader->constI));
176 if (!shader->constI)
177 {
178 ERR("Failed to allocate the constants array\n");
179 return FALSE;
180 }
181 }
182
183 newconst = calloc(1, sizeof(*newconst));
184 if (!newconst)
185 {
186 ERR("Failed to allocate a new constant\n");
187 return FALSE;
188 }
189 newconst->regnum = reg;
190 newconst->value[0].i = x;
191 newconst->value[1].i = y;
192 newconst->value[2].i = z;
193 newconst->value[3].i = w;
194 shader->constI[shader->num_ci] = newconst;
195
196 shader->num_ci++;
197 return TRUE;
198}
199
201{
202 struct constant *newconst;
203
204 if (shader->num_cb)
205 {
206 struct constant **newarray;
207 newarray = realloc(shader->constB, sizeof(*shader->constB) * (shader->num_cb + 1));
208 if (!newarray)
209 {
210 ERR("Failed to grow the constants array\n");
211 return FALSE;
212 }
213 shader->constB = newarray;
214 }
215 else
216 {
217 shader->constB = calloc(1, sizeof(*shader->constB));
218 if (!shader->constB)
219 {
220 ERR("Failed to allocate the constants array\n");
221 return FALSE;
222 }
223 }
224
225 newconst = calloc(1, sizeof(*newconst));
226 if (!newconst)
227 {
228 ERR("Failed to allocate a new constant\n");
229 return FALSE;
230 }
231 newconst->regnum = reg;
232 newconst->value[0].b = x;
233 shader->constB[shader->num_cb] = newconst;
234
235 shader->num_cb++;
236 return TRUE;
237}
238
240 uint32_t mod, BOOL output, uint32_t regnum, uint32_t writemask, BOOL builtin)
241{
242 struct declaration **decl;
243 unsigned int i, *num;
244
245 if (!shader)
246 return FALSE;
247
248 if (output)
249 {
250 num = &shader->num_outputs;
251 decl = &shader->outputs;
252 }
253 else
254 {
255 num = &shader->num_inputs;
256 decl = &shader->inputs;
257 }
258
259 if (*num == 0)
260 {
261 *decl = calloc(1, sizeof(**decl));
262 if (!*decl)
263 {
264 ERR("Error allocating declarations array\n");
265 return FALSE;
266 }
267 }
268 else
269 {
270 struct declaration *newdecl;
271
272 for (i = 0; i < *num; i++)
273 {
274 if ((*decl)[i].regnum == regnum && ((*decl)[i].writemask & writemask))
275 WARN("Declaration of register %u already exists, writemask match 0x%x\n",
276 regnum, (*decl)[i].writemask & writemask);
277 }
278
279 newdecl = realloc(*decl, sizeof(**decl) * ((*num) + 1));
280 if (!newdecl)
281 {
282 ERR("Error reallocating declarations array\n");
283 return FALSE;
284 }
285 *decl = newdecl;
286 }
287 (*decl)[*num].usage = usage;
288 (*decl)[*num].usage_idx = usage_idx;
289 (*decl)[*num].regnum = regnum;
290 (*decl)[*num].mod = mod;
291 (*decl)[*num].writemask = writemask;
292 (*decl)[*num].builtin = builtin;
293 (*num)++;
294
295 return TRUE;
296}
297
299 unsigned int i;
300
301 if (!shader)
302 return FALSE;
303
304 if (shader->num_samplers == 0)
305 {
306 shader->samplers = calloc(1, sizeof(*shader->samplers));
307 if (!shader->samplers)
308 {
309 ERR("Error allocating samplers array\n");
310 return FALSE;
311 }
312 }
313 else
314 {
315 struct samplerdecl *newarray;
316
317 for (i = 0; i < shader->num_samplers; i++)
318 {
319 if (shader->samplers[i].regnum == regnum)
320 {
321 WARN("Sampler %u already declared\n", regnum);
322 /* This is not an error as far as the assembler is concerned.
323 * Direct3D might refuse to load the compiled shader though */
324 }
325 }
326
327 newarray = realloc(shader->samplers, sizeof(*shader->samplers) * (shader->num_samplers + 1));
328 if (!newarray)
329 {
330 ERR("Error reallocating samplers array\n");
331 return FALSE;
332 }
333 shader->samplers = newarray;
334 }
335
336 shader->samplers[shader->num_samplers].type = samptype;
337 shader->samplers[shader->num_samplers].mod = mod;
338 shader->samplers[shader->num_samplers].regnum = regnum;
339 shader->num_samplers++;
340 return TRUE;
341}
342
344{
346 unsigned int size, alloc_size;
348};
349
350struct bc_writer;
351
352typedef void (*instr_writer)(struct bc_writer *writer, const struct instruction *instr,
353 struct bytecode_buffer *buffer);
354
356{
357 void (*header)(struct bc_writer *writer, const struct bwriter_shader *shader,
358 struct bytecode_buffer *buffer);
359 void (*end)(struct bc_writer *writer, const struct bwriter_shader *shader,
360 struct bytecode_buffer *buffer);
361 void (*srcreg)(struct bc_writer *writer, const struct shader_reg *reg,
362 struct bytecode_buffer *buffer);
363 void (*dstreg)(struct bc_writer *writer, const struct shader_reg *reg,
365 void (*opcode)(struct bc_writer *writer, const struct instruction *instr,
367
369 {
373};
374
376{
377 const struct bytecode_backend *funcs;
378 const struct bwriter_shader *shader;
379
381
382 /* Vertex shader varying mapping. */
384
385 /* Pixel shader varying mapping. */
387};
388
389
390/* shader bytecode buffer manipulation functions.
391 * allocate_buffer creates a new buffer structure, put_u32 adds a new
392 * uint32_t to the buffer. In the rare case of a memory allocation failure
393 * when trying to grow the buffer a flag is set in the buffer to mark it
394 * invalid. This avoids return value checking and passing in many places
395 */
396static struct bytecode_buffer *allocate_buffer(void) {
397 struct bytecode_buffer *ret;
398
399 ret = calloc(1, sizeof(*ret));
400 if(!ret) return NULL;
401 ret->state = S_OK;
402 return ret;
403}
404
406{
407 if (FAILED(buffer->state))
408 return;
409
410 if (!array_reserve((void **)&buffer->data, &buffer->alloc_size, buffer->size + 1, sizeof(*buffer->data)))
411 {
412 buffer->state = E_OUTOFMEMORY;
413 return;
414 }
415
416 buffer->data[buffer->size++] = value;
417}
418
419/* bwriter -> d3d9 conversion functions. */
420
422{
423 switch (shader->type)
424 {
425 case ST_VERTEX:
426 return D3DVS_VERSION(shader->major_version, shader->minor_version);
427 case ST_PIXEL:
428 return D3DPS_VERSION(shader->major_version, shader->minor_version);
429 default:
430 ERR("Invalid shader type %#x.\n", shader->type);
431 return 0;
432 }
433}
434
435static uint32_t d3d9_swizzle(uint32_t bwriter_swizzle)
436{
437 uint32_t ret = 0;
438
439 if ((bwriter_swizzle & BWRITERVS_X_X) == BWRITERVS_X_X) ret |= D3DVS_X_X;
440 if ((bwriter_swizzle & BWRITERVS_X_Y) == BWRITERVS_X_Y) ret |= D3DVS_X_Y;
441 if ((bwriter_swizzle & BWRITERVS_X_Z) == BWRITERVS_X_Z) ret |= D3DVS_X_Z;
442 if ((bwriter_swizzle & BWRITERVS_X_W) == BWRITERVS_X_W) ret |= D3DVS_X_W;
443
444 if ((bwriter_swizzle & BWRITERVS_Y_X) == BWRITERVS_Y_X) ret |= D3DVS_Y_X;
445 if ((bwriter_swizzle & BWRITERVS_Y_Y) == BWRITERVS_Y_Y) ret |= D3DVS_Y_Y;
446 if ((bwriter_swizzle & BWRITERVS_Y_Z) == BWRITERVS_Y_Z) ret |= D3DVS_Y_Z;
447 if ((bwriter_swizzle & BWRITERVS_Y_W) == BWRITERVS_Y_W) ret |= D3DVS_Y_W;
448
449 if ((bwriter_swizzle & BWRITERVS_Z_X) == BWRITERVS_Z_X) ret |= D3DVS_Z_X;
450 if ((bwriter_swizzle & BWRITERVS_Z_Y) == BWRITERVS_Z_Y) ret |= D3DVS_Z_Y;
451 if ((bwriter_swizzle & BWRITERVS_Z_Z) == BWRITERVS_Z_Z) ret |= D3DVS_Z_Z;
452 if ((bwriter_swizzle & BWRITERVS_Z_W) == BWRITERVS_Z_W) ret |= D3DVS_Z_W;
453
454 if ((bwriter_swizzle & BWRITERVS_W_X) == BWRITERVS_W_X) ret |= D3DVS_W_X;
455 if ((bwriter_swizzle & BWRITERVS_W_Y) == BWRITERVS_W_Y) ret |= D3DVS_W_Y;
456 if ((bwriter_swizzle & BWRITERVS_W_Z) == BWRITERVS_W_Z) ret |= D3DVS_W_Z;
457 if ((bwriter_swizzle & BWRITERVS_W_W) == BWRITERVS_W_W) ret |= D3DVS_W_W;
458
459 return ret;
460}
461
462static uint32_t d3d9_writemask(uint32_t bwriter_writemask)
463{
464 uint32_t ret = 0;
465
466 if (bwriter_writemask & BWRITERSP_WRITEMASK_0) ret |= D3DSP_WRITEMASK_0;
467 if (bwriter_writemask & BWRITERSP_WRITEMASK_1) ret |= D3DSP_WRITEMASK_1;
468 if (bwriter_writemask & BWRITERSP_WRITEMASK_2) ret |= D3DSP_WRITEMASK_2;
469 if (bwriter_writemask & BWRITERSP_WRITEMASK_3) ret |= D3DSP_WRITEMASK_3;
470
471 return ret;
472}
473
474static uint32_t d3d9_srcmod(uint32_t bwriter_srcmod)
475{
476 switch (bwriter_srcmod)
477 {
478 case BWRITERSPSM_NONE: return D3DSPSM_NONE;
479 case BWRITERSPSM_NEG: return D3DSPSM_NEG;
480 case BWRITERSPSM_BIAS: return D3DSPSM_BIAS;
482 case BWRITERSPSM_SIGN: return D3DSPSM_SIGN;
484 case BWRITERSPSM_COMP: return D3DSPSM_COMP;
485 case BWRITERSPSM_X2: return D3DSPSM_X2;
486 case BWRITERSPSM_X2NEG: return D3DSPSM_X2NEG;
487 case BWRITERSPSM_DZ: return D3DSPSM_DZ;
488 case BWRITERSPSM_DW: return D3DSPSM_DW;
489 case BWRITERSPSM_ABS: return D3DSPSM_ABS;
491 case BWRITERSPSM_NOT: return D3DSPSM_NOT;
492 default:
493 FIXME("Unhandled BWRITERSPSM token %#x.\n", bwriter_srcmod);
494 return 0;
495 }
496}
497
498static uint32_t d3d9_dstmod(uint32_t bwriter_mod)
499{
500 uint32_t ret = 0;
501
502 if (bwriter_mod & BWRITERSPDM_SATURATE) ret |= D3DSPDM_SATURATE;
505
506 return ret;
507}
508
509static uint32_t d3d9_comparetype(uint32_t asmshader_comparetype)
510{
511 switch (asmshader_comparetype)
512 {
513 case BWRITER_COMPARISON_GT: return D3DSPC_GT;
514 case BWRITER_COMPARISON_EQ: return D3DSPC_EQ;
515 case BWRITER_COMPARISON_GE: return D3DSPC_GE;
516 case BWRITER_COMPARISON_LT: return D3DSPC_LT;
517 case BWRITER_COMPARISON_NE: return D3DSPC_NE;
518 case BWRITER_COMPARISON_LE: return D3DSPC_LE;
519 default:
520 FIXME("Unexpected BWRITER_COMPARISON type %#x.\n", asmshader_comparetype);
521 return 0;
522 }
523}
524
525static uint32_t d3d9_sampler(uint32_t bwriter_sampler)
526{
527 if (bwriter_sampler == BWRITERSTT_UNKNOWN) return D3DSTT_UNKNOWN;
528 if (bwriter_sampler == BWRITERSTT_1D) return D3DSTT_1D;
529 if (bwriter_sampler == BWRITERSTT_2D) return D3DSTT_2D;
530 if (bwriter_sampler == BWRITERSTT_CUBE) return D3DSTT_CUBE;
531 if (bwriter_sampler == BWRITERSTT_VOLUME) return D3DSTT_VOLUME;
532 FIXME("Unexpected BWRITERSAMPLER_TEXTURE_TYPE type %#x.\n", bwriter_sampler);
533
534 return 0;
535}
536
537static uint32_t d3d9_register(uint32_t bwriter_register)
538{
539 if (bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
540 if (bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;
541 if (bwriter_register == BWRITERSPR_CONST) return D3DSPR_CONST;
542 if (bwriter_register == BWRITERSPR_ADDR) return D3DSPR_ADDR;
543 if (bwriter_register == BWRITERSPR_TEXTURE) return D3DSPR_TEXTURE;
544 if (bwriter_register == BWRITERSPR_RASTOUT) return D3DSPR_RASTOUT;
545 if (bwriter_register == BWRITERSPR_ATTROUT) return D3DSPR_ATTROUT;
546 if (bwriter_register == BWRITERSPR_TEXCRDOUT) return D3DSPR_TEXCRDOUT;
547 if (bwriter_register == BWRITERSPR_OUTPUT) return D3DSPR_OUTPUT;
548 if (bwriter_register == BWRITERSPR_CONSTINT) return D3DSPR_CONSTINT;
549 if (bwriter_register == BWRITERSPR_COLOROUT) return D3DSPR_COLOROUT;
550 if (bwriter_register == BWRITERSPR_DEPTHOUT) return D3DSPR_DEPTHOUT;
551 if (bwriter_register == BWRITERSPR_SAMPLER) return D3DSPR_SAMPLER;
552 if (bwriter_register == BWRITERSPR_CONSTBOOL) return D3DSPR_CONSTBOOL;
553 if (bwriter_register == BWRITERSPR_LOOP) return D3DSPR_LOOP;
554 if (bwriter_register == BWRITERSPR_MISCTYPE) return D3DSPR_MISCTYPE;
555 if (bwriter_register == BWRITERSPR_LABEL) return D3DSPR_LABEL;
556 if (bwriter_register == BWRITERSPR_PREDICATE) return D3DSPR_PREDICATE;
557
558 FIXME("Unexpected BWRITERSPR %#x.\n", bwriter_register);
559 return ~0U;
560}
561
562static uint32_t d3d9_opcode(uint32_t bwriter_opcode)
563{
564 switch (bwriter_opcode)
565 {
566 case BWRITERSIO_NOP: return D3DSIO_NOP;
567 case BWRITERSIO_MOV: return D3DSIO_MOV;
568 case BWRITERSIO_ADD: return D3DSIO_ADD;
569 case BWRITERSIO_SUB: return D3DSIO_SUB;
570 case BWRITERSIO_MAD: return D3DSIO_MAD;
571 case BWRITERSIO_MUL: return D3DSIO_MUL;
572 case BWRITERSIO_RCP: return D3DSIO_RCP;
573 case BWRITERSIO_RSQ: return D3DSIO_RSQ;
574 case BWRITERSIO_DP3: return D3DSIO_DP3;
575 case BWRITERSIO_DP4: return D3DSIO_DP4;
576 case BWRITERSIO_MIN: return D3DSIO_MIN;
577 case BWRITERSIO_MAX: return D3DSIO_MAX;
578 case BWRITERSIO_SLT: return D3DSIO_SLT;
579 case BWRITERSIO_SGE: return D3DSIO_SGE;
580 case BWRITERSIO_EXP: return D3DSIO_EXP;
581 case BWRITERSIO_LOG: return D3DSIO_LOG;
582 case BWRITERSIO_LIT: return D3DSIO_LIT;
583 case BWRITERSIO_DST: return D3DSIO_DST;
584 case BWRITERSIO_LRP: return D3DSIO_LRP;
585 case BWRITERSIO_FRC: return D3DSIO_FRC;
586 case BWRITERSIO_M4x4: return D3DSIO_M4x4;
587 case BWRITERSIO_M4x3: return D3DSIO_M4x3;
588 case BWRITERSIO_M3x4: return D3DSIO_M3x4;
589 case BWRITERSIO_M3x3: return D3DSIO_M3x3;
590 case BWRITERSIO_M3x2: return D3DSIO_M3x2;
591 case BWRITERSIO_CALL: return D3DSIO_CALL;
592 case BWRITERSIO_CALLNZ: return D3DSIO_CALLNZ;
593 case BWRITERSIO_LOOP: return D3DSIO_LOOP;
594 case BWRITERSIO_RET: return D3DSIO_RET;
596 case BWRITERSIO_LABEL: return D3DSIO_LABEL;
597 case BWRITERSIO_DCL: return D3DSIO_DCL;
598 case BWRITERSIO_POW: return D3DSIO_POW;
599 case BWRITERSIO_CRS: return D3DSIO_CRS;
600 case BWRITERSIO_SGN: return D3DSIO_SGN;
601 case BWRITERSIO_ABS: return D3DSIO_ABS;
602 case BWRITERSIO_NRM: return D3DSIO_NRM;
603 case BWRITERSIO_SINCOS: return D3DSIO_SINCOS;
604 case BWRITERSIO_REP: return D3DSIO_REP;
605 case BWRITERSIO_ENDREP: return D3DSIO_ENDREP;
606 case BWRITERSIO_IF: return D3DSIO_IF;
607 case BWRITERSIO_IFC: return D3DSIO_IFC;
608 case BWRITERSIO_ELSE: return D3DSIO_ELSE;
609 case BWRITERSIO_ENDIF: return D3DSIO_ENDIF;
610 case BWRITERSIO_BREAK: return D3DSIO_BREAK;
611 case BWRITERSIO_BREAKC: return D3DSIO_BREAKC;
612 case BWRITERSIO_MOVA: return D3DSIO_MOVA;
613 case BWRITERSIO_DEFB: return D3DSIO_DEFB;
614 case BWRITERSIO_DEFI: return D3DSIO_DEFI;
615
618 case BWRITERSIO_TEX: return D3DSIO_TEX;
619 case BWRITERSIO_TEXBEM: return D3DSIO_TEXBEM;
629 case BWRITERSIO_EXPP: return D3DSIO_EXPP;
630 case BWRITERSIO_LOGP: return D3DSIO_LOGP;
631 case BWRITERSIO_CND: return D3DSIO_CND;
632 case BWRITERSIO_DEF: return D3DSIO_DEF;
636 case BWRITERSIO_TEXDP3: return D3DSIO_TEXDP3;
639 case BWRITERSIO_CMP: return D3DSIO_CMP;
640 case BWRITERSIO_BEM: return D3DSIO_BEM;
641 case BWRITERSIO_DP2ADD: return D3DSIO_DP2ADD;
642 case BWRITERSIO_DSX: return D3DSIO_DSX;
643 case BWRITERSIO_DSY: return D3DSIO_DSY;
644 case BWRITERSIO_TEXLDD: return D3DSIO_TEXLDD;
645 case BWRITERSIO_SETP: return D3DSIO_SETP;
646 case BWRITERSIO_TEXLDL: return D3DSIO_TEXLDL;
647 case BWRITERSIO_BREAKP: return D3DSIO_BREAKP;
648
649 case BWRITERSIO_PHASE: return D3DSIO_PHASE;
651 case BWRITERSIO_END: return D3DSIO_END;
652
655
656 default:
657 FIXME("Unhandled BWRITERSIO token %#x.\n", bwriter_opcode);
658 return ~0U;
659 }
660}
661
663{
666 (num & D3DSP_REGNUM_MASK); /* No shift */
667}
668
669/******************************************************
670 * Implementation of the writer functions starts here *
671 ******************************************************/
672static void write_declarations(struct bc_writer *writer, struct bytecode_buffer *buffer,
673 const struct declaration *decls, unsigned int num, uint32_t type)
674{
675 uint32_t instr_dcl = D3DSIO_DCL;
677 unsigned int i;
678 struct shader_reg reg;
679
680 ZeroMemory(&reg, sizeof(reg));
681
682 if (writer->shader->major_version > 1)
683 instr_dcl |= 2 << D3DSI_INSTLENGTH_SHIFT;
684
685 for(i = 0; i < num; i++) {
686 if(decls[i].builtin) continue;
687
688 /* Write the DCL instruction */
689 put_u32(buffer, instr_dcl);
690
691 /* Write the usage and index */
692 token = (1u << 31); /* Bit 31 of non-instruction opcodes is 1 */
696
697 /* Write the dest register */
698 reg.type = type;
699 reg.regnum = decls[i].regnum;
700 reg.writemask = decls[i].writemask;
701 writer->funcs->dstreg(writer, &reg, buffer, 0, decls[i].mod);
702 }
703}
704
705static void write_const(struct constant **consts, int num, uint32_t opcode, uint32_t reg_type, struct bytecode_buffer *buffer, BOOL len)
706{
707 const uint32_t reg = (1u << 31) | d3dsp_register( reg_type, 0 ) | D3DSP_WRITEMASK_ALL;
708 uint32_t instr_def = opcode;
709 unsigned int i;
710
711 if(len) {
712 if(opcode == D3DSIO_DEFB)
713 instr_def |= 2 << D3DSI_INSTLENGTH_SHIFT;
714 else
715 instr_def |= 5 << D3DSI_INSTLENGTH_SHIFT;
716 }
717
718 for(i = 0; i < num; i++) {
719 /* Write the DEF instruction */
720 put_u32(buffer, instr_def);
721
722 put_u32(buffer, reg | (consts[i]->regnum & D3DSP_REGNUM_MASK));
723 put_u32(buffer, consts[i]->value[0].d);
724 if(opcode != D3DSIO_DEFB) {
725 put_u32(buffer, consts[i]->value[1].d);
726 put_u32(buffer, consts[i]->value[2].d);
727 put_u32(buffer, consts[i]->value[3].d);
728 }
729 }
730}
731
732static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
734}
735
736/* This function looks for VS 1/2 registers mapping to VS 3 output registers */
738{
740 unsigned int i;
741
742 for (i = 0; i < shader->num_outputs; i++)
743 {
744 if (!shader->outputs[i].builtin)
745 continue;
746
747 usage = shader->outputs[i].usage;
748 usage_idx = shader->outputs[i].usage_idx;
749 writemask = shader->outputs[i].writemask;
750 regnum = shader->outputs[i].regnum;
751
752 switch (usage)
753 {
756 if (usage_idx > 0)
757 {
758 WARN("dcl_position%u not supported in sm 1/2 shaders.\n", usage_idx);
759 return E_INVALIDARG;
760 }
761 TRACE("o%u is oPos.\n", regnum);
762 writer->oPos_regnum = regnum;
763 break;
764
766 if (usage_idx > 1)
767 {
768 WARN("dcl_color%u not supported in sm 1/2 shaders.\n", usage_idx);
769 return E_INVALIDARG;
770 }
772 {
773 WARN("Only WRITEMASK_ALL is supported on color in sm 1/2\n");
774 return E_INVALIDARG;
775 }
776 TRACE("o%u is oD%u.\n", regnum, usage_idx);
777 writer->oD_regnum[usage_idx] = regnum;
778 break;
779
781 if (usage_idx >= 8)
782 {
783 WARN("dcl_color%u not supported in sm 1/2 shaders.\n", usage_idx);
784 return E_INVALIDARG;
785 }
790 {
791 WARN("Partial writemasks not supported on texture coordinates in sm 1 and 2\n");
792 return E_INVALIDARG;
793 }
794 TRACE("o%u is oT%u.\n", regnum, usage_idx);
795 writer->oT_regnum[usage_idx] = regnum;
796 break;
797
799 if (usage_idx > 0)
800 {
801 WARN("dcl_psize%u not supported in sm 1/2 shaders.\n", usage_idx);
802 return E_INVALIDARG;
803 }
804 TRACE("o%u writemask 0x%08x is oPts.\n", regnum, writemask);
805 writer->oPts_regnum = regnum;
806 writer->oPts_mask = writemask;
807 break;
808
810 if (usage_idx > 0)
811 {
812 WARN("dcl_fog%u not supported in sm 1 shaders.\n", usage_idx);
813 return E_INVALIDARG;
814 }
817 {
818 WARN("Unsupported fog writemask\n");
819 return E_INVALIDARG;
820 }
821 TRACE("o%u writemask 0x%08x is oFog.\n", regnum, writemask);
822 writer->oFog_regnum = regnum;
823 writer->oFog_mask = writemask;
824 break;
825
826 default:
827 WARN("Varying type %u is not supported in shader model 1.x.\n", usage);
828 return E_INVALIDARG;
829 }
830 }
831
832 return S_OK;
833}
834
835static void vs_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
836 HRESULT hr;
837
838 if(shader->num_ci || shader->num_cb) {
839 WARN("Int and bool constants are not supported in shader model 1 shaders\n");
840 WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
841 This->state = E_INVALIDARG;
842 return;
843 }
844
846 if(FAILED(hr)) {
847 This->state = hr;
848 return;
849 }
850
853}
854
856 uint32_t texcoords)
857{
859 unsigned int i;
860
861 writer->v_regnum[0] = -1;
862 writer->v_regnum[1] = -1;
863 for (i = 0; i < 8; i++)
864 writer->t_regnum[i] = -1;
865
866 for (i = 0; i < shader->num_inputs; i++)
867 {
868 if (!shader->inputs[i].builtin)
869 continue;
870
871 usage = shader->inputs[i].usage;
872 usage_idx = shader->inputs[i].usage_idx;
873 writemask = shader->inputs[i].writemask;
874 regnum = shader->inputs[i].regnum;
875
876 switch (usage)
877 {
879 if (usage_idx > 1)
880 {
881 WARN("dcl_color%u not supported in sm 1 shaders\n", usage_idx);
882 return E_INVALIDARG;
883 }
885 {
886 WARN("Only WRITEMASK_ALL is supported on color in sm 1\n");
887 return E_INVALIDARG;
888 }
889 TRACE("v%u is v%u\n", regnum, usage_idx);
890 writer->v_regnum[usage_idx] = regnum;
891 break;
892
894 if (usage_idx > texcoords)
895 {
896 WARN("dcl_texcoord%u not supported in this shader version\n", usage_idx);
897 return E_INVALIDARG;
898 }
903 WARN("Partial writemasks not supported on texture coordinates in sm 1 and 2\n");
904 else
906 TRACE("v%u is t%u\n", regnum, usage_idx);
907 writer->t_regnum[usage_idx] = regnum;
908 break;
909
910 default:
911 WARN("Varying type %u is not supported in shader model 1.x\n", usage);
912 return E_INVALIDARG;
913 }
914 }
915
916 return S_OK;
917}
918
919static void ps_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
920 HRESULT hr;
921
922 /* First check the constants and varyings, and complain if unsupported things are used */
923 if(shader->num_ci || shader->num_cb) {
924 WARN("Int and bool constants are not supported in shader model 1 shaders\n");
925 WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
926 This->state = E_INVALIDARG;
927 return;
928 }
929
931 if(FAILED(hr)) {
932 This->state = hr;
933 return;
934 }
935
937}
938
939static void ps_1_4_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
940 HRESULT hr;
941
942 /* First check the constants and varyings, and complain if unsupported things are used */
943 if(shader->num_ci || shader->num_cb) {
944 WARN("Int and bool constants are not supported in shader model 1 shaders\n");
945 WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
946 This->state = E_INVALIDARG;
947 return;
948 }
950 if(FAILED(hr)) {
951 This->state = hr;
952 return;
953 }
954
956}
957
958static void end(struct bc_writer *writer, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
959{
961}
962
963static uint32_t map_vs_output(struct bc_writer *writer, uint32_t regnum, uint32_t mask, BOOL *has_components)
964{
965 unsigned int i;
966
967 *has_components = TRUE;
968 if (regnum == writer->oPos_regnum)
969 {
971 }
972 if (regnum == writer->oFog_regnum && mask == writer->oFog_mask)
973 {
974 *has_components = FALSE;
976 }
977 if (regnum == writer->oPts_regnum && mask == writer->oPts_mask)
978 {
979 *has_components = FALSE;
981 }
982 for (i = 0; i < 2; i++)
983 {
984 if (regnum == writer->oD_regnum[i])
986 }
987 for (i = 0; i < 8; i++)
988 {
989 if (regnum == writer->oT_regnum[i])
991 }
992
993 /* The varying must be undeclared - if an unsupported varying was declared,
994 * the vs_find_builtin_varyings function would have caught it and this code
995 * would not run */
996 WARN("Undeclared varying %u.\n", regnum);
997 writer->state = E_INVALIDARG;
998 return -1;
999}
1000
1001static void vs_12_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer,
1003{
1004 uint32_t token = (1u << 31); /* Bit 31 of registers is 1 */
1005 BOOL has_wmask;
1006
1007 if (reg->rel_reg)
1008 {
1009 WARN("Relative addressing not supported for destination registers\n");
1010 writer->state = E_INVALIDARG;
1011 return;
1012 }
1013
1014 switch (reg->type)
1015 {
1016 case BWRITERSPR_OUTPUT:
1017 token |= map_vs_output(writer, reg->regnum, reg->writemask, &has_wmask);
1018 break;
1019
1020 case BWRITERSPR_RASTOUT:
1021 case BWRITERSPR_ATTROUT:
1022 /* These registers are mapped to input and output regs. They can be encoded in the bytecode,
1023 * but are unexpected. If we hit this path it might be due to an error.
1024 */
1025 FIXME("Unexpected register type %u.\n", reg->type);
1026 /* drop through */
1027 case BWRITERSPR_INPUT:
1028 case BWRITERSPR_TEMP:
1029 case BWRITERSPR_CONST:
1030 token |= d3dsp_register( reg->type, reg->regnum );
1031 has_wmask = TRUE;
1032 break;
1033
1034 case BWRITERSPR_ADDR:
1035 if (reg->regnum != 0)
1036 {
1037 WARN("Only a0 exists\n");
1038 writer->state = E_INVALIDARG;
1039 return;
1040 }
1042 has_wmask = TRUE;
1043 break;
1044
1046 if (writer->shader->major_version != 2 || writer->shader->minor_version != 1)
1047 {
1048 WARN("Predicate register is allowed only in vs_2_x\n");
1049 writer->state = E_INVALIDARG;
1050 return;
1051 }
1052 if (reg->regnum != 0)
1053 {
1054 WARN("Only predicate register p0 exists\n");
1055 writer->state = E_INVALIDARG;
1056 return;
1057 }
1059 has_wmask = TRUE;
1060 break;
1061
1062 default:
1063 WARN("Invalid register type for 1.x-2.x vertex shader\n");
1064 writer->state = E_INVALIDARG;
1065 return;
1066 }
1067
1068 /* strictly speaking there are no modifiers in vs_2_0 and vs_1_x, but they can be written
1069 * into the bytecode and since the compiler doesn't do such checks write them
1070 * (the checks are done by the undocumented shader validator)
1071 */
1073 token |= d3d9_dstmod(mod);
1074
1075 if (has_wmask)
1076 token |= d3d9_writemask(reg->writemask);
1078}
1079
1080static void vs_1_x_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
1081{
1082 uint32_t token = (1u << 31); /* Bit 31 of registers is 1 */
1084 BOOL has_swizzle;
1085
1086 switch (reg->type)
1087 {
1088 case BWRITERSPR_OUTPUT:
1089 /* Map the swizzle to a writemask, the format expected by
1090 * map_vs_output */
1091 switch (reg->swizzle)
1092 {
1095 break;
1098 break;
1101 break;
1104 break;
1105 default:
1106 component = 0;
1107 }
1108 token |= map_vs_output(writer, reg->regnum, component, &has_swizzle);
1109 break;
1110
1111 case BWRITERSPR_RASTOUT:
1112 case BWRITERSPR_ATTROUT:
1113 /* These registers are mapped to input and output regs. They can
1114 * be encoded in the bytecode, but are unexpected. If we hit this
1115 * path it might be due to an error. */
1116 FIXME("Unexpected register type %u.\n", reg->type);
1117 /* drop through */
1118 case BWRITERSPR_INPUT:
1119 case BWRITERSPR_TEMP:
1120 case BWRITERSPR_CONST:
1121 case BWRITERSPR_ADDR:
1122 token |= d3dsp_register(reg->type, reg->regnum);
1123 if (reg->rel_reg)
1124 {
1125 if (reg->rel_reg->type != BWRITERSPR_ADDR || reg->rel_reg->regnum != 0
1126 || reg->rel_reg->swizzle != BWRITERVS_SWIZZLE_X)
1127 {
1128 WARN("Relative addressing in vs_1_x is only allowed with a0.x\n");
1129 writer->state = E_INVALIDARG;
1130 return;
1131 }
1133 }
1134 break;
1135
1136 default:
1137 WARN("Invalid register type for 1.x vshader\n");
1138 writer->state = E_INVALIDARG;
1139 return;
1140 }
1141
1142 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1143
1144 token |= d3d9_srcmod(reg->srcmod);
1146}
1147
1148static void write_srcregs(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
1149{
1150 unsigned int i;
1151
1152 if (instr->has_predicate)
1153 writer->funcs->srcreg(writer, &instr->predicate, buffer);
1154
1155 for (i = 0; i < instr->num_srcs; ++i)
1156 writer->funcs->srcreg(writer, &instr->src[i], buffer);
1157}
1158
1159static uint32_t map_ps13_temp(struct bc_writer *writer, const struct shader_reg *reg)
1160{
1161 if (reg->regnum == T0_REG)
1162 return d3dsp_register(D3DSPR_TEXTURE, 0);
1163 if (reg->regnum == T1_REG)
1164 return d3dsp_register(D3DSPR_TEXTURE, 1);
1165 if(reg->regnum == T2_REG)
1166 return d3dsp_register(D3DSPR_TEXTURE, 2);
1167 if (reg->regnum == T3_REG)
1168 return d3dsp_register(D3DSPR_TEXTURE, 3);
1169 return d3dsp_register(D3DSPR_TEMP, reg->regnum);
1170}
1171
1172static uint32_t map_ps_input(struct bc_writer *writer, const struct shader_reg *reg)
1173{
1174 unsigned int i;
1175
1176 /* Map color interpolators */
1177 for (i = 0; i < ARRAY_SIZE(writer->v_regnum); ++i)
1178 {
1179 if (reg->regnum == writer->v_regnum[i])
1180 return d3dsp_register(D3DSPR_INPUT, i);
1181 }
1182 for (i = 0; i < ARRAY_SIZE(writer->t_regnum); ++i)
1183 {
1184 if(reg->regnum == writer->t_regnum[i])
1186 }
1187
1188 WARN("Invalid ps 1/2 varying\n");
1189 writer->state = E_INVALIDARG;
1190 return 0;
1191}
1192
1193static void ps_1_0123_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
1194{
1195 uint32_t token = 1u << 31;
1196
1197 if (reg->rel_reg)
1198 {
1199 WARN("Relative addressing not supported in <= ps_3_0\n");
1200 writer->state = E_INVALIDARG;
1201 return;
1202 }
1203
1204 switch (reg->type)
1205 {
1206 case BWRITERSPR_INPUT:
1207 token |= map_ps_input(writer, reg);
1208 break;
1209
1210 /* Take care about the texture temporaries. There's a problem: They aren't
1211 * declared anywhere, so we can only hardcode the values that are used
1212 * to map ps_1_3 shaders to the common shader structure
1213 */
1214 case BWRITERSPR_TEMP:
1215 token |= map_ps13_temp(writer, reg);
1216 break;
1217
1218 case BWRITERSPR_CONST: /* Can be mapped 1:1 */
1219 token |= d3dsp_register( reg->type, reg->regnum );
1220 break;
1221
1222 default:
1223 WARN("Invalid register type for <= ps_1_3 shader\n");
1224 writer->state = E_INVALIDARG;
1225 return;
1226 }
1227
1228 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1229
1230 if(reg->srcmod == BWRITERSPSM_DZ || reg->srcmod == BWRITERSPSM_DW
1231 || reg->srcmod == BWRITERSPSM_ABS || reg->srcmod == BWRITERSPSM_ABSNEG
1232 || reg->srcmod == BWRITERSPSM_NOT)
1233 {
1234 WARN("Invalid source modifier %u for <= ps_1_3\n", reg->srcmod);
1235 writer->state = E_INVALIDARG;
1236 return;
1237 }
1238 token |= d3d9_srcmod(reg->srcmod);
1240}
1241
1242static void ps_1_0123_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer,
1244{
1245 uint32_t token = (1u << 31); /* Bit 31 of registers is 1 */
1246
1247 if (reg->rel_reg)
1248 {
1249 WARN("Relative addressing not supported for destination registers\n");
1250 writer->state = E_INVALIDARG;
1251 return;
1252 }
1253
1254 switch (reg->type)
1255 {
1256 case BWRITERSPR_TEMP:
1257 token |= map_ps13_temp(writer, reg);
1258 break;
1259
1260 /* texkill uses the input register as a destination parameter */
1261 case BWRITERSPR_INPUT:
1262 token |= map_ps_input(writer, reg);
1263 break;
1264
1265 default:
1266 WARN("Invalid dest register type for 1.x pshader\n");
1267 writer->state = E_INVALIDARG;
1268 return;
1269 }
1270
1272 token |= d3d9_dstmod(mod);
1273
1274 token |= d3d9_writemask(reg->writemask);
1276}
1277
1278/* The length of an instruction consists of the destination register (if any),
1279 * the number of source registers, the number of address registers used for
1280 * indirect addressing, and optionally the predicate register */
1281static unsigned int instrlen(const struct instruction *instr, unsigned int srcs, unsigned int dsts)
1282{
1283 unsigned int ret = srcs + dsts + (instr->has_predicate ? 1 : 0);
1284 unsigned int i;
1285
1286 if (dsts && instr->dst.rel_reg)
1287 ++ret;
1288 for (i = 0; i < srcs; ++i)
1289 if (instr->src[i].rel_reg)
1290 ++ret;
1291 return ret;
1292}
1293
1294static void sm_1_x_opcode(struct bc_writer *writer, const struct instruction *instr, uint32_t token,
1295 struct bytecode_buffer *buffer)
1296{
1297 /* Instruction length isn't encoded in sm_1_x. */
1298 if (instr->coissue)
1301}
1302
1303static void instr_handler(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
1304{
1305 uint32_t token = d3d9_opcode(instr->opcode);
1306
1307 writer->funcs->opcode(writer, instr, token, buffer);
1308 if (instr->has_dst)
1309 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1310 write_srcregs(writer, instr, buffer);
1311}
1312
1313static const struct instr_handler_table vs_1_x_handlers[] = {
1340
1341 {BWRITERSIO_END, NULL}, /* Sentinel value, it signals
1342 the end of the list */
1343};
1344
1345static const struct bytecode_backend vs_1_x_backend = {
1347 end,
1352};
1353
1354static void instr_ps_1_0123_texld(struct bc_writer *writer, const struct instruction *instr,
1355 struct bytecode_buffer *buffer)
1356{
1357 struct shader_reg reg;
1358 uint32_t swizzlemask;
1359 uint32_t idx;
1360
1361 if (instr->src[1].type != BWRITERSPR_SAMPLER || instr->src[1].regnum > 3)
1362 {
1363 WARN("Unsupported sampler type %u regnum %u.\n", instr->src[1].type, instr->src[1].regnum);
1364 writer->state = E_INVALIDARG;
1365 return;
1366 }
1367 else if (instr->dst.type != BWRITERSPR_TEMP)
1368 {
1369 WARN("Can only sample into a temp register\n");
1370 writer->state = E_INVALIDARG;
1371 return;
1372 }
1373
1374 idx = instr->src[1].regnum;
1375 if ((idx == 0 && instr->dst.regnum != T0_REG) || (idx == 1 && instr->dst.regnum != T1_REG)
1376 || (idx == 2 && instr->dst.regnum != T2_REG) || (idx == 3 && instr->dst.regnum != T3_REG))
1377 {
1378 WARN("Sampling from sampler s%u to register r%u is not possible in ps_1_x\n", idx, instr->dst.regnum);
1379 writer->state = E_INVALIDARG;
1380 return;
1381 }
1382 if (instr->src[0].type == BWRITERSPR_INPUT)
1383 {
1384 /* A simple non-dependent read tex instruction */
1385 if (instr->src[0].regnum != writer->t_regnum[idx])
1386 {
1387 WARN("Cannot sample from s%u with texture address data from interpolator %u\n", idx, instr->src[0].regnum);
1388 writer->state = E_INVALIDARG;
1389 return;
1390 }
1391 writer->funcs->opcode(writer, instr, D3DSIO_TEX & D3DSI_OPCODE_MASK, buffer);
1392
1393 /* map the temp dstreg to the ps_1_3 texture temporary register */
1394 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1395 }
1396 else if (instr->src[0].type == BWRITERSPR_TEMP)
1397 {
1398 swizzlemask = 3 | (3 << 2) | (3 << 4);
1399 if ((instr->src[0].swizzle & swizzlemask) == (BWRITERVS_X_X | BWRITERVS_Y_Y | BWRITERVS_Z_Z))
1400 {
1401 TRACE("writing texreg2rgb\n");
1402 writer->funcs->opcode(writer, instr, D3DSIO_TEXREG2RGB & D3DSI_OPCODE_MASK, buffer);
1403 }
1404 else if (instr->src[0].swizzle == (BWRITERVS_X_W | BWRITERVS_Y_X | BWRITERVS_Z_X | BWRITERVS_W_X))
1405 {
1406 TRACE("writing texreg2ar\n");
1407 writer->funcs->opcode(writer, instr, D3DSIO_TEXREG2AR & D3DSI_OPCODE_MASK, buffer);
1408 }
1409 else if (instr->src[0].swizzle == (BWRITERVS_X_Y | BWRITERVS_Y_Z | BWRITERVS_Z_Z | BWRITERVS_W_Z))
1410 {
1411 TRACE("writing texreg2gb\n");
1412 writer->funcs->opcode(writer, instr, D3DSIO_TEXREG2GB & D3DSI_OPCODE_MASK, buffer);
1413 }
1414 else
1415 {
1416 WARN("Unsupported src addr swizzle in dependent texld: 0x%08x\n", instr->src[0].swizzle);
1417 writer->state = E_INVALIDARG;
1418 return;
1419 }
1420
1421 /* Dst and src reg can be mapped normally. Both registers are
1422 * temporary registers in the source shader and have to be mapped to
1423 * the temporary form of the texture registers. However, the src reg
1424 * doesn't have a swizzle. */
1425 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1426 reg = instr->src[0];
1427 reg.swizzle = BWRITERVS_NOSWIZZLE;
1428 writer->funcs->srcreg(writer, &reg, buffer);
1429 }
1430 else
1431 {
1432 WARN("Invalid address data source register\n");
1433 writer->state = E_INVALIDARG;
1434 return;
1435 }
1436}
1437
1438static void instr_ps_1_0123_mov(struct bc_writer *writer, const struct instruction *instr,
1439 struct bytecode_buffer *buffer)
1440{
1442
1443 if (instr->dst.type == BWRITERSPR_TEMP && instr->src[0].type == BWRITERSPR_INPUT)
1444 {
1445 if ((instr->dst.regnum == T0_REG && instr->src[0].regnum == writer->t_regnum[0])
1446 || (instr->dst.regnum == T1_REG && instr->src[0].regnum == writer->t_regnum[1])
1447 || (instr->dst.regnum == T2_REG && instr->src[0].regnum == writer->t_regnum[2])
1448 || (instr->dst.regnum == T3_REG && instr->src[0].regnum == writer->t_regnum[3]))
1449 {
1450 if (instr->dstmod & BWRITERSPDM_SATURATE)
1451 {
1452 writer->funcs->opcode(writer, instr, D3DSIO_TEXCOORD & D3DSI_OPCODE_MASK, buffer);
1453 /* Remove the SATURATE flag, it's implicit to the instruction */
1454 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod & (~BWRITERSPDM_SATURATE));
1455 return;
1456 }
1457 else
1458 {
1459 WARN("A varying -> temp copy is only supported with the SATURATE modifier in <=ps_1_3\n");
1460 writer->state = E_INVALIDARG;
1461 return;
1462 }
1463 }
1464 else if (instr->src[0].regnum == writer->v_regnum[0] || instr->src[0].regnum == writer->v_regnum[1])
1465 {
1466 /* Handled by the normal mov below. Just drop out of the if condition */
1467 }
1468 else
1469 {
1470 WARN("Unsupported varying -> temp mov in <= ps_1_3\n");
1471 writer->state = E_INVALIDARG;
1472 return;
1473 }
1474 }
1475
1476 writer->funcs->opcode(writer, instr, token, buffer);
1477 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1478 writer->funcs->srcreg(writer, &instr->src[0], buffer);
1479}
1480
1481static const struct instr_handler_table ps_1_0123_handlers[] = {
1491
1492 /* pshader instructions */
1510};
1511
1514 end,
1519};
1520
1521static void ps_1_4_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
1522{
1523 uint32_t token = 1u << 31; /* Bit 31 of registers is 1. */
1524
1525 if (reg->rel_reg)
1526 {
1527 WARN("Relative addressing not supported in <= ps_3_0.\n");
1528 writer->state = E_INVALIDARG;
1529 return;
1530 }
1531
1532 switch (reg->type)
1533 {
1534 case BWRITERSPR_INPUT:
1535 token |= map_ps_input(writer, reg);
1536 break;
1537
1538 /* Can be mapped 1:1 */
1539 case BWRITERSPR_TEMP:
1540 case BWRITERSPR_CONST:
1541 token |= d3dsp_register( reg->type, reg->regnum );
1542 break;
1543
1544 default:
1545 WARN("Invalid register type for ps_1_4 shader\n");
1546 writer->state = E_INVALIDARG;
1547 return;
1548 }
1549
1550 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1551
1552 if (reg->srcmod == BWRITERSPSM_ABS || reg->srcmod == BWRITERSPSM_ABSNEG || reg->srcmod == BWRITERSPSM_NOT)
1553 {
1554 WARN("Invalid source modifier %u for ps_1_4\n", reg->srcmod);
1555 writer->state = E_INVALIDARG;
1556 return;
1557 }
1558 token |= d3d9_srcmod(reg->srcmod);
1560}
1561
1562static void ps_1_4_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer,
1564{
1565 uint32_t token = 1u << 31; /* Bit 31 of registers is 1. */
1566
1567 if (reg->rel_reg)
1568 {
1569 WARN("Relative addressing not supported for destination registers\n");
1570 writer->state = E_INVALIDARG;
1571 return;
1572 }
1573
1574 switch (reg->type)
1575 {
1576 case BWRITERSPR_TEMP: /* 1:1 mapping */
1577 token |= d3dsp_register( reg->type, reg->regnum );
1578 break;
1579
1580 /* For texkill */
1581 case BWRITERSPR_INPUT:
1582 token |= map_ps_input(writer, reg);
1583 break;
1584
1585 default:
1586 WARN("Invalid dest register type for 1.x pshader\n");
1587 writer->state = E_INVALIDARG;
1588 return;
1589 }
1590
1592 token |= d3d9_dstmod(mod);
1593
1594 token |= d3d9_writemask(reg->writemask);
1596}
1597
1598static void instr_ps_1_4_mov(struct bc_writer *writer, const struct instruction *instr,
1599 struct bytecode_buffer *buffer)
1600{
1602
1603 if (instr->dst.type == BWRITERSPR_TEMP && instr->src[0].type == BWRITERSPR_INPUT)
1604 {
1605 if (instr->src[0].regnum == writer->t_regnum[0] || instr->src[0].regnum == writer->t_regnum[1]
1606 || instr->src[0].regnum == writer->t_regnum[2] || instr->src[0].regnum == writer->t_regnum[3]
1607 || instr->src[0].regnum == writer->t_regnum[4] || instr->src[0].regnum == writer->t_regnum[5])
1608 {
1609 /* Similar to a regular mov, but a different opcode */
1611 }
1612 else if (instr->src[0].regnum == writer->v_regnum[0] || instr->src[0].regnum == writer->v_regnum[1])
1613 {
1614 /* Handled by the normal mov below. Just drop out of the if condition */
1615 }
1616 else
1617 {
1618 WARN("Unsupported varying -> temp mov in ps_1_4\n");
1619 writer->state = E_INVALIDARG;
1620 return;
1621 }
1622 }
1623
1624 writer->funcs->opcode(writer, instr, token, buffer);
1625 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1626 writer->funcs->srcreg(writer, &instr->src[0], buffer);
1627}
1628
1629static void instr_ps_1_4_texld(struct bc_writer *writer, const struct instruction *instr,
1630 struct bytecode_buffer *buffer)
1631{
1632 if (instr->src[1].type != BWRITERSPR_SAMPLER || instr->src[1].regnum > 5)
1633 {
1634 WARN("Unsupported sampler type %u regnum %u.\n",
1635 instr->src[1].type, instr->src[1].regnum);
1636 writer->state = E_INVALIDARG;
1637 return;
1638 }
1639 else if (instr->dst.type != BWRITERSPR_TEMP)
1640 {
1641 WARN("Can only sample into a temp register\n");
1642 writer->state = E_INVALIDARG;
1643 return;
1644 }
1645
1646 if (instr->src[1].regnum != instr->dst.regnum)
1647 {
1648 WARN("Sampling from sampler s%u to register r%u is not possible in ps_1_4.\n",
1649 instr->src[1].regnum, instr->dst.regnum);
1650 writer->state = E_INVALIDARG;
1651 return;
1652 }
1653
1654 writer->funcs->opcode(writer, instr, D3DSIO_TEX & D3DSI_OPCODE_MASK, buffer);
1655 writer->funcs->dstreg(writer, &instr->dst, buffer, instr->shift, instr->dstmod);
1656 writer->funcs->srcreg(writer, &instr->src[0], buffer);
1657}
1658
1659static const struct instr_handler_table ps_1_4_handlers[] = {
1669
1670 /* pshader instructions */
1677
1680};
1681
1682static const struct bytecode_backend ps_1_4_backend = {
1684 end,
1689};
1690
1691static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
1693}
1694
1695static void write_constI(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
1697}
1698
1699static void vs_2_header(struct bc_writer *This,
1700 const struct bwriter_shader *shader,
1701 struct bytecode_buffer *buffer) {
1702 HRESULT hr;
1703
1705 if(FAILED(hr)) {
1706 This->state = hr;
1707 return;
1708 }
1709
1714}
1715
1716static void vs_2_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
1717{
1718 uint32_t token = 1u << 31; /* Bit 31 of registers is 1 */
1720 uint32_t d3d9reg;
1721 BOOL has_swizzle;
1722
1723 switch (reg->type)
1724 {
1725 case BWRITERSPR_OUTPUT:
1726 /* Map the swizzle to a writemask, the format expected by
1727 * map_vs_output. */
1728 switch (reg->swizzle)
1729 {
1732 break;
1735 break;
1738 break;
1741 break;
1742 default:
1743 component = 0;
1744 }
1745 token |= map_vs_output(writer, reg->regnum, component, &has_swizzle);
1746 break;
1747
1748 case BWRITERSPR_RASTOUT:
1749 case BWRITERSPR_ATTROUT:
1750 /* These registers are mapped to input and output regs. They can be encoded in the bytecode,
1751 * but are unexpected. If we hit this path it might be due to an error.
1752 */
1753 FIXME("Unexpected register type %u.\n", reg->type);
1754 /* drop through */
1755 case BWRITERSPR_INPUT:
1756 case BWRITERSPR_TEMP:
1757 case BWRITERSPR_CONST:
1758 case BWRITERSPR_ADDR:
1761 case BWRITERSPR_LABEL:
1762 d3d9reg = d3d9_register(reg->type);
1763 token |= d3dsp_register(d3d9reg, reg->regnum);
1764 break;
1765
1766 case BWRITERSPR_LOOP:
1767 if (reg->regnum != 0)
1768 {
1769 WARN("Only regnum 0 is supported for the loop index register in vs_2_0\n");
1770 writer->state = E_INVALIDARG;
1771 return;
1772 }
1774 break;
1775
1777 if (writer->shader->major_version != 2 || writer->shader->minor_version != 1)
1778 {
1779 WARN("Predicate register is allowed only in vs_2_x\n");
1780 writer->state = E_INVALIDARG;
1781 return;
1782 }
1783 if (reg->regnum > 0)
1784 {
1785 WARN("Only predicate register 0 is supported\n");
1786 writer->state = E_INVALIDARG;
1787 return;
1788 }
1790 break;
1791
1792 default:
1793 WARN("Invalid register type for 2.0 vshader\n");
1794 writer->state = E_INVALIDARG;
1795 return;
1796 }
1797
1798 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
1799 token |= d3d9_srcmod(reg->srcmod);
1800
1801 if (reg->rel_reg)
1803
1805
1806 /* vs_2_0 and newer write the register containing the index explicitly in
1807 * the binary code. */
1809 vs_2_srcreg(writer, reg->rel_reg, buffer);
1810}
1811
1812static void sm_2_opcode(struct bc_writer *writer, const struct instruction *instr, uint32_t token,
1813 struct bytecode_buffer *buffer)
1814{
1815 unsigned int dst_count = instr->has_dst ? 1 : 0;
1816
1817 /* From SM 2 onwards instruction length is encoded in the opcode field. */
1818 token |= instrlen(instr, instr->num_srcs, dst_count) << D3DSI_INSTLENGTH_SHIFT;
1819 if (instr->comptype)
1820 token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
1821 if (instr->has_predicate)
1824}
1825
1826static const struct instr_handler_table vs_2_0_handlers[] = {
1861
1873
1875};
1876
1877static const struct bytecode_backend vs_2_0_backend = {
1879 end,
1884};
1885
1886static const struct instr_handler_table vs_2_x_handlers[] = {
1921
1936
1939
1941};
1942
1943static const struct bytecode_backend vs_2_x_backend = {
1945 end,
1950};
1951
1952static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
1953{
1955 uint32_t instr_dcl = D3DSIO_DCL | (2 << D3DSI_INSTLENGTH_SHIFT);
1956 unsigned int i;
1958
1959 for (i = 0; i < shader->num_samplers; ++i)
1960 {
1961 /* Write the DCL instruction */
1962 put_u32(buffer, instr_dcl);
1963 token = 1u << 31;
1964 /* Already shifted */
1965 token |= d3d9_sampler(shader->samplers[i].type) & D3DSP_TEXTURETYPE_MASK;
1967 token = reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK);
1968 token |= d3d9_dstmod(shader->samplers[i].mod);
1970 }
1971}
1972
1973static void ps_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
1975 if(FAILED(hr)) {
1976 This->state = hr;
1977 return;
1978 }
1979
1985}
1986
1987static void ps_2_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
1988{
1989 uint32_t token = 1u << 31; /* Bit 31 of registers is 1 */
1990 uint32_t d3d9reg;
1991
1992 if (reg->rel_reg)
1993 {
1994 WARN("Relative addressing not supported in <= ps_3_0\n");
1995 writer->state = E_INVALIDARG;
1996 return;
1997 }
1998
1999 switch (reg->type)
2000 {
2001 case BWRITERSPR_INPUT:
2002 token |= map_ps_input(writer, reg);
2003 break;
2004
2005 /* Can be mapped 1:1 */
2006 case BWRITERSPR_TEMP:
2007 case BWRITERSPR_CONST:
2011 case BWRITERSPR_SAMPLER:
2012 case BWRITERSPR_LABEL:
2014 d3d9reg = d3d9_register(reg->type);
2015 token |= d3dsp_register(d3d9reg, reg->regnum);
2016 break;
2017
2019 if (writer->shader->minor_version == 0)
2020 {
2021 WARN("Predicate register not supported in ps_2_0\n");
2022 writer->state = E_INVALIDARG;
2023 }
2024 if (reg->regnum)
2025 {
2026 WARN("Predicate register with regnum %u not supported.\n", reg->regnum);
2027 writer->state = E_INVALIDARG;
2028 }
2030 break;
2031
2032 default:
2033 WARN("Invalid register type for ps_2_0 shader\n");
2034 writer->state = E_INVALIDARG;
2035 return;
2036 }
2037
2038 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
2039
2040 token |= d3d9_srcmod(reg->srcmod);
2042}
2043
2044static void ps_2_0_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer,
2046{
2047 uint32_t token = 1u << 31; /* Bit 31 of registers is 1 */
2048 uint32_t d3d9reg;
2049
2050 if (reg->rel_reg)
2051 {
2052 WARN("Relative addressing not supported for destination registers\n");
2053 writer->state = E_INVALIDARG;
2054 return;
2055 }
2056
2057 switch (reg->type)
2058 {
2059 case BWRITERSPR_TEMP: /* 1:1 mapping */
2062 d3d9reg = d3d9_register(reg->type);
2063 token |= d3dsp_register(d3d9reg, reg->regnum);
2064 break;
2065
2067 if (writer->shader->minor_version == 0)
2068 {
2069 WARN("Predicate register not supported in ps_2_0\n");
2070 writer->state = E_INVALIDARG;
2071 }
2073 break;
2074
2075 /* texkill uses the input register as a destination parameter */
2076 case BWRITERSPR_INPUT:
2077 token |= map_ps_input(writer, reg);
2078 break;
2079
2080 default:
2081 WARN("Invalid dest register type for 2.x pshader\n");
2082 writer->state = E_INVALIDARG;
2083 return;
2084 }
2085
2087 token |= d3d9_dstmod(mod);
2088
2089 token |= d3d9_writemask(reg->writemask);
2091}
2092
2093static const struct instr_handler_table ps_2_0_handlers[] = {
2124
2129
2131};
2132
2133static const struct bytecode_backend ps_2_0_backend = {
2135 end,
2140};
2141
2142static const struct instr_handler_table ps_2_x_handlers[] = {
2173
2186
2193
2196
2198
2200};
2201
2202static const struct bytecode_backend ps_2_x_backend = {
2204 end,
2209};
2210
2211static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
2213 write_declarations(This, buffer, shader->outputs, shader->num_outputs, BWRITERSPR_OUTPUT);
2218}
2219
2220static void sm_3_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
2221{
2222 const struct bwriter_shader *shader = writer->shader;
2223 uint32_t token = 1u << 31; /* Bit 31 of registers is 1 */
2224 uint32_t d3d9reg;
2225
2226 d3d9reg = d3d9_register(reg->type);
2227 token |= d3dsp_register(d3d9reg, reg->regnum);
2229 token |= d3d9_srcmod(reg->srcmod);
2230
2231 if (reg->rel_reg)
2232 {
2233 if (reg->type == BWRITERSPR_CONST && shader->type == ST_PIXEL)
2234 {
2235 WARN("c%u[...] is unsupported in ps_3_0.\n", reg->regnum);
2236 writer->state = E_INVALIDARG;
2237 return;
2238 }
2239
2240 if (((reg->rel_reg->type == BWRITERSPR_ADDR && shader->type == ST_VERTEX)
2241 || reg->rel_reg->type == BWRITERSPR_LOOP) && reg->rel_reg->regnum == 0)
2242 {
2244 }
2245 else
2246 {
2247 WARN("Unsupported relative addressing register\n");
2248 writer->state = E_INVALIDARG;
2249 return;
2250 }
2251 }
2252
2254
2255 /* vs_2_0 and newer write the register containing the index explicitly in
2256 * the binary code. */
2258 sm_3_srcreg(writer, reg->rel_reg, buffer);
2259}
2260
2261static void sm_3_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer,
2263{
2264 const struct bwriter_shader *shader = writer->shader;
2265 uint32_t token = 1u << 31; /* Bit 31 of registers is 1 */
2266 uint32_t d3d9reg;
2267
2268 if (reg->rel_reg)
2269 {
2270 if (shader->type == ST_VERTEX && reg->type == BWRITERSPR_OUTPUT)
2271 {
2273 }
2274 else
2275 {
2276 WARN("Relative addressing not supported for this shader type or register type\n");
2277 writer->state = E_INVALIDARG;
2278 return;
2279 }
2280 }
2281
2282 d3d9reg = d3d9_register(reg->type);
2283 token |= d3dsp_register(d3d9reg, reg->regnum);
2284 token |= d3d9_dstmod(mod);
2285 token |= d3d9_writemask(reg->writemask);
2287
2288 /* vs_2_0 and newer write the register containing the index explicitly in
2289 * the binary code. */
2291 sm_3_srcreg(writer, reg->rel_reg, buffer);
2292}
2293
2294static const struct instr_handler_table vs_3_handlers[] = {
2329
2344
2348
2350};
2351
2352static const struct bytecode_backend vs_3_backend = {
2354 end,
2359};
2360
2361static const struct instr_handler_table ps_3_handlers[] = {
2392
2407
2411
2419
2421};
2422
2423static const struct bytecode_backend ps_3_backend = {
2425 end,
2430};
2431
2432static const struct
2433{
2435 unsigned char major, minor;
2437}
2439{
2440 {ST_VERTEX, 1, 0, &vs_1_x_backend},
2441 {ST_VERTEX, 1, 1, &vs_1_x_backend},
2442 {ST_VERTEX, 2, 0, &vs_2_0_backend},
2443 {ST_VERTEX, 2, 1, &vs_2_x_backend},
2444 {ST_VERTEX, 3, 0, &vs_3_backend},
2445
2446 {ST_PIXEL, 1, 0, &ps_1_0123_backend},
2447 {ST_PIXEL, 1, 1, &ps_1_0123_backend},
2448 {ST_PIXEL, 1, 2, &ps_1_0123_backend},
2449 {ST_PIXEL, 1, 3, &ps_1_0123_backend},
2450 {ST_PIXEL, 1, 4, &ps_1_4_backend},
2451 {ST_PIXEL, 2, 0, &ps_2_0_backend},
2452 {ST_PIXEL, 2, 1, &ps_2_x_backend},
2453 {ST_PIXEL, 3, 0, &ps_3_backend},
2455
2456static HRESULT call_instr_handler(struct bc_writer *writer, const struct instruction *instr,
2457 struct bytecode_buffer *buffer)
2458{
2459 unsigned int i;
2460
2461 for (i = 0; writer->funcs->instructions[i].opcode != BWRITERSIO_END; ++i)
2462 {
2463 if (instr->opcode == writer->funcs->instructions[i].opcode)
2464 {
2465 if (!writer->funcs->instructions[i].func)
2466 {
2467 WARN("Opcode %u not supported by this profile.\n", instr->opcode);
2468 return E_INVALIDARG;
2469 }
2470 writer->funcs->instructions[i].func(writer, instr, buffer);
2471 return S_OK;
2472 }
2473 }
2474
2475 FIXME("Unhandled instruction %u - %s.\n", instr->opcode, debug_print_opcode(instr->opcode));
2476 return E_INVALIDARG;
2477}
2478
2480{
2481 struct bc_writer *writer;
2482 struct bytecode_buffer *buffer = NULL;
2483 HRESULT hr;
2484 unsigned int i;
2485
2486 if(!shader){
2487 ERR("NULL shader structure, aborting\n");
2488 return E_FAIL;
2489 }
2490
2491 if (!(writer = calloc(1, sizeof(*writer))))
2492 return E_OUTOFMEMORY;
2493
2494 for (i = 0; i < ARRAY_SIZE(shader_backends); ++i)
2495 {
2496 if (shader->type == shader_backends[i].type
2497 && shader->major_version == shader_backends[i].major
2498 && shader->minor_version == shader_backends[i].minor)
2499 {
2500 writer->funcs = shader_backends[i].backend;
2501 break;
2502 }
2503 }
2504
2505 if (!writer->funcs)
2506 {
2507 FIXME("Unsupported shader type %#x, version %u.%u.\n",
2508 shader->type, shader->major_version, shader->minor_version);
2509 free(writer);
2510 return E_NOTIMPL;
2511 }
2512
2513 writer->shader = shader;
2514 *result = NULL;
2515
2517 if(!buffer) {
2518 WARN("Failed to allocate a buffer for the shader bytecode\n");
2519 hr = E_FAIL;
2520 goto error;
2521 }
2522
2523 /* Write shader type and version */
2525
2526 writer->funcs->header(writer, shader, buffer);
2527 if(FAILED(writer->state)) {
2528 hr = writer->state;
2529 goto error;
2530 }
2531
2532 for(i = 0; i < shader->num_instrs; i++) {
2533 hr = call_instr_handler(writer, shader->instr[i], buffer);
2534 if(FAILED(hr)) {
2535 goto error;
2536 }
2537 }
2538
2539 if(FAILED(writer->state)) {
2540 hr = writer->state;
2541 goto error;
2542 }
2543
2544 writer->funcs->end(writer, shader, buffer);
2545
2546 if(FAILED(buffer->state)) {
2547 hr = buffer->state;
2548 goto error;
2549 }
2550
2551 *size = buffer->size * sizeof(uint32_t);
2552 *result = buffer->data;
2553 buffer->data = NULL;
2554 hr = S_OK;
2555
2556error:
2557 if(buffer) {
2558 free(buffer->data);
2559 free(buffer);
2560 }
2561 free(writer);
2562 return hr;
2563}
2564
2566 unsigned int i, j;
2567
2568 TRACE("Deleting shader %p\n", shader);
2569
2570 for(i = 0; i < shader->num_cf; i++) {
2571 free(shader->constF[i]);
2572 }
2573 free(shader->constF);
2574 for(i = 0; i < shader->num_ci; i++) {
2575 free(shader->constI[i]);
2576 }
2577 free(shader->constI);
2578 for(i = 0; i < shader->num_cb; i++) {
2579 free(shader->constB[i]);
2580 }
2581 free(shader->constB);
2582
2583 free(shader->inputs);
2584 free(shader->outputs);
2585 free(shader->samplers);
2586
2587 for(i = 0; i < shader->num_instrs; i++) {
2588 for(j = 0; j < shader->instr[i]->num_srcs; j++) {
2589 free(shader->instr[i]->src[j].rel_reg);
2590 }
2591 free(shader->instr[i]->src);
2592 free(shader->instr[i]->dst.rel_reg);
2593 free(shader->instr[i]);
2594 }
2595 free(shader->instr);
2596
2597 free(shader);
2598}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:68
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define U(x)
Definition: wordpad.c:45
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
static uint32_t d3d9_opcode(uint32_t bwriter_opcode)
static void put_u32(struct bytecode_buffer *buffer, uint32_t value)
static uint32_t d3d9_srcmod(uint32_t bwriter_srcmod)
static const struct @269 shader_backends[]
BOOL add_constB(struct bwriter_shader *shader, uint32_t reg, BOOL x)
static void write_constI(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
static void sm_3_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
static void write_srcregs(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static void instr_ps_1_0123_mov(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static uint32_t d3d9_swizzle(uint32_t bwriter_swizzle)
static const struct bytecode_backend ps_2_x_backend
static const struct instr_handler_table vs_2_x_handlers[]
static uint32_t map_vs_output(struct bc_writer *writer, uint32_t regnum, uint32_t mask, BOOL *has_components)
static const struct bytecode_backend ps_1_4_backend
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
static void write_const(struct constant **consts, int num, uint32_t opcode, uint32_t reg_type, struct bytecode_buffer *buffer, BOOL len)
HRESULT shader_write_bytecode(const struct bwriter_shader *shader, uint32_t **result, uint32_t *size)
static uint32_t d3d9_sampler(uint32_t bwriter_sampler)
static HRESULT call_instr_handler(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static void ps_1_4_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
const struct bytecode_backend * backend
static uint32_t map_ps_input(struct bc_writer *writer, const struct shader_reg *reg)
static const struct bytecode_backend ps_2_0_backend
static uint32_t sm1_version(const struct bwriter_shader *shader)
static const struct bytecode_backend vs_1_x_backend
static const struct instr_handler_table vs_2_0_handlers[]
static void vs_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static HRESULT find_ps_builtin_semantics(struct bc_writer *writer, const struct bwriter_shader *shader, uint32_t texcoords)
static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
static void ps_1_4_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static uint32_t d3d9_register(uint32_t bwriter_register)
BOOL add_constF(struct bwriter_shader *shader, uint32_t reg, float x, float y, float z, float w)
static const struct instr_handler_table ps_3_handlers[]
static uint32_t map_ps13_temp(struct bc_writer *writer, const struct shader_reg *reg)
BOOL record_sampler(struct bwriter_shader *shader, uint32_t samptype, uint32_t mod, uint32_t regnum)
static void sm_2_opcode(struct bc_writer *writer, const struct instruction *instr, uint32_t token, struct bytecode_buffer *buffer)
struct instruction * alloc_instr(unsigned int srcs)
static const struct instr_handler_table ps_2_0_handlers[]
unsigned char major
static void sm_3_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void ps_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void vs_2_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void instr_ps_1_4_mov(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void write_declarations(struct bc_writer *writer, struct bytecode_buffer *buffer, const struct declaration *decls, unsigned int num, uint32_t type)
static HRESULT vs_find_builtin_varyings(struct bc_writer *writer, const struct bwriter_shader *shader)
void SlDeleteShader(struct bwriter_shader *shader)
static uint32_t d3d9_writemask(uint32_t bwriter_writemask)
static const struct bytecode_backend vs_2_0_backend
static uint32_t d3d9_comparetype(uint32_t asmshader_comparetype)
static uint32_t d3d9_dstmod(uint32_t bwriter_mod)
static void ps_2_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static const struct instr_handler_table ps_2_x_handlers[]
static void instr_handler(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static const struct instr_handler_table vs_1_x_handlers[]
static void ps_1_0123_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void sm_1_x_opcode(struct bc_writer *writer, const struct instruction *instr, uint32_t token, struct bytecode_buffer *buffer)
static const struct bytecode_backend vs_2_x_backend
static void instr_ps_1_4_texld(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static const struct bytecode_backend ps_1_0123_backend
static const struct bytecode_backend vs_3_backend
static void vs_12_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
enum shader_type type
unsigned char minor
static const struct instr_handler_table vs_3_handlers[]
static const struct instr_handler_table ps_1_4_handlers[]
void(* instr_writer)(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static void ps_2_0_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
static unsigned int instrlen(const struct instruction *instr, unsigned int srcs, unsigned int dsts)
static struct bytecode_buffer * allocate_buffer(void)
BOOL record_declaration(struct bwriter_shader *shader, uint32_t usage, uint32_t usage_idx, uint32_t mod, BOOL output, uint32_t regnum, uint32_t writemask, BOOL builtin)
static const struct bytecode_backend ps_3_backend
static void vs_2_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void vs_1_x_srcreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
static void ps_1_x_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len)
static void ps_1_0123_dstreg(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
static const struct instr_handler_table ps_1_0123_handlers[]
static void instr_ps_1_0123_texld(struct bc_writer *writer, const struct instruction *instr, struct bytecode_buffer *buffer)
static void ps_1_4_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer)
BOOL add_constI(struct bwriter_shader *shader, uint32_t reg, int x, int y, int z, int w)
static uint32_t d3dsp_register(D3DSHADER_PARAM_REGISTER_TYPE type, uint32_t num)
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr)
BYTE usage_idx
#define D3DVS_W_Z
Definition: d3d8types.h:448
#define D3DSP_WRITEMASK_ALL
Definition: d3d8types.h:378
@ D3DSPSM_COMP
Definition: d3d8types.h:466
@ D3DSPSM_NEG
Definition: d3d8types.h:461
@ D3DSPSM_BIASNEG
Definition: d3d8types.h:463
@ D3DSPSM_DZ
Definition: d3d8types.h:469
@ D3DSPSM_SIGN
Definition: d3d8types.h:464
@ D3DSPSM_X2NEG
Definition: d3d8types.h:468
@ D3DSPSM_NONE
Definition: d3d8types.h:460
@ D3DSPSM_SIGNNEG
Definition: d3d8types.h:465
@ D3DSPSM_DW
Definition: d3d8types.h:470
@ D3DSPSM_BIAS
Definition: d3d8types.h:462
@ D3DSPSM_X2
Definition: d3d8types.h:467
#define D3DSP_WRITEMASK_2
Definition: d3d8types.h:376
#define D3DVS_X_Z
Definition: d3d8types.h:433
#define D3DPS_VERSION(major, minor)
Definition: d3d8types.h:474
#define D3DVS_Z_Z
Definition: d3d8types.h:443
#define D3DVS_W_W
Definition: d3d8types.h:449
#define D3DVS_SWIZZLE_MASK
Definition: d3d8types.h:426
@ D3DSPDM_SATURATE
Definition: d3d8types.h:385
#define D3DSI_COISSUE
Definition: d3d8types.h:371
#define D3DSP_WRITEMASK_3
Definition: d3d8types.h:377
#define D3DSP_DSTSHIFT_SHIFT
Definition: d3d8types.h:390
#define D3DVS_Y_Y
Definition: d3d8types.h:437
#define D3DVS_W_X
Definition: d3d8types.h:446
#define D3DSP_DSTSHIFT_MASK
Definition: d3d8types.h:391
#define D3DSI_OPCODE_MASK
Definition: d3d8types.h:306
#define D3DSP_WRITEMASK_0
Definition: d3d8types.h:374
enum _D3DSHADER_PARAM_REGISTER_TYPE D3DSHADER_PARAM_REGISTER_TYPE
#define D3DVS_Z_X
Definition: d3d8types.h:441
#define D3DVS_Y_X
Definition: d3d8types.h:436
#define D3DSP_WRITEMASK_1
Definition: d3d8types.h:375
#define D3DVS_ADDRESSMODE_MASK
Definition: d3d8types.h:417
#define D3DSP_REGTYPE_MASK
Definition: d3d8types.h:395
#define D3DVS_VERSION(major, minor)
Definition: d3d8types.h:475
@ D3DSIO_M4x4
Definition: d3d8types.h:330
@ D3DSIO_MIN
Definition: d3d8types.h:320
@ D3DSIO_MAD
Definition: d3d8types.h:314
@ D3DSIO_TEXCOORD
Definition: d3d8types.h:336
@ D3DSIO_CND
Definition: d3d8types.h:352
@ D3DSIO_TEXDP3TEX
Definition: d3d8types.h:355
@ D3DSIO_EXPP
Definition: d3d8types.h:350
@ D3DSIO_TEXM3x3SPEC
Definition: d3d8types.h:348
@ D3DSIO_M3x4
Definition: d3d8types.h:332
@ D3DSIO_CMP
Definition: d3d8types.h:360
@ D3DSIO_TEXKILL
Definition: d3d8types.h:337
@ D3DSIO_TEXM3x2PAD
Definition: d3d8types.h:343
@ D3DSIO_SGE
Definition: d3d8types.h:323
@ D3DSIO_MOV
Definition: d3d8types.h:311
@ D3DSIO_TEXBEM
Definition: d3d8types.h:339
@ D3DSIO_MAX
Definition: d3d8types.h:321
@ D3DSIO_SUB
Definition: d3d8types.h:313
@ D3DSIO_TEXDP3
Definition: d3d8types.h:357
@ D3DSIO_COMMENT
Definition: d3d8types.h:364
@ D3DSIO_FRC
Definition: d3d8types.h:329
@ D3DSIO_M4x3
Definition: d3d8types.h:331
@ D3DSIO_NOP
Definition: d3d8types.h:310
@ D3DSIO_LRP
Definition: d3d8types.h:328
@ D3DSIO_TEX
Definition: d3d8types.h:338
@ D3DSIO_ADD
Definition: d3d8types.h:312
@ D3DSIO_TEXM3x2TEX
Definition: d3d8types.h:344
@ D3DSIO_M3x3
Definition: d3d8types.h:333
@ D3DSIO_TEXBEML
Definition: d3d8types.h:340
@ D3DSIO_END
Definition: d3d8types.h:365
@ D3DSIO_EXP
Definition: d3d8types.h:324
@ D3DSIO_TEXM3x3VSPEC
Definition: d3d8types.h:349
@ D3DSIO_TEXREG2GB
Definition: d3d8types.h:342
@ D3DSIO_M3x2
Definition: d3d8types.h:334
@ D3DSIO_TEXREG2AR
Definition: d3d8types.h:341
@ D3DSIO_BEM
Definition: d3d8types.h:361
@ D3DSIO_DP4
Definition: d3d8types.h:319
@ D3DSIO_TEXM3x3
Definition: d3d8types.h:358
@ D3DSIO_TEXM3x3PAD
Definition: d3d8types.h:345
@ D3DSIO_LOGP
Definition: d3d8types.h:351
@ D3DSIO_TEXM3x3TEX
Definition: d3d8types.h:346
@ D3DSIO_LOG
Definition: d3d8types.h:325
@ D3DSIO_DST
Definition: d3d8types.h:327
@ D3DSIO_DP3
Definition: d3d8types.h:318
@ D3DSIO_TEXM3x2DEPTH
Definition: d3d8types.h:356
@ D3DSIO_RCP
Definition: d3d8types.h:316
@ D3DSIO_DEF
Definition: d3d8types.h:353
@ D3DSIO_SLT
Definition: d3d8types.h:322
@ D3DSIO_RSQ
Definition: d3d8types.h:317
@ D3DSIO_LIT
Definition: d3d8types.h:326
@ D3DSIO_TEXREG2RGB
Definition: d3d8types.h:354
@ D3DSIO_PHASE
Definition: d3d8types.h:363
@ D3DSIO_TEXDEPTH
Definition: d3d8types.h:359
@ D3DSIO_MUL
Definition: d3d8types.h:315
#define D3DVS_X_X
Definition: d3d8types.h:431
#define D3DVS_Y_W
Definition: d3d8types.h:439
#define D3DVS_W_Y
Definition: d3d8types.h:447
#define D3DVS_Z_W
Definition: d3d8types.h:444
#define D3DVS_Y_Z
Definition: d3d8types.h:438
@ D3DSRO_POINT_SIZE
Definition: d3d8types.h:412
@ D3DSRO_FOG
Definition: d3d8types.h:411
@ D3DSRO_POSITION
Definition: d3d8types.h:410
#define D3DVS_X_Y
Definition: d3d8types.h:432
#define D3DSP_REGTYPE_SHIFT
Definition: d3d8types.h:394
@ D3DVS_ADDRMODE_RELATIVE
Definition: d3d8types.h:421
#define D3DVS_X_W
Definition: d3d8types.h:434
@ D3DSPR_TEXTURE
Definition: d3d8types.h:402
@ D3DSPR_RASTOUT
Definition: d3d8types.h:403
@ D3DSPR_ADDR
Definition: d3d8types.h:401
@ D3DSPR_TEMP
Definition: d3d8types.h:398
@ D3DSPR_INPUT
Definition: d3d8types.h:399
@ D3DSPR_ATTROUT
Definition: d3d8types.h:404
@ D3DSPR_CONST
Definition: d3d8types.h:400
@ D3DSPR_TEXCRDOUT
Definition: d3d8types.h:405
#define D3DVS_Z_Y
Definition: d3d8types.h:442
#define D3DSP_REGTYPE_MASK2
Definition: d3d9types.h:529
@ D3DSPSM_ABS
Definition: d3d9types.h:639
@ D3DSPSM_NOT
Definition: d3d9types.h:641
@ D3DSPSM_ABSNEG
Definition: d3d9types.h:640
#define D3DSI_INSTLENGTH_SHIFT
Definition: d3d9types.h:372
#define D3DSI_TEXLD_BIAS
Definition: d3d9types.h:473
@ D3DSPDM_PARTIALPRECISION
Definition: d3d9types.h:515
@ D3DSPDM_MSAMPCENTROID
Definition: d3d9types.h:516
#define D3DSP_DCL_USAGE_MASK
Definition: d3d9types.h:479
@ D3DSPC_EQ
Definition: d3d9types.h:1626
@ D3DSPC_NE
Definition: d3d9types.h:1629
@ D3DSPC_GE
Definition: d3d9types.h:1627
@ D3DSPC_LT
Definition: d3d9types.h:1628
@ D3DSPC_GT
Definition: d3d9types.h:1625
@ D3DSPC_LE
Definition: d3d9types.h:1630
#define D3DSHADER_INSTRUCTION_PREDICATED
Definition: d3d9types.h:470
#define D3DSP_REGTYPE_SHIFT2
Definition: d3d9types.h:527
#define D3DSI_TEXLD_PROJECT
Definition: d3d9types.h:472
#define D3DSP_DCL_USAGE_SHIFT
Definition: d3d9types.h:478
@ D3DSIO_BREAK
Definition: d3d9types.h:420
@ D3DSIO_DP2ADD
Definition: d3d9types.h:452
@ D3DSIO_CALL
Definition: d3d9types.h:401
@ D3DSIO_POW
Definition: d3d9types.h:408
@ D3DSIO_REP
Definition: d3d9types.h:414
@ D3DSIO_ENDREP
Definition: d3d9types.h:415
@ D3DSIO_CRS
Definition: d3d9types.h:409
@ D3DSIO_RET
Definition: d3d9types.h:404
@ D3DSIO_CALLNZ
Definition: d3d9types.h:402
@ D3DSIO_NRM
Definition: d3d9types.h:412
@ D3DSIO_SGN
Definition: d3d9types.h:410
@ D3DSIO_TEXLDL
Definition: d3d9types.h:457
@ D3DSIO_ENDLOOP
Definition: d3d9types.h:405
@ D3DSIO_TEXLDD
Definition: d3d9types.h:455
@ D3DSIO_DSX
Definition: d3d9types.h:453
@ D3DSIO_DEFB
Definition: d3d9types.h:423
@ D3DSIO_DCL
Definition: d3d9types.h:407
@ D3DSIO_ABS
Definition: d3d9types.h:411
@ D3DSIO_SINCOS
Definition: d3d9types.h:413
@ D3DSIO_LOOP
Definition: d3d9types.h:403
@ D3DSIO_SETP
Definition: d3d9types.h:456
@ D3DSIO_IF
Definition: d3d9types.h:416
@ D3DSIO_BREAKP
Definition: d3d9types.h:458
@ D3DSIO_BREAKC
Definition: d3d9types.h:421
@ D3DSIO_IFC
Definition: d3d9types.h:417
@ D3DSIO_ENDIF
Definition: d3d9types.h:419
@ D3DSIO_DEFI
Definition: d3d9types.h:424
@ D3DSIO_MOVA
Definition: d3d9types.h:422
@ D3DSIO_DSY
Definition: d3d9types.h:454
@ D3DSIO_ELSE
Definition: d3d9types.h:418
@ D3DSIO_LABEL
Definition: d3d9types.h:406
#define D3DSP_REGNUM_MASK
Definition: d3d9types.h:500
@ D3DSTT_UNKNOWN
Definition: d3d9types.h:491
@ D3DSTT_2D
Definition: d3d9types.h:493
@ D3DSTT_VOLUME
Definition: d3d9types.h:495
@ D3DSTT_CUBE
Definition: d3d9types.h:494
@ D3DSTT_1D
Definition: d3d9types.h:492
#define D3DSP_TEXTURETYPE_MASK
Definition: d3d9types.h:488
#define D3DSP_DCL_USAGEINDEX_MASK
Definition: d3d9types.h:482
#define D3DSP_DCL_USAGEINDEX_SHIFT
Definition: d3d9types.h:481
@ D3DSPR_LOOP
Definition: d3d9types.h:550
@ D3DSPR_SAMPLER
Definition: d3d9types.h:545
@ D3DSPR_COLOROUT
Definition: d3d9types.h:543
@ D3DSPR_DEPTHOUT
Definition: d3d9types.h:544
@ D3DSPR_CONSTINT
Definition: d3d9types.h:542
@ D3DSPR_MISCTYPE
Definition: d3d9types.h:552
@ D3DSPR_OUTPUT
Definition: d3d9types.h:541
@ D3DSPR_LABEL
Definition: d3d9types.h:553
@ D3DSPR_CONSTBOOL
Definition: d3d9types.h:549
@ D3DSPR_PREDICATE
Definition: d3d9types.h:554
#define BWRITERVS_Y_W
@ BWRITERSPSM_COMP
@ BWRITERSPSM_X2
@ BWRITERSPSM_ABS
@ BWRITERSPSM_NONE
@ BWRITERSPSM_BIAS
@ BWRITERSPSM_X2NEG
@ BWRITERSPSM_NEG
@ BWRITERSPSM_SIGNNEG
@ BWRITERSPSM_BIASNEG
@ BWRITERSPSM_DZ
@ BWRITERSPSM_ABSNEG
@ BWRITERSPSM_NOT
@ BWRITERSPSM_SIGN
@ BWRITERSPSM_DW
#define BWRITERVS_SWIZZLE_Z
#define BWRITERVS_Z_Z
#define BWRITERSP_WRITEMASK_3
#define BWRITERSP_WRITEMASK_0
@ BWRITER_COMPARISON_NE
@ BWRITER_COMPARISON_LE
@ BWRITER_COMPARISON_GT
@ BWRITER_COMPARISON_GE
@ BWRITER_COMPARISON_LT
@ BWRITER_COMPARISON_EQ
#define BWRITERVS_X_X
#define T3_REG
@ BWRITERSPDM_SATURATE
@ BWRITERSPDM_PARTIALPRECISION
@ BWRITERSPDM_MSAMPCENTROID
#define BWRITERVS_Y_Y
@ BWRITERDECLUSAGE_FOG
@ BWRITERDECLUSAGE_PSIZE
@ BWRITERDECLUSAGE_COLOR
@ BWRITERDECLUSAGE_POSITION
@ BWRITERDECLUSAGE_POSITIONT
@ BWRITERDECLUSAGE_TEXCOORD
#define BWRITERSP_WRITEMASK_ALL
#define BWRITERVS_Y_X
#define BWRITERVS_W_X
#define BWRITERVS_Z_X
#define BWRITERVS_SWIZZLE_X
#define BWRITERVS_Z_W
#define BWRITERVS_Y_Z
#define T1_REG
#define BWRITERVS_Z_Y
#define BWRITERVS_W_W
#define BWRITERVS_X_Z
#define BWRITERVS_SWIZZLE_W
#define BWRITERVS_NOSWIZZLE
#define BWRITERVS_W_Z
#define BWRITERSP_WRITEMASK_1
@ BWRITERSTT_CUBE
@ BWRITERSTT_UNKNOWN
@ BWRITERSTT_VOLUME
@ BWRITERSTT_2D
@ BWRITERSTT_1D
#define T0_REG
@ ST_VERTEX
@ ST_PIXEL
@ BWRITERSPR_TEXCRDOUT
@ BWRITERSPR_CONSTINT
@ BWRITERSPR_MISCTYPE
@ BWRITERSPR_RASTOUT
@ BWRITERSPR_LOOP
@ BWRITERSPR_CONSTBOOL
@ BWRITERSPR_COLOROUT
@ BWRITERSPR_SAMPLER
@ BWRITERSPR_CONST
@ BWRITERSPR_TEXTURE
@ BWRITERSPR_DEPTHOUT
@ BWRITERSPR_ADDR
@ BWRITERSPR_ATTROUT
@ BWRITERSPR_TEMP
@ BWRITERSPR_INPUT
@ BWRITERSPR_PREDICATE
@ BWRITERSPR_LABEL
@ BWRITERSPR_OUTPUT
#define BWRITERVS_W_Y
#define BWRITERSP_WRITEMASK_2
#define BWRITERVS_X_Y
@ BWRITERSIO_EXP
@ BWRITERSIO_TEXBEML
@ BWRITERSIO_DSX
@ BWRITERSIO_LRP
@ BWRITERSIO_MAX
@ BWRITERSIO_TEXLDB
@ BWRITERSIO_BEM
@ BWRITERSIO_RCP
@ BWRITERSIO_MOV
@ BWRITERSIO_POW
@ BWRITERSIO_NRM
@ BWRITERSIO_DEF
@ BWRITERSIO_TEXM3x3TEX
@ BWRITERSIO_DEFB
@ BWRITERSIO_MIN
@ BWRITERSIO_TEXM3x2PAD
@ BWRITERSIO_DP2ADD
@ BWRITERSIO_SGE
@ BWRITERSIO_CALLNZ
@ BWRITERSIO_MUL
@ BWRITERSIO_BREAK
@ BWRITERSIO_END
@ BWRITERSIO_CALL
@ BWRITERSIO_TEXM3x3PAD
@ BWRITERSIO_ENDREP
@ BWRITERSIO_CND
@ BWRITERSIO_BREAKP
@ BWRITERSIO_SGN
@ BWRITERSIO_M3x4
@ BWRITERSIO_TEXDP3
@ BWRITERSIO_LOOP
@ BWRITERSIO_TEX
@ BWRITERSIO_TEXREG2AR
@ BWRITERSIO_TEXLDD
@ BWRITERSIO_TEXM3x3SPEC
@ BWRITERSIO_DCL
@ BWRITERSIO_TEXM3x2DEPTH
@ BWRITERSIO_EXPP
@ BWRITERSIO_TEXCOORD
@ BWRITERSIO_MOVA
@ BWRITERSIO_ENDIF
@ BWRITERSIO_TEXREG2RGB
@ BWRITERSIO_IFC
@ BWRITERSIO_TEXBEM
@ BWRITERSIO_MAD
@ BWRITERSIO_CRS
@ BWRITERSIO_FRC
@ BWRITERSIO_LABEL
@ BWRITERSIO_SINCOS
@ BWRITERSIO_ADD
@ BWRITERSIO_M4x3
@ BWRITERSIO_M3x2
@ BWRITERSIO_TEXM3x3VSPEC
@ BWRITERSIO_TEXLDL
@ BWRITERSIO_DSY
@ BWRITERSIO_SUB
@ BWRITERSIO_TEXDP3TEX
@ BWRITERSIO_TEXDEPTH
@ BWRITERSIO_TEXKILL
@ BWRITERSIO_M4x4
@ BWRITERSIO_DP4
@ BWRITERSIO_ELSE
@ BWRITERSIO_LIT
@ BWRITERSIO_IF
@ BWRITERSIO_LOGP
@ BWRITERSIO_RET
@ BWRITERSIO_CMP
@ BWRITERSIO_DP3
@ BWRITERSIO_LOG
@ BWRITERSIO_PHASE
@ BWRITERSIO_M3x3
@ BWRITERSIO_TEXLDP
@ BWRITERSIO_REP
@ BWRITERSIO_DEFI
@ BWRITERSIO_ENDLOOP
@ BWRITERSIO_TEXM3x2TEX
@ BWRITERSIO_SETP
@ BWRITERSIO_RSQ
@ BWRITERSIO_TEXM3x3
@ BWRITERSIO_COMMENT
@ BWRITERSIO_TEXREG2GB
@ BWRITERSIO_BREAKC
@ BWRITERSIO_ABS
@ BWRITERSIO_DST
@ BWRITERSIO_SLT
@ BWRITERSIO_NOP
#define BWRITERVS_X_W
#define T2_REG
#define BWRITERVS_SWIZZLE_Y
const char * debug_print_opcode(uint32_t opcode)
Definition: utils.c:422
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
unsigned int idx
Definition: utils.c:40
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint shader
Definition: glext.h:6030
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLdouble GLdouble z
Definition: glext.h:5874
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
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
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
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 int reg
Definition: i386-dis.c:1290
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define d
Definition: ke_i.h:81
#define ZeroMemory
Definition: minwinbase.h:31
#define error(str)
Definition: mkdosfs.c:1605
#define shift
Definition: input.c:3280
#define uint32_t
Definition: nsiface.idl:61
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
#define calloc
Definition: rosglue.h:14
#define TRACE(s)
Definition: solgame.cpp:4
enum vkd3d_shader_register_type reg_type
Definition: spirv.c:4885
struct vkd3d_spirv_builtin builtin
Definition: spirv.c:4840
const struct bwriter_shader * shader
uint32_t oPos_regnum
uint32_t oPts_regnum
uint32_t oD_regnum[2]
uint32_t v_regnum[2]
uint32_t oPts_mask
uint32_t t_regnum[8]
uint32_t oFog_regnum
uint32_t oT_regnum[8]
const struct bytecode_backend * funcs
uint32_t oFog_mask
HRESULT state
const struct bytecode_backend::instr_handler_table * instructions
void(* dstreg)(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer, uint32_t shift, uint32_t mod)
void(* opcode)(struct bc_writer *writer, const struct instruction *instr, uint32_t token, struct bytecode_buffer *buffer)
void(* srcreg)(struct bc_writer *writer, const struct shader_reg *reg, struct bytecode_buffer *buffer)
unsigned int alloc_size
unsigned int size
union constant::@270 value[4]
unsigned int regnum
unsigned int num_srcs
enum bwriter_comparison_type comptype
struct shader_reg predicate
struct shader_reg * src
struct shader_reg dst
unsigned int regnum
uint32_t writemask
#define max(a, b)
Definition: svc.c:63
Definition: pdh_main.c:64