2 * Direct3D bytecode output functions
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2009 Matteo Bruni
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dx9_36_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
31 /****************************************************************
32 * General assembler shader construction helper routines follow *
33 ****************************************************************/
34 /* struct instruction *alloc_instr
36 * Allocates a new instruction structure with srcs registers
39 * srcs: Number of source registers to allocate
42 * A pointer to the allocated instruction structure
43 * NULL in case of an allocation failure
45 struct instruction *alloc_instr(unsigned int srcs) {
46 struct instruction *ret = asm_alloc(sizeof(*ret));
48 ERR("Failed to allocate memory for an instruction structure\n");
53 ret->src = asm_alloc(srcs * sizeof(*ret->src));
55 ERR("Failed to allocate memory for instruction registers\n");
64 /* void add_instruction
66 * Adds a new instruction to the shader's instructions array and grows the instruction array
69 * The function does NOT copy the instruction structure. Make sure not to release the
70 * instruction or any of its substructures like registers.
73 * shader: Shader to add the instruction to
74 * instr: Instruction to add to the shader
76 BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
77 struct instruction **new_instructions;
79 if(!shader) return FALSE;
81 if(shader->instr_alloc_size == 0) {
82 shader->instr = asm_alloc(sizeof(*shader->instr) * INSTRARRAY_INITIAL_SIZE);
84 ERR("Failed to allocate the shader instruction array\n");
87 shader->instr_alloc_size = INSTRARRAY_INITIAL_SIZE;
88 } else if(shader->instr_alloc_size == shader->num_instrs) {
89 new_instructions = asm_realloc(shader->instr,
90 sizeof(*shader->instr) * (shader->instr_alloc_size) * 2);
91 if(!new_instructions) {
92 ERR("Failed to grow the shader instruction array\n");
95 shader->instr = new_instructions;
96 shader->instr_alloc_size = shader->instr_alloc_size * 2;
97 } else if(shader->num_instrs > shader->instr_alloc_size) {
98 ERR("More instructions than allocated. This should not happen\n");
102 shader->instr[shader->num_instrs] = instr;
103 shader->num_instrs++;
107 BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w) {
108 struct constant *newconst;
111 struct constant **newarray;
112 newarray = asm_realloc(shader->constF,
113 sizeof(*shader->constF) * (shader->num_cf + 1));
115 ERR("Failed to grow the constants array\n");
118 shader->constF = newarray;
120 shader->constF = asm_alloc(sizeof(*shader->constF));
121 if(!shader->constF) {
122 ERR("Failed to allocate the constants array\n");
127 newconst = asm_alloc(sizeof(*newconst));
129 ERR("Failed to allocate a new constant\n");
132 newconst->regnum = reg;
133 newconst->value[0].f = x;
134 newconst->value[1].f = y;
135 newconst->value[2].f = z;
136 newconst->value[3].f = w;
137 shader->constF[shader->num_cf] = newconst;
143 BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask) {
145 struct declaration **decl;
148 if(!shader) return FALSE;
151 num = &shader->num_outputs;
152 decl = &shader->outputs;
154 num = &shader->num_inputs;
155 decl = &shader->inputs;
159 *decl = asm_alloc(sizeof(**decl));
161 ERR("Error allocating declarations array\n");
165 struct declaration *newdecl;
166 for(i = 0; i < *num; i++) {
167 if((*decl)[i].regnum == regnum && ((*decl)[i].writemask & writemask)) {
168 WARN("Declaration of register %u already exists, writemask match 0x%x\n",
169 regnum, (*decl)[i].writemask & writemask);
173 newdecl = asm_realloc(*decl,
174 sizeof(**decl) * ((*num) + 1));
176 ERR("Error reallocating declarations array\n");
181 (*decl)[*num].usage = usage;
182 (*decl)[*num].usage_idx = usage_idx;
183 (*decl)[*num].regnum = regnum;
184 (*decl)[*num].writemask = writemask;
190 BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum) {
193 if(!shader) return FALSE;
195 if(shader->num_samplers == 0) {
196 shader->samplers = asm_alloc(sizeof(*shader->samplers));
197 if(!shader->samplers) {
198 ERR("Error allocating samplers array\n");
202 struct samplerdecl *newarray;
204 for(i = 0; i < shader->num_samplers; i++) {
205 if(shader->samplers[i].regnum == regnum) {
206 WARN("Sampler %u already declared\n", regnum);
207 /* This is not an error as far as the assembler is concerned.
208 * Direct3D might refuse to load the compiled shader though
213 newarray = asm_realloc(shader->samplers,
214 sizeof(*shader->samplers) * (shader->num_samplers + 1));
216 ERR("Error reallocating samplers array\n");
219 shader->samplers = newarray;
222 shader->samplers[shader->num_samplers].type = samptype;
223 shader->samplers[shader->num_samplers].regnum = regnum;
224 shader->num_samplers++;
229 /* shader bytecode buffer manipulation functions.
230 * allocate_buffer creates a new buffer structure, put_dword adds a new
231 * DWORD to the buffer. In the rare case of a memory allocation failure
232 * when trying to grow the buffer a flag is set in the buffer to mark it
233 * invalid. This avoids return value checking and passing in many places
235 static struct bytecode_buffer *allocate_buffer(void) {
236 struct bytecode_buffer *ret;
238 ret = asm_alloc(sizeof(*ret));
239 if(!ret) return NULL;
241 ret->alloc_size = BYTECODEBUFFER_INITIAL_SIZE;
242 ret->data = asm_alloc(sizeof(DWORD) * ret->alloc_size);
251 static void put_dword(struct bytecode_buffer *buffer, DWORD value) {
252 if(FAILED(buffer->state)) return;
254 if(buffer->alloc_size == buffer->size) {
256 buffer->alloc_size *= 2;
257 newarray = asm_realloc(buffer->data,
258 sizeof(DWORD) * buffer->alloc_size);
260 ERR("Failed to grow the buffer data memory\n");
261 buffer->state = E_OUTOFMEMORY;
264 buffer->data = newarray;
266 buffer->data[buffer->size++] = value;
269 /******************************************************
270 * Implementation of the writer functions starts here *
271 ******************************************************/
272 static void write_declarations(struct bytecode_buffer *buffer, BOOL len,
273 const struct declaration *decls, unsigned int num, DWORD type) {
275 DWORD instr_dcl = D3DSIO_DCL;
279 instr_dcl |= 2 << D3DSI_INSTLENGTH_SHIFT;
282 for(i = 0; i < num; i++) {
283 /* Write the DCL instruction */
284 put_dword(buffer, instr_dcl);
286 /* Write the usage and index */
287 token = (1 << 31); /* Bit 31 of non-instruction opcodes is 1 */
288 token |= (decls[i].usage << D3DSP_DCL_USAGE_SHIFT) & D3DSP_DCL_USAGE_MASK;
289 token |= (decls[i].usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT) & D3DSP_DCL_USAGEINDEX_MASK;
290 put_dword(buffer, token);
292 /* Write the dest register */
293 token = (1 << 31); /* Bit 31 of non-instruction opcodes is 1 */
294 token |= (type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
295 token |= (d3d9_writemask(decls[i].writemask)) & D3DSP_WRITEMASK_ALL;
296 token |= decls[i].regnum & D3DSP_REGNUM_MASK;
297 put_dword(buffer, token);
301 static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
303 DWORD instr_def = D3DSIO_DEF;
304 const DWORD reg = (1<<31) |
305 ((D3DSPR_CONST << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) |
309 instr_def |= 5 << D3DSI_INSTLENGTH_SHIFT;
312 for(i = 0; i < shader->num_cf; i++) {
313 /* Write the DEF instruction */
314 put_dword(buffer, instr_def);
316 put_dword(buffer, reg | (shader->constF[i]->regnum & D3DSP_REGNUM_MASK));
317 put_dword(buffer, shader->constF[i]->value[0].d);
318 put_dword(buffer, shader->constF[i]->value[1].d);
319 put_dword(buffer, shader->constF[i]->value[2].d);
320 put_dword(buffer, shader->constF[i]->value[3].d);
324 static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
325 put_dword(buffer, D3DSIO_END);
328 static void write_srcregs(struct bc_writer *This, const struct instruction *instr,
329 struct bytecode_buffer *buffer){
331 if(instr->has_predicate){
332 This->funcs->srcreg(This, &instr->predicate, buffer);
334 for(i = 0; i < instr->num_srcs; i++){
335 This->funcs->srcreg(This, &instr->src[i], buffer);
339 /* The length of an instruction consists of the destination register (if any),
340 * the number of source registers, the number of address registers used for
341 * indirect addressing, and optionally the predicate register
343 static DWORD instrlen(const struct instruction *instr, unsigned int srcs, unsigned int dsts) {
345 DWORD ret = srcs + dsts + (instr->has_predicate ? 1 : 0);
348 if(instr->dst.rel_reg) ret++;
350 for(i = 0; i < srcs; i++) {
351 if(instr->src[i].rel_reg) ret++;
356 static void instr_handler(struct bc_writer *This,
357 const struct instruction *instr,
358 struct bytecode_buffer *buffer) {
359 DWORD token = d3d9_opcode(instr->opcode);
360 TRACE("token: %x\n", token);
362 This->funcs->opcode(This, instr, token, buffer);
363 if(instr->has_dst) This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
364 write_srcregs(This, instr, buffer);
367 static void sm_2_opcode(struct bc_writer *This,
368 const struct instruction *instr,
369 DWORD token, struct bytecode_buffer *buffer) {
370 /* From sm 2 onwards instruction length is encoded in the opcode field */
371 int dsts = instr->has_dst ? 1 : 0;
372 token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
374 token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
375 if(instr->has_predicate)
376 token |= D3DSHADER_INSTRUCTION_PREDICATED;
377 put_dword(buffer,token);
380 static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
382 DWORD instr_dcl = D3DSIO_DCL | (2 << D3DSI_INSTLENGTH_SHIFT);
384 const DWORD reg = (1<<31) |
385 ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) |
386 ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2) |
389 for(i = 0; i < shader->num_samplers; i++) {
390 /* Write the DCL instruction */
391 put_dword(buffer, instr_dcl);
393 /* Already shifted */
394 token |= (d3d9_sampler(shader->samplers[i].type)) & D3DSP_TEXTURETYPE_MASK;
395 put_dword(buffer, token);
396 put_dword(buffer, reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK));
400 static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
401 /* Declare the shader type and version */
402 put_dword(buffer, This->version);
404 write_declarations(buffer, TRUE, shader->inputs, shader->num_inputs, D3DSPR_INPUT);
405 write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
406 write_constF(shader, buffer, TRUE);
407 write_samplers(shader, buffer);
411 static void sm_3_srcreg(struct bc_writer *This,
412 const struct shader_reg *reg,
413 struct bytecode_buffer *buffer) {
414 DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
417 d3d9reg = d3d9_register(reg->type);
418 token |= (d3d9reg << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
419 token |= (d3d9reg << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2;
420 token |= reg->regnum & D3DSP_REGNUM_MASK;
422 token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK;
423 token |= d3d9_srcmod(reg->srcmod);
426 if(reg->type == BWRITERSPR_CONST && This->version == BWRITERPS_VERSION(3, 0)) {
427 WARN("c%u[...] is unsupported in ps_3_0\n", reg->regnum);
428 This->state = E_INVALIDARG;
431 if(((reg->rel_reg->type == BWRITERSPR_ADDR && This->version == BWRITERVS_VERSION(3, 0)) ||
432 reg->rel_reg->type == BWRITERSPR_LOOP) &&
433 reg->rel_reg->regnum == 0) {
434 token |= D3DVS_ADDRMODE_RELATIVE & D3DVS_ADDRESSMODE_MASK;
436 WARN("Unsupported relative addressing register\n");
437 This->state = E_INVALIDARG;
442 put_dword(buffer, token);
444 /* vs_2_0 and newer write the register containing the index explicitly in the
447 if(token & D3DVS_ADDRMODE_RELATIVE) {
448 sm_3_srcreg(This, reg->rel_reg, buffer);
452 static void sm_3_dstreg(struct bc_writer *This,
453 const struct shader_reg *reg,
454 struct bytecode_buffer *buffer,
455 DWORD shift, DWORD mod) {
456 DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
460 if(This->version == BWRITERVS_VERSION(3, 0) &&
461 reg->type == BWRITERSPR_OUTPUT) {
462 token |= D3DVS_ADDRMODE_RELATIVE & D3DVS_ADDRESSMODE_MASK;
464 WARN("Relative addressing not supported for this shader type or register type\n");
465 This->state = E_INVALIDARG;
470 d3d9reg = d3d9_register(reg->type);
471 token |= (d3d9reg << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
472 token |= (d3d9reg << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2;
473 token |= reg->regnum & D3DSP_REGNUM_MASK; /* No shift */
475 token |= d3d9_dstmod(mod);
477 token |= d3d9_writemask(reg->writemask);
478 put_dword(buffer, token);
480 /* vs_2_0 and newer write the register containing the index explicitly in the
483 if(token & D3DVS_ADDRMODE_RELATIVE) {
484 sm_3_srcreg(This, reg->rel_reg, buffer);
488 static const struct instr_handler_table vs_3_handlers[] = {
489 {BWRITERSIO_ADD, instr_handler},
490 {BWRITERSIO_NOP, instr_handler},
491 {BWRITERSIO_MOV, instr_handler},
492 {BWRITERSIO_SUB, instr_handler},
493 {BWRITERSIO_MAD, instr_handler},
494 {BWRITERSIO_MUL, instr_handler},
495 {BWRITERSIO_RCP, instr_handler},
496 {BWRITERSIO_RSQ, instr_handler},
497 {BWRITERSIO_DP3, instr_handler},
498 {BWRITERSIO_DP4, instr_handler},
499 {BWRITERSIO_MIN, instr_handler},
500 {BWRITERSIO_MAX, instr_handler},
501 {BWRITERSIO_SLT, instr_handler},
502 {BWRITERSIO_SGE, instr_handler},
503 {BWRITERSIO_ABS, instr_handler},
504 {BWRITERSIO_EXP, instr_handler},
505 {BWRITERSIO_LOG, instr_handler},
506 {BWRITERSIO_EXPP, instr_handler},
507 {BWRITERSIO_LOGP, instr_handler},
508 {BWRITERSIO_DST, instr_handler},
509 {BWRITERSIO_LRP, instr_handler},
510 {BWRITERSIO_FRC, instr_handler},
511 {BWRITERSIO_CRS, instr_handler},
512 {BWRITERSIO_SGN, instr_handler},
513 {BWRITERSIO_NRM, instr_handler},
514 {BWRITERSIO_SINCOS, instr_handler},
515 {BWRITERSIO_M4x4, instr_handler},
516 {BWRITERSIO_M4x3, instr_handler},
517 {BWRITERSIO_M3x4, instr_handler},
518 {BWRITERSIO_M3x3, instr_handler},
519 {BWRITERSIO_M3x2, instr_handler},
520 {BWRITERSIO_LIT, instr_handler},
521 {BWRITERSIO_POW, instr_handler},
522 {BWRITERSIO_MOVA, instr_handler},
524 {BWRITERSIO_CALL, instr_handler},
525 {BWRITERSIO_CALLNZ, instr_handler},
526 {BWRITERSIO_REP, instr_handler},
527 {BWRITERSIO_ENDREP, instr_handler},
528 {BWRITERSIO_IF, instr_handler},
529 {BWRITERSIO_LABEL, instr_handler},
530 {BWRITERSIO_IFC, instr_handler},
531 {BWRITERSIO_ELSE, instr_handler},
532 {BWRITERSIO_ENDIF, instr_handler},
533 {BWRITERSIO_BREAK, instr_handler},
534 {BWRITERSIO_BREAKC, instr_handler},
535 {BWRITERSIO_LOOP, instr_handler},
536 {BWRITERSIO_RET, instr_handler},
537 {BWRITERSIO_ENDLOOP, instr_handler},
539 {BWRITERSIO_SETP, instr_handler},
540 {BWRITERSIO_BREAKP, instr_handler},
541 {BWRITERSIO_TEXLDL, instr_handler},
543 {BWRITERSIO_END, NULL},
546 static const struct bytecode_backend vs_3_backend = {
555 static void init_vs30_dx9_writer(struct bc_writer *writer) {
556 TRACE("Creating DirectX9 vertex shader 3.0 writer\n");
557 writer->funcs = &vs_3_backend;
560 static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
561 struct bc_writer *ret = asm_alloc(sizeof(*ret));
564 WARN("Failed to allocate a bytecode writer instance\n");
569 case BWRITERVS_VERSION(1, 0):
571 WARN("Unsupported dxversion for vertex shader 1.0 requested: %u\n", dxversion);
574 /* TODO: Set the appropriate writer backend */
576 case BWRITERVS_VERSION(1, 1):
578 WARN("Unsupported dxversion for vertex shader 1.1 requested: %u\n", dxversion);
581 /* TODO: Set the appropriate writer backend */
583 case BWRITERVS_VERSION(2, 0):
585 WARN("Unsupported dxversion for vertex shader 2.0 requested: %u\n", dxversion);
588 /* TODO: Set the appropriate writer backend */
590 case BWRITERVS_VERSION(2, 1):
592 WARN("Unsupported dxversion for vertex shader 2.x requested: %u\n", dxversion);
595 /* TODO: Set the appropriate writer backend */
597 case BWRITERVS_VERSION(3, 0):
599 WARN("Unsupported dxversion for vertex shader 3.0 requested: %u\n", dxversion);
602 init_vs30_dx9_writer(ret);
605 case BWRITERPS_VERSION(1, 0):
607 WARN("Unsupported dxversion for pixel shader 1.0 requested: %u\n", dxversion);
610 /* TODO: Set the appropriate writer backend */
612 case BWRITERPS_VERSION(1, 1):
614 WARN("Unsupported dxversion for pixel shader 1.1 requested: %u\n", dxversion);
617 /* TODO: Set the appropriate writer backend */
619 case BWRITERPS_VERSION(1, 2):
621 WARN("Unsupported dxversion for pixel shader 1.2 requested: %u\n", dxversion);
624 /* TODO: Set the appropriate writer backend */
626 case BWRITERPS_VERSION(1, 3):
628 WARN("Unsupported dxversion for pixel shader 1.3 requested: %u\n", dxversion);
631 /* TODO: Set the appropriate writer backend */
633 case BWRITERPS_VERSION(1, 4):
635 WARN("Unsupported dxversion for pixel shader 1.4 requested: %u\n", dxversion);
638 /* TODO: Set the appropriate writer backend */
641 case BWRITERPS_VERSION(2, 0):
643 WARN("Unsupported dxversion for pixel shader 2.0 requested: %u\n", dxversion);
646 /* TODO: Set the appropriate writer backend */
649 case BWRITERPS_VERSION(2, 1):
651 WARN("Unsupported dxversion for pixel shader 2.x requested: %u\n", dxversion);
654 /* TODO: Set the appropriate writer backend */
657 case BWRITERPS_VERSION(3, 0):
659 WARN("Unsupported dxversion for pixel shader 3.0 requested: %u\n", dxversion);
662 /* TODO: Set the appropriate writer backend */
666 WARN("Unexpected shader version requested: %08x\n", version);
669 ret->version = version;
677 static HRESULT call_instr_handler(struct bc_writer *writer,
678 const struct instruction *instr,
679 struct bytecode_buffer *buffer) {
682 while(writer->funcs->instructions[i].opcode != BWRITERSIO_END) {
683 if(instr->opcode == writer->funcs->instructions[i].opcode) {
684 if(!writer->funcs->instructions[i].func) {
685 WARN("Opcode %u not supported by this profile\n", instr->opcode);
688 writer->funcs->instructions[i].func(writer, instr, buffer);
694 FIXME("Unhandled instruction %u\n", instr->opcode);
698 /* SlWriteBytecode (wineshader.@)
700 * Writes shader version specific bytecode from the shader passed in.
701 * The returned bytecode can be passed to the Direct3D runtime like
702 * IDirect3DDevice9::Create*Shader.
705 * shader: Shader to translate into bytecode
706 * version: Shader version to generate(d3d version token)
707 * dxversion: DirectX version the code targets
708 * result: the resulting shader bytecode
713 DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result) {
714 struct bc_writer *writer;
715 struct bytecode_buffer *buffer = NULL;
720 ERR("NULL shader structure, aborting\n");
723 writer = create_writer(shader->version, dxversion);
727 WARN("Could not create a bytecode writer instance. Either unsupported version\n");
728 WARN("or out of memory\n");
733 buffer = allocate_buffer();
735 WARN("Failed to allocate a buffer for the shader bytecode\n");
740 writer->funcs->header(writer, shader, buffer);
741 if(FAILED(writer->state)) {
746 for(i = 0; i < shader->num_instrs; i++) {
747 hr = call_instr_handler(writer, shader->instr[i], buffer);
753 if(FAILED(writer->state)) {
758 writer->funcs->end(writer, shader, buffer);
760 if(FAILED(buffer->state)) {
765 /* Cut off unneeded memory from the result buffer */
766 *result = asm_realloc(buffer->data,
767 sizeof(DWORD) * buffer->size);
769 *result = buffer->data;
776 asm_free(buffer->data);
783 void SlDeleteShader(struct bwriter_shader *shader) {
786 TRACE("Deleting shader %p\n", shader);
788 for(i = 0; i < shader->num_cf; i++) {
789 asm_free(shader->constF[i]);
791 asm_free(shader->constF);
792 for(i = 0; i < shader->num_ci; i++) {
793 asm_free(shader->constI[i]);
795 asm_free(shader->constI);
796 for(i = 0; i < shader->num_cb; i++) {
797 asm_free(shader->constB[i]);
799 asm_free(shader->constB);
801 asm_free(shader->inputs);
802 asm_free(shader->outputs);
803 asm_free(shader->samplers);
805 for(i = 0; i < shader->num_instrs; i++) {
806 for(j = 0; j < shader->instr[i]->num_srcs; j++) {
807 asm_free(shader->instr[i]->src[j].rel_reg);
809 asm_free(shader->instr[i]->src);
810 asm_free(shader->instr[i]);
812 asm_free(shader->instr);