1 /*
2  * Copyright 2008 Stefan Dösinger
3  * Copyright 2009 Matteo Bruni
4  * Copyright 2008-2009 Henri Verbeet for CodeWeavers
5  * Copyright 2010 Rico Schüller
6  * Copyright 2012 Matteo Bruni for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  *
22  */
23 
24 #include <stdio.h>
25 
26 #include "d3dcompiler_private.h"
27 
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
29 
30 #define WINE_D3DCOMPILER_TO_STR(x) case x: return #x
31 
32 const char *debug_d3dcompiler_shader_variable_class(D3D_SHADER_VARIABLE_CLASS c)
33 {
34     switch (c)
35     {
36         WINE_D3DCOMPILER_TO_STR(D3D_SVC_SCALAR);
37         WINE_D3DCOMPILER_TO_STR(D3D_SVC_VECTOR);
38         WINE_D3DCOMPILER_TO_STR(D3D_SVC_MATRIX_ROWS);
39         WINE_D3DCOMPILER_TO_STR(D3D_SVC_MATRIX_COLUMNS);
40         WINE_D3DCOMPILER_TO_STR(D3D_SVC_OBJECT);
41         WINE_D3DCOMPILER_TO_STR(D3D_SVC_STRUCT);
42         WINE_D3DCOMPILER_TO_STR(D3D_SVC_INTERFACE_CLASS);
43         WINE_D3DCOMPILER_TO_STR(D3D_SVC_INTERFACE_POINTER);
44         default:
45             FIXME("Unrecognized D3D_SHADER_VARIABLE_CLASS %#x.\n", c);
46             return "unrecognized";
47     }
48 }
49 
50 const char *debug_d3dcompiler_shader_variable_type(D3D_SHADER_VARIABLE_TYPE t)
51 {
52     switch (t)
53     {
54         WINE_D3DCOMPILER_TO_STR(D3D_SVT_VOID);
55         WINE_D3DCOMPILER_TO_STR(D3D_SVT_BOOL);
56         WINE_D3DCOMPILER_TO_STR(D3D_SVT_INT);
57         WINE_D3DCOMPILER_TO_STR(D3D_SVT_FLOAT);
58         WINE_D3DCOMPILER_TO_STR(D3D_SVT_STRING);
59         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE);
60         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE1D);
61         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE2D);
62         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE3D);
63         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURECUBE);
64         WINE_D3DCOMPILER_TO_STR(D3D_SVT_SAMPLER);
65         WINE_D3DCOMPILER_TO_STR(D3D_SVT_PIXELSHADER);
66         WINE_D3DCOMPILER_TO_STR(D3D_SVT_VERTEXSHADER);
67         WINE_D3DCOMPILER_TO_STR(D3D_SVT_UINT);
68         WINE_D3DCOMPILER_TO_STR(D3D_SVT_UINT8);
69         WINE_D3DCOMPILER_TO_STR(D3D_SVT_GEOMETRYSHADER);
70         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RASTERIZER);
71         WINE_D3DCOMPILER_TO_STR(D3D_SVT_DEPTHSTENCIL);
72         WINE_D3DCOMPILER_TO_STR(D3D_SVT_BLEND);
73         WINE_D3DCOMPILER_TO_STR(D3D_SVT_BUFFER);
74         WINE_D3DCOMPILER_TO_STR(D3D_SVT_CBUFFER);
75         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TBUFFER);
76         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE1DARRAY);
77         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE2DARRAY);
78         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RENDERTARGETVIEW);
79         WINE_D3DCOMPILER_TO_STR(D3D_SVT_DEPTHSTENCILVIEW);
80         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE2DMS);
81         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURE2DMSARRAY);
82         WINE_D3DCOMPILER_TO_STR(D3D_SVT_TEXTURECUBEARRAY);
83         WINE_D3DCOMPILER_TO_STR(D3D_SVT_HULLSHADER);
84         WINE_D3DCOMPILER_TO_STR(D3D_SVT_DOMAINSHADER);
85         WINE_D3DCOMPILER_TO_STR(D3D_SVT_INTERFACE_POINTER);
86         WINE_D3DCOMPILER_TO_STR(D3D_SVT_COMPUTESHADER);
87         WINE_D3DCOMPILER_TO_STR(D3D_SVT_DOUBLE);
88         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWTEXTURE1D);
89         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWTEXTURE1DARRAY);
90         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWTEXTURE2D);
91         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWTEXTURE2DARRAY);
92         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWTEXTURE3D);
93         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWBUFFER);
94         WINE_D3DCOMPILER_TO_STR(D3D_SVT_BYTEADDRESS_BUFFER);
95         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWBYTEADDRESS_BUFFER);
96         WINE_D3DCOMPILER_TO_STR(D3D_SVT_STRUCTURED_BUFFER);
97         WINE_D3DCOMPILER_TO_STR(D3D_SVT_RWSTRUCTURED_BUFFER);
98         WINE_D3DCOMPILER_TO_STR(D3D_SVT_APPEND_STRUCTURED_BUFFER);
99         WINE_D3DCOMPILER_TO_STR(D3D_SVT_CONSUME_STRUCTURED_BUFFER);
100         default:
101             FIXME("Unrecognized D3D_SHADER_VARIABLE_TYPE %#x.\n", t);
102             return "unrecognized";
103     }
104 }
105 
106 const char *debug_d3dcompiler_d3d_blob_part(D3D_BLOB_PART part)
107 {
108     switch(part)
109     {
110         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_SIGNATURE_BLOB);
111         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_OUTPUT_SIGNATURE_BLOB);
112         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB);
113         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB);
114         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_ALL_SIGNATURE_BLOB);
115         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_DEBUG_INFO);
116         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_LEGACY_SHADER);
117         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_PREPASS_SHADER);
118         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_XNA_SHADER);
119         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_ALTERNATE_SHADER);
120         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_DETAILS);
121         WINE_D3DCOMPILER_TO_STR(D3D_BLOB_TEST_COMPILE_PERF);
122         default:
123             FIXME("Unrecognized D3D_BLOB_PART %#x\n", part);
124             return "unrecognized";
125     }
126 }
127 
128 const char *debug_print_srcmod(DWORD mod)
129 {
130     switch (mod)
131     {
132         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_NEG);
133         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_BIAS);
134         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_BIASNEG);
135         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_SIGN);
136         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_SIGNNEG);
137         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_COMP);
138         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_X2);
139         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_X2NEG);
140         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_DZ);
141         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_DW);
142         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_ABS);
143         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_ABSNEG);
144         WINE_D3DCOMPILER_TO_STR(BWRITERSPSM_NOT);
145         default:
146             FIXME("Unrecognized source modifier %#x.\n", mod);
147             return "unrecognized_src_mod";
148     }
149 }
150 
151 #undef WINE_D3DCOMPILER_TO_STR
152 
153 const char *debug_print_dstmod(DWORD mod)
154 {
155     switch (mod)
156     {
157         case 0:
158             return "";
159         case BWRITERSPDM_SATURATE:
160             return "_sat";
161         case BWRITERSPDM_PARTIALPRECISION:
162             return "_pp";
163         case BWRITERSPDM_MSAMPCENTROID:
164             return "_centroid";
165         case BWRITERSPDM_SATURATE | BWRITERSPDM_PARTIALPRECISION:
166             return "_sat_pp";
167         case BWRITERSPDM_SATURATE | BWRITERSPDM_MSAMPCENTROID:
168             return "_sat_centroid";
169         case BWRITERSPDM_PARTIALPRECISION | BWRITERSPDM_MSAMPCENTROID:
170             return "_pp_centroid";
171         case BWRITERSPDM_SATURATE | BWRITERSPDM_PARTIALPRECISION | BWRITERSPDM_MSAMPCENTROID:
172             return "_sat_pp_centroid";
173         default:
174             return "Unexpected modifier\n";
175     }
176 }
177 
178 const char *debug_print_shift(DWORD shift)
179 {
180     static const char * const shiftstrings[] =
181     {
182         "",
183         "_x2",
184         "_x4",
185         "_x8",
186         "_x16",
187         "_x32",
188         "",
189         "",
190         "",
191         "",
192         "",
193         "",
194         "_d16",
195         "_d8",
196         "_d4",
197         "_d2",
198     };
199     return shiftstrings[shift];
200 }
201 
202 static const char *get_regname(const struct shader_reg *reg)
203 {
204     switch (reg->type)
205     {
206         case BWRITERSPR_TEMP:
207             return wine_dbg_sprintf("r%u", reg->regnum);
208         case BWRITERSPR_INPUT:
209             return wine_dbg_sprintf("v%u", reg->regnum);
210         case BWRITERSPR_CONST:
211             return wine_dbg_sprintf("c%u", reg->regnum);
212         case BWRITERSPR_ADDR:
213             return wine_dbg_sprintf("a%u", reg->regnum);
214         case BWRITERSPR_TEXTURE:
215             return wine_dbg_sprintf("t%u", reg->regnum);
216         case BWRITERSPR_RASTOUT:
217             switch (reg->regnum)
218             {
219                 case BWRITERSRO_POSITION:   return "oPos";
220                 case BWRITERSRO_FOG:        return "oFog";
221                 case BWRITERSRO_POINT_SIZE: return "oPts";
222                 default: return "Unexpected RASTOUT";
223             }
224         case BWRITERSPR_ATTROUT:
225             return wine_dbg_sprintf("oD%u", reg->regnum);
226         case BWRITERSPR_TEXCRDOUT:
227             return wine_dbg_sprintf("oT%u", reg->regnum);
228         case BWRITERSPR_OUTPUT:
229             return wine_dbg_sprintf("o%u", reg->regnum);
230         case BWRITERSPR_CONSTINT:
231             return wine_dbg_sprintf("i%u", reg->regnum);
232         case BWRITERSPR_COLOROUT:
233             return wine_dbg_sprintf("oC%u", reg->regnum);
234         case BWRITERSPR_DEPTHOUT:
235             return "oDepth";
236         case BWRITERSPR_SAMPLER:
237             return wine_dbg_sprintf("s%u", reg->regnum);
238         case BWRITERSPR_CONSTBOOL:
239             return wine_dbg_sprintf("b%u", reg->regnum);
240         case BWRITERSPR_LOOP:
241             return "aL";
242         case BWRITERSPR_MISCTYPE:
243             switch (reg->regnum)
244             {
245                 case 0: return "vPos";
246                 case 1: return "vFace";
247                 default: return "unexpected misctype";
248             }
249         case BWRITERSPR_LABEL:
250             return wine_dbg_sprintf("l%u", reg->regnum);
251         case BWRITERSPR_PREDICATE:
252             return wine_dbg_sprintf("p%u", reg->regnum);
253         default:
254             return wine_dbg_sprintf("unknown regname %#x", reg->type);
255     }
256 }
257 
258 static const char *debug_print_writemask(DWORD mask)
259 {
260     char ret[6];
261     unsigned char pos = 1;
262 
263     if(mask == BWRITERSP_WRITEMASK_ALL) return "";
264     ret[0] = '.';
265     if(mask & BWRITERSP_WRITEMASK_0) ret[pos++] = 'x';
266     if(mask & BWRITERSP_WRITEMASK_1) ret[pos++] = 'y';
267     if(mask & BWRITERSP_WRITEMASK_2) ret[pos++] = 'z';
268     if(mask & BWRITERSP_WRITEMASK_3) ret[pos++] = 'w';
269     ret[pos] = 0;
270 
271     return wine_dbg_sprintf("%s", ret);
272 }
273 
274 static const char *debug_print_swizzle(DWORD arg)
275 {
276     char ret[6];
277     unsigned int i;
278     DWORD swizzle[4];
279 
280     switch (arg)
281     {
282         case BWRITERVS_NOSWIZZLE:
283             return "";
284         case BWRITERVS_SWIZZLE_X:
285             return ".x";
286         case BWRITERVS_SWIZZLE_Y:
287             return ".y";
288         case BWRITERVS_SWIZZLE_Z:
289             return ".z";
290         case BWRITERVS_SWIZZLE_W:
291             return ".w";
292     }
293 
294     swizzle[0] = (arg >> (BWRITERVS_SWIZZLE_SHIFT + 0)) & 0x03;
295     swizzle[1] = (arg >> (BWRITERVS_SWIZZLE_SHIFT + 2)) & 0x03;
296     swizzle[2] = (arg >> (BWRITERVS_SWIZZLE_SHIFT + 4)) & 0x03;
297     swizzle[3] = (arg >> (BWRITERVS_SWIZZLE_SHIFT + 6)) & 0x03;
298 
299     ret[0] = '.';
300     for (i = 0; i < 4; ++i)
301     {
302         switch (swizzle[i])
303         {
304             case 0: ret[1 + i] = 'x'; break;
305             case 1: ret[1 + i] = 'y'; break;
306             case 2: ret[1 + i] = 'z'; break;
307             case 3: ret[1 + i] = 'w'; break;
308         }
309     }
310     ret[5] = '\0';
311 
312     return wine_dbg_sprintf("%s", ret);
313 }
314 
315 static const char *debug_print_relarg(const struct shader_reg *reg)
316 {
317     const char *short_swizzle;
318     if (!reg->rel_reg) return "";
319 
320     short_swizzle = debug_print_swizzle(reg->rel_reg->u.swizzle);
321 
322     if (reg->rel_reg->type == BWRITERSPR_ADDR)
323         return wine_dbg_sprintf("[a%u%s]", reg->rel_reg->regnum, short_swizzle);
324     else if(reg->rel_reg->type == BWRITERSPR_LOOP && reg->rel_reg->regnum == 0)
325         return wine_dbg_sprintf("[aL%s]", short_swizzle);
326     else
327         return "Unexpected relative addressing argument";
328 }
329 
330 const char *debug_print_dstreg(const struct shader_reg *reg)
331 {
332     return wine_dbg_sprintf("%s%s%s", get_regname(reg),
333             debug_print_relarg(reg),
334             debug_print_writemask(reg->u.writemask));
335 }
336 
337 const char *debug_print_srcreg(const struct shader_reg *reg)
338 {
339     switch (reg->srcmod)
340     {
341         case BWRITERSPSM_NONE:
342             return wine_dbg_sprintf("%s%s%s", get_regname(reg),
343                     debug_print_relarg(reg),
344                     debug_print_swizzle(reg->u.swizzle));
345         case BWRITERSPSM_NEG:
346             return wine_dbg_sprintf("-%s%s%s", get_regname(reg),
347                     debug_print_relarg(reg),
348                     debug_print_swizzle(reg->u.swizzle));
349         case BWRITERSPSM_BIAS:
350             return wine_dbg_sprintf("%s%s_bias%s", get_regname(reg),
351                     debug_print_relarg(reg),
352                     debug_print_swizzle(reg->u.swizzle));
353         case BWRITERSPSM_BIASNEG:
354             return wine_dbg_sprintf("-%s%s_bias%s", get_regname(reg),
355                     debug_print_relarg(reg),
356                     debug_print_swizzle(reg->u.swizzle));
357         case BWRITERSPSM_SIGN:
358             return wine_dbg_sprintf("%s%s_bx2%s", get_regname(reg),
359                     debug_print_relarg(reg),
360                     debug_print_swizzle(reg->u.swizzle));
361         case BWRITERSPSM_SIGNNEG:
362             return wine_dbg_sprintf("-%s%s_bx2%s", get_regname(reg),
363                     debug_print_relarg(reg),
364                     debug_print_swizzle(reg->u.swizzle));
365         case BWRITERSPSM_COMP:
366             return wine_dbg_sprintf("1 - %s%s%s", get_regname(reg),
367                     debug_print_relarg(reg),
368                     debug_print_swizzle(reg->u.swizzle));
369         case BWRITERSPSM_X2:
370             return wine_dbg_sprintf("%s%s_x2%s", get_regname(reg),
371                     debug_print_relarg(reg),
372                     debug_print_swizzle(reg->u.swizzle));
373         case BWRITERSPSM_X2NEG:
374             return wine_dbg_sprintf("-%s%s_x2%s", get_regname(reg),
375                     debug_print_relarg(reg),
376                     debug_print_swizzle(reg->u.swizzle));
377         case BWRITERSPSM_DZ:
378             return wine_dbg_sprintf("%s%s_dz%s", get_regname(reg),
379                     debug_print_relarg(reg),
380                     debug_print_swizzle(reg->u.swizzle));
381         case BWRITERSPSM_DW:
382             return wine_dbg_sprintf("%s%s_dw%s", get_regname(reg),
383                     debug_print_relarg(reg),
384                     debug_print_swizzle(reg->u.swizzle));
385         case BWRITERSPSM_ABS:
386             return wine_dbg_sprintf("%s%s_abs%s", get_regname(reg),
387                     debug_print_relarg(reg),
388                     debug_print_swizzle(reg->u.swizzle));
389         case BWRITERSPSM_ABSNEG:
390             return wine_dbg_sprintf("-%s%s_abs%s", get_regname(reg),
391                     debug_print_relarg(reg),
392                     debug_print_swizzle(reg->u.swizzle));
393         case BWRITERSPSM_NOT:
394             return wine_dbg_sprintf("!%s%s%s", get_regname(reg),
395                     debug_print_relarg(reg),
396                     debug_print_swizzle(reg->u.swizzle));
397     }
398     return "Unknown modifier";
399 }
400 
401 const char *debug_print_comp(DWORD comp)
402 {
403     switch (comp)
404     {
405         case BWRITER_COMPARISON_NONE: return "";
406         case BWRITER_COMPARISON_GT:   return "_gt";
407         case BWRITER_COMPARISON_EQ:   return "_eq";
408         case BWRITER_COMPARISON_GE:   return "_ge";
409         case BWRITER_COMPARISON_LT:   return "_lt";
410         case BWRITER_COMPARISON_NE:   return "_ne";
411         case BWRITER_COMPARISON_LE:   return "_le";
412         default: return "_unknown";
413     }
414 }
415 
416 const char *debug_print_opcode(DWORD opcode)
417 {
418     switch (opcode)
419     {
420         case BWRITERSIO_NOP:          return "nop";
421         case BWRITERSIO_MOV:          return "mov";
422         case BWRITERSIO_ADD:          return "add";
423         case BWRITERSIO_SUB:          return "sub";
424         case BWRITERSIO_MAD:          return "mad";
425         case BWRITERSIO_MUL:          return "mul";
426         case BWRITERSIO_RCP:          return "rcp";
427         case BWRITERSIO_RSQ:          return "rsq";
428         case BWRITERSIO_DP3:          return "dp3";
429         case BWRITERSIO_DP4:          return "dp4";
430         case BWRITERSIO_MIN:          return "min";
431         case BWRITERSIO_MAX:          return "max";
432         case BWRITERSIO_SLT:          return "slt";
433         case BWRITERSIO_SGE:          return "sge";
434         case BWRITERSIO_EXP:          return "exp";
435         case BWRITERSIO_LOG:          return "log";
436         case BWRITERSIO_LIT:          return "lit";
437         case BWRITERSIO_DST:          return "dst";
438         case BWRITERSIO_LRP:          return "lrp";
439         case BWRITERSIO_FRC:          return "frc";
440         case BWRITERSIO_M4x4:         return "m4x4";
441         case BWRITERSIO_M4x3:         return "m4x3";
442         case BWRITERSIO_M3x4:         return "m3x4";
443         case BWRITERSIO_M3x3:         return "m3x3";
444         case BWRITERSIO_M3x2:         return "m3x2";
445         case BWRITERSIO_CALL:         return "call";
446         case BWRITERSIO_CALLNZ:       return "callnz";
447         case BWRITERSIO_LOOP:         return "loop";
448         case BWRITERSIO_RET:          return "ret";
449         case BWRITERSIO_ENDLOOP:      return "endloop";
450         case BWRITERSIO_LABEL:        return "label";
451         case BWRITERSIO_DCL:          return "dcl";
452         case BWRITERSIO_POW:          return "pow";
453         case BWRITERSIO_CRS:          return "crs";
454         case BWRITERSIO_SGN:          return "sgn";
455         case BWRITERSIO_ABS:          return "abs";
456         case BWRITERSIO_NRM:          return "nrm";
457         case BWRITERSIO_SINCOS:       return "sincos";
458         case BWRITERSIO_REP:          return "rep";
459         case BWRITERSIO_ENDREP:       return "endrep";
460         case BWRITERSIO_IF:           return "if";
461         case BWRITERSIO_IFC:          return "ifc";
462         case BWRITERSIO_ELSE:         return "else";
463         case BWRITERSIO_ENDIF:        return "endif";
464         case BWRITERSIO_BREAK:        return "break";
465         case BWRITERSIO_BREAKC:       return "breakc";
466         case BWRITERSIO_MOVA:         return "mova";
467         case BWRITERSIO_DEFB:         return "defb";
468         case BWRITERSIO_DEFI:         return "defi";
469         case BWRITERSIO_TEXCOORD:     return "texcoord";
470         case BWRITERSIO_TEXKILL:      return "texkill";
471         case BWRITERSIO_TEX:          return "tex";
472         case BWRITERSIO_TEXBEM:       return "texbem";
473         case BWRITERSIO_TEXBEML:      return "texbeml";
474         case BWRITERSIO_TEXREG2AR:    return "texreg2ar";
475         case BWRITERSIO_TEXREG2GB:    return "texreg2gb";
476         case BWRITERSIO_TEXM3x2PAD:   return "texm3x2pad";
477         case BWRITERSIO_TEXM3x2TEX:   return "texm3x2tex";
478         case BWRITERSIO_TEXM3x3PAD:   return "texm3x3pad";
479         case BWRITERSIO_TEXM3x3TEX:   return "texm3x3tex";
480         case BWRITERSIO_TEXM3x3SPEC:  return "texm3x3vspec";
481         case BWRITERSIO_TEXM3x3VSPEC: return "texm3x3vspec";
482         case BWRITERSIO_EXPP:         return "expp";
483         case BWRITERSIO_LOGP:         return "logp";
484         case BWRITERSIO_CND:          return "cnd";
485         case BWRITERSIO_DEF:          return "def";
486         case BWRITERSIO_TEXREG2RGB:   return "texreg2rgb";
487         case BWRITERSIO_TEXDP3TEX:    return "texdp3tex";
488         case BWRITERSIO_TEXM3x2DEPTH: return "texm3x2depth";
489         case BWRITERSIO_TEXDP3:       return "texdp3";
490         case BWRITERSIO_TEXM3x3:      return "texm3x3";
491         case BWRITERSIO_TEXDEPTH:     return "texdepth";
492         case BWRITERSIO_CMP:          return "cmp";
493         case BWRITERSIO_BEM:          return "bem";
494         case BWRITERSIO_DP2ADD:       return "dp2add";
495         case BWRITERSIO_DSX:          return "dsx";
496         case BWRITERSIO_DSY:          return "dsy";
497         case BWRITERSIO_TEXLDD:       return "texldd";
498         case BWRITERSIO_SETP:         return "setp";
499         case BWRITERSIO_TEXLDL:       return "texldl";
500         case BWRITERSIO_BREAKP:       return "breakp";
501         case BWRITERSIO_PHASE:        return "phase";
502 
503         case BWRITERSIO_TEXLDP:       return "texldp";
504         case BWRITERSIO_TEXLDB:       return "texldb";
505 
506         default:                      return "unknown";
507     }
508 }
509 
510 void skip_dword_unknown(const char **ptr, unsigned int count)
511 {
512     unsigned int i;
513     DWORD d;
514 
515     FIXME("Skipping %u unknown DWORDs:\n", count);
516     for (i = 0; i < count; ++i)
517     {
518         read_dword(ptr, &d);
519         FIXME("\t0x%08x\n", d);
520     }
521 }
522 
523 static void write_dword_unknown(char **ptr, DWORD d)
524 {
525     FIXME("Writing unknown DWORD 0x%08x\n", d);
526     write_dword(ptr, d);
527 }
528 
529 HRESULT dxbc_add_section(struct dxbc *dxbc, DWORD tag, const char *data, DWORD data_size)
530 {
531     TRACE("dxbc %p, tag %s, size %#x.\n", dxbc, debugstr_an((const char *)&tag, 4), data_size);
532 
533     if (dxbc->count >= dxbc->size)
534     {
535         struct dxbc_section *new_sections;
536         DWORD new_size = dxbc->size << 1;
537 
538         new_sections = HeapReAlloc(GetProcessHeap(), 0, dxbc->sections, new_size * sizeof(*dxbc->sections));
539         if (!new_sections)
540         {
541             ERR("Failed to allocate dxbc section memory\n");
542             return E_OUTOFMEMORY;
543         }
544 
545         dxbc->sections = new_sections;
546         dxbc->size = new_size;
547     }
548 
549     dxbc->sections[dxbc->count].tag = tag;
550     dxbc->sections[dxbc->count].data_size = data_size;
551     dxbc->sections[dxbc->count].data = data;
552     ++dxbc->count;
553 
554     return S_OK;
555 }
556 
557 HRESULT dxbc_init(struct dxbc *dxbc, unsigned int size)
558 {
559     TRACE("dxbc %p, size %u.\n", dxbc, size);
560 
561     /* use a good starting value for the size if none specified */
562     if (!size) size = 2;
563 
564     dxbc->sections = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*dxbc->sections));
565     if (!dxbc->sections)
566     {
567         ERR("Failed to allocate dxbc section memory\n");
568         return E_OUTOFMEMORY;
569     }
570 
571     dxbc->size = size;
572     dxbc->count = 0;
573 
574     return S_OK;
575 }
576 
577 HRESULT dxbc_parse(const char *data, SIZE_T data_size, struct dxbc *dxbc)
578 {
579     const char *ptr = data;
580     HRESULT hr;
581     unsigned int i;
582     DWORD tag, total_size, chunk_count;
583 
584     if (!data)
585     {
586         WARN("No data supplied.\n");
587         return E_FAIL;
588     }
589 
590     read_dword(&ptr, &tag);
591     TRACE("tag: %s.\n", debugstr_an((const char *)&tag, 4));
592 
593     if (tag != TAG_DXBC)
594     {
595         WARN("Wrong tag.\n");
596         return E_FAIL;
597     }
598 
599     /* checksum? */
600     skip_dword_unknown(&ptr, 4);
601 
602     skip_dword_unknown(&ptr, 1);
603 
604     read_dword(&ptr, &total_size);
605     TRACE("total size: %#x\n", total_size);
606 
607     if (data_size != total_size)
608     {
609         WARN("Wrong size supplied.\n");
610         return D3DERR_INVALIDCALL;
611     }
612 
613     read_dword(&ptr, &chunk_count);
614     TRACE("chunk count: %#x\n", chunk_count);
615 
616     hr = dxbc_init(dxbc, chunk_count);
617     if (FAILED(hr))
618     {
619         WARN("Failed to init dxbc\n");
620         return hr;
621     }
622 
623     for (i = 0; i < chunk_count; ++i)
624     {
625         DWORD chunk_tag, chunk_size;
626         const char *chunk_ptr;
627         DWORD chunk_offset;
628 
629         read_dword(&ptr, &chunk_offset);
630         TRACE("chunk %u at offset %#x\n", i, chunk_offset);
631 
632         chunk_ptr = data + chunk_offset;
633 
634         read_dword(&chunk_ptr, &chunk_tag);
635         read_dword(&chunk_ptr, &chunk_size);
636 
637         hr = dxbc_add_section(dxbc, chunk_tag, chunk_ptr, chunk_size);
638         if (FAILED(hr))
639         {
640             WARN("Failed to add section to dxbc\n");
641             return hr;
642         }
643     }
644 
645     return hr;
646 }
647 
648 void dxbc_destroy(struct dxbc *dxbc)
649 {
650     TRACE("dxbc %p.\n", dxbc);
651 
652     HeapFree(GetProcessHeap(), 0, dxbc->sections);
653 }
654 
655 HRESULT dxbc_write_blob(struct dxbc *dxbc, ID3DBlob **blob)
656 {
657     DWORD size = 32, offset = size + 4 * dxbc->count;
658     ID3DBlob *object;
659     HRESULT hr;
660     char *ptr;
661     unsigned int i;
662 
663     TRACE("dxbc %p, blob %p.\n", dxbc, blob);
664 
665     for (i = 0; i < dxbc->count; ++i)
666     {
667         size += 12 + dxbc->sections[i].data_size;
668     }
669 
670     hr = D3DCreateBlob(size, &object);
671     if (FAILED(hr))
672     {
673         WARN("Failed to create blob\n");
674         return hr;
675     }
676 
677     ptr = ID3D10Blob_GetBufferPointer(object);
678 
679     write_dword(&ptr, TAG_DXBC);
680 
681     /* signature(?) */
682     write_dword_unknown(&ptr, 0);
683     write_dword_unknown(&ptr, 0);
684     write_dword_unknown(&ptr, 0);
685     write_dword_unknown(&ptr, 0);
686 
687     /* seems to be always 1 */
688     write_dword_unknown(&ptr, 1);
689 
690     /* DXBC size */
691     write_dword(&ptr, size);
692 
693     /* chunk count */
694     write_dword(&ptr, dxbc->count);
695 
696     /* write the chunk offsets */
697     for (i = 0; i < dxbc->count; ++i)
698     {
699         write_dword(&ptr, offset);
700         offset += 8 + dxbc->sections[i].data_size;
701     }
702 
703     /* write the chunks */
704     for (i = 0; i < dxbc->count; ++i)
705     {
706         write_dword(&ptr, dxbc->sections[i].tag);
707         write_dword(&ptr, dxbc->sections[i].data_size);
708         memcpy(ptr, dxbc->sections[i].data, dxbc->sections[i].data_size);
709         ptr += dxbc->sections[i].data_size;
710     }
711 
712     TRACE("Created ID3DBlob %p\n", object);
713 
714     *blob = object;
715 
716     return S_OK;
717 }
718 
719 void compilation_message(struct compilation_messages *msg, const char *fmt, __ms_va_list args)
720 {
721     char* buffer;
722     int rc, size;
723 
724     if (msg->capacity == 0)
725     {
726         msg->string = d3dcompiler_alloc(MESSAGEBUFFER_INITIAL_SIZE);
727         if (msg->string == NULL)
728         {
729             ERR("Error allocating memory for parser messages\n");
730             return;
731         }
732         msg->capacity = MESSAGEBUFFER_INITIAL_SIZE;
733     }
734 
735     while (1)
736     {
737         rc = vsnprintf(msg->string + msg->size,
738                 msg->capacity - msg->size, fmt, args);
739 
740         if (rc < 0 || rc >= msg->capacity - msg->size)
741         {
742             size = msg->capacity * 2;
743             buffer = d3dcompiler_realloc(msg->string, size);
744             if (buffer == NULL)
745             {
746                 ERR("Error reallocating memory for parser messages\n");
747                 return;
748             }
749             msg->string = buffer;
750             msg->capacity = size;
751         }
752         else
753         {
754             TRACE("%s", msg->string + msg->size);
755             msg->size += rc;
756             return;
757         }
758     }
759 }
760 
761 BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var)
762 {
763     struct hlsl_ir_var *var;
764 
765     LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
766     {
767         if (!strcmp(decl->name, var->name))
768             return FALSE;
769     }
770     if (local_var && scope->upper->upper == hlsl_ctx.globals)
771     {
772         /* Check whether the variable redefines a function parameter. */
773         LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
774         {
775             if (!strcmp(decl->name, var->name))
776                 return FALSE;
777         }
778     }
779 
780     list_add_tail(&scope->vars, &decl->scope_entry);
781     return TRUE;
782 }
783 
784 struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name)
785 {
786     struct hlsl_ir_var *var;
787 
788     LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
789     {
790         if (!strcmp(name, var->name))
791             return var;
792     }
793     if (!scope->upper)
794         return NULL;
795     return get_variable(scope->upper, name);
796 }
797 
798 void free_declaration(struct hlsl_ir_var *decl)
799 {
800     d3dcompiler_free((void *)decl->name);
801     d3dcompiler_free((void *)decl->semantic);
802     d3dcompiler_free((void *)decl->reg_reservation);
803     d3dcompiler_free(decl);
804 }
805 
806 struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
807         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
808 {
809     struct hlsl_type *type;
810 
811     type = d3dcompiler_alloc(sizeof(*type));
812     if (!type)
813     {
814         ERR("Out of memory\n");
815         return NULL;
816     }
817     type->name = name;
818     type->type = type_class;
819     type->base_type = base_type;
820     type->dimx = dimx;
821     type->dimy = dimy;
822 
823     list_add_tail(&hlsl_ctx.types, &type->entry);
824 
825     return type;
826 }
827 
828 struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size)
829 {
830     struct hlsl_type *type = new_hlsl_type(NULL, HLSL_CLASS_ARRAY, HLSL_TYPE_FLOAT, 1, 1);
831 
832     if (!type)
833         return NULL;
834 
835     type->modifiers = basic_type->modifiers;
836     type->e.array.elements_count = array_size;
837     type->e.array.type = basic_type;
838     return type;
839 }
840 
841 struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive)
842 {
843     struct wine_rb_entry *entry = wine_rb_get(&scope->types, name);
844     if (entry)
845         return WINE_RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry);
846 
847     if (recursive && scope->upper)
848         return get_type(scope->upper, name, recursive);
849     return NULL;
850 }
851 
852 BOOL find_function(const char *name)
853 {
854     return wine_rb_get(&hlsl_ctx.functions, name) != NULL;
855 }
856 
857 unsigned int components_count_type(struct hlsl_type *type)
858 {
859     unsigned int count = 0;
860     struct hlsl_struct_field *field;
861 
862     if (type->type <= HLSL_CLASS_LAST_NUMERIC)
863     {
864         return type->dimx * type->dimy;
865     }
866     if (type->type == HLSL_CLASS_ARRAY)
867     {
868         return components_count_type(type->e.array.type) * type->e.array.elements_count;
869     }
870     if (type->type != HLSL_CLASS_STRUCT)
871     {
872         ERR("Unexpected data type %s.\n", debug_hlsl_type(type));
873         return 0;
874     }
875 
876     LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
877     {
878         count += components_count_type(field->type);
879     }
880     return count;
881 }
882 
883 BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
884 {
885     if (t1 == t2)
886         return TRUE;
887 
888     if (t1->type != t2->type)
889         return FALSE;
890     if (t1->base_type != t2->base_type)
891         return FALSE;
892     if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim)
893         return FALSE;
894     if ((t1->modifiers & HLSL_MODIFIERS_COMPARISON_MASK)
895             != (t2->modifiers & HLSL_MODIFIERS_COMPARISON_MASK))
896         return FALSE;
897     if (t1->dimx != t2->dimx)
898         return FALSE;
899     if (t1->dimy != t2->dimy)
900         return FALSE;
901     if (t1->type == HLSL_CLASS_STRUCT)
902     {
903         struct list *t1cur, *t2cur;
904         struct hlsl_struct_field *t1field, *t2field;
905 
906         t1cur = list_head(t1->e.elements);
907         t2cur = list_head(t2->e.elements);
908         while (t1cur && t2cur)
909         {
910             t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry);
911             t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry);
912             if (!compare_hlsl_types(t1field->type, t2field->type))
913                 return FALSE;
914             if (strcmp(t1field->name, t2field->name))
915                 return FALSE;
916             t1cur = list_next(t1->e.elements, t1cur);
917             t2cur = list_next(t2->e.elements, t2cur);
918         }
919         if (t1cur != t2cur)
920             return FALSE;
921     }
922     if (t1->type == HLSL_CLASS_ARRAY)
923         return t1->e.array.elements_count == t2->e.array.elements_count
924                 && compare_hlsl_types(t1->e.array.type, t2->e.array.type);
925 
926     return TRUE;
927 }
928 
929 struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
930 {
931     struct hlsl_type *type;
932     struct hlsl_struct_field *old_field, *field;
933 
934     type = d3dcompiler_alloc(sizeof(*type));
935     if (!type)
936     {
937         ERR("Out of memory\n");
938         return NULL;
939     }
940     if (old->name)
941     {
942         type->name = d3dcompiler_strdup(old->name);
943         if (!type->name)
944         {
945             d3dcompiler_free(type);
946             return NULL;
947         }
948     }
949     type->type = old->type;
950     type->base_type = old->base_type;
951     type->dimx = old->dimx;
952     type->dimy = old->dimy;
953     type->modifiers = old->modifiers;
954     type->sampler_dim = old->sampler_dim;
955     switch (old->type)
956     {
957         case HLSL_CLASS_ARRAY:
958             type->e.array.type = old->e.array.type;
959             type->e.array.elements_count = old->e.array.elements_count;
960             break;
961         case HLSL_CLASS_STRUCT:
962             type->e.elements = d3dcompiler_alloc(sizeof(*type->e.elements));
963             if (!type->e.elements)
964             {
965                 d3dcompiler_free((void *)type->name);
966                 d3dcompiler_free(type);
967                 return NULL;
968             }
969             list_init(type->e.elements);
970             LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry)
971             {
972                 field = d3dcompiler_alloc(sizeof(*field));
973                 if (!field)
974                 {
975                     LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry)
976                     {
977                         d3dcompiler_free((void *)field->semantic);
978                         d3dcompiler_free((void *)field->name);
979                         d3dcompiler_free(field);
980                     }
981                     d3dcompiler_free(type->e.elements);
982                     d3dcompiler_free((void *)type->name);
983                     d3dcompiler_free(type);
984                     return NULL;
985                 }
986                 field->type = clone_hlsl_type(old_field->type);
987                 field->name = d3dcompiler_strdup(old_field->name);
988                 if (old_field->semantic)
989                     field->semantic = d3dcompiler_strdup(old_field->semantic);
990                 field->modifiers = old_field->modifiers;
991                 list_add_tail(type->e.elements, &field->entry);
992             }
993             break;
994         default:
995             break;
996     }
997 
998     list_add_tail(&hlsl_ctx.types, &type->entry);
999     return type;
1000 }
1001 
1002 static BOOL convertible_data_type(struct hlsl_type *type)
1003 {
1004     return type->type != HLSL_CLASS_OBJECT;
1005 }
1006 
1007 BOOL compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1008 {
1009    if (!convertible_data_type(t1) || !convertible_data_type(t2))
1010         return FALSE;
1011 
1012     if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
1013     {
1014         /* Scalar vars can be cast to pretty much everything */
1015         if (t1->dimx == 1 && t1->dimy == 1)
1016             return TRUE;
1017 
1018         if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
1019             return t1->dimx >= t2->dimx;
1020     }
1021 
1022     /* The other way around is true too i.e. whatever to scalar */
1023     if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1)
1024         return TRUE;
1025 
1026     if (t1->type == HLSL_CLASS_ARRAY)
1027     {
1028         if (compare_hlsl_types(t1->e.array.type, t2))
1029             /* e.g. float4[3] to float4 is allowed */
1030             return TRUE;
1031 
1032         if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
1033             return components_count_type(t1) >= components_count_type(t2);
1034         else
1035             return components_count_type(t1) == components_count_type(t2);
1036     }
1037 
1038     if (t1->type == HLSL_CLASS_STRUCT)
1039         return components_count_type(t1) >= components_count_type(t2);
1040 
1041     if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
1042         return components_count_type(t1) == components_count_type(t2);
1043 
1044     if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1045     {
1046         if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1047             return TRUE;
1048 
1049         /* Matrix-vector conversion is apparently allowed if they have the same components count */
1050         if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1051                 && components_count_type(t1) == components_count_type(t2))
1052             return TRUE;
1053         return FALSE;
1054     }
1055 
1056     if (components_count_type(t1) >= components_count_type(t2))
1057         return TRUE;
1058     return FALSE;
1059 }
1060 
1061 static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1062 {
1063     if (!convertible_data_type(t1) || !convertible_data_type(t2))
1064         return FALSE;
1065 
1066     if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
1067     {
1068         /* Scalar vars can be converted to any other numeric data type */
1069         if (t1->dimx == 1 && t1->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1070             return TRUE;
1071         /* The other way around is true too */
1072         if (t2->dimx == 1 && t2->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1073             return TRUE;
1074     }
1075 
1076     if (t1->type == HLSL_CLASS_ARRAY && t2->type == HLSL_CLASS_ARRAY)
1077     {
1078         return components_count_type(t1) == components_count_type(t2);
1079     }
1080 
1081     if ((t1->type == HLSL_CLASS_ARRAY && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1082             || (t1->type <= HLSL_CLASS_LAST_NUMERIC && t2->type == HLSL_CLASS_ARRAY))
1083     {
1084         /* e.g. float4[3] to float4 is allowed */
1085         if (t1->type == HLSL_CLASS_ARRAY && compare_hlsl_types(t1->e.array.type, t2))
1086             return TRUE;
1087         if (components_count_type(t1) == components_count_type(t2))
1088             return TRUE;
1089         return FALSE;
1090     }
1091 
1092     if (t1->type <= HLSL_CLASS_VECTOR && t2->type <= HLSL_CLASS_VECTOR)
1093     {
1094         if (t1->dimx >= t2->dimx)
1095             return TRUE;
1096         return FALSE;
1097     }
1098 
1099     if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1100     {
1101         if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX
1102                 && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1103             return TRUE;
1104 
1105         /* Matrix-vector conversion is apparently allowed if they have the same components count */
1106         if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1107                 && components_count_type(t1) == components_count_type(t2))
1108             return TRUE;
1109         return FALSE;
1110     }
1111 
1112     if (t1->type == HLSL_CLASS_STRUCT && t2->type == HLSL_CLASS_STRUCT)
1113         return compare_hlsl_types(t1, t2);
1114 
1115     return FALSE;
1116 }
1117 
1118 static BOOL expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1119 {
1120     if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR)
1121         return FALSE;
1122 
1123     /* Scalar vars can be converted to pretty much everything */
1124     if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1))
1125         return TRUE;
1126 
1127     if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
1128         return TRUE;
1129 
1130     if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1131     {
1132         /* Matrix-vector conversion is apparently allowed if either they have the same components
1133            count or the matrix is nx1 or 1xn */
1134         if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1135         {
1136             if (components_count_type(t1) == components_count_type(t2))
1137                 return TRUE;
1138 
1139             return (t1->type == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1))
1140                     || (t2->type == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1));
1141         }
1142 
1143         /* Both matrices */
1144         if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1145                 || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy))
1146             return TRUE;
1147     }
1148 
1149     return FALSE;
1150 }
1151 
1152 static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2)
1153 {
1154     static const enum hlsl_base_type types[] =
1155     {
1156         HLSL_TYPE_BOOL,
1157         HLSL_TYPE_INT,
1158         HLSL_TYPE_UINT,
1159         HLSL_TYPE_HALF,
1160         HLSL_TYPE_FLOAT,
1161         HLSL_TYPE_DOUBLE,
1162     };
1163     int t1_idx = -1, t2_idx = -1, i;
1164 
1165     for (i = 0; i < ARRAY_SIZE(types); ++i)
1166     {
1167         /* Always convert away from HLSL_TYPE_HALF */
1168         if (t1 == types[i])
1169             t1_idx = t1 == HLSL_TYPE_HALF ? i + 1 : i;
1170         if (t2 == types[i])
1171             t2_idx = t2 == HLSL_TYPE_HALF ? i + 1 : i;
1172 
1173         if (t1_idx != -1 && t2_idx != -1)
1174             break;
1175     }
1176     if (t1_idx == -1 || t2_idx == -1)
1177     {
1178         FIXME("Unexpected base type.\n");
1179         return HLSL_TYPE_FLOAT;
1180     }
1181     return t1_idx >= t2_idx ? t1 : t2;
1182 }
1183 
1184 static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type *t2,
1185         struct source_location *loc)
1186 {
1187     enum hlsl_type_class type;
1188     enum hlsl_base_type base;
1189     unsigned int dimx, dimy;
1190 
1191     if (t1->type > HLSL_CLASS_LAST_NUMERIC || t2->type > HLSL_CLASS_LAST_NUMERIC)
1192     {
1193         hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
1194                 "non scalar/vector/matrix data type in expression");
1195         return NULL;
1196     }
1197 
1198     if (compare_hlsl_types(t1, t2))
1199         return t1;
1200 
1201     if (!expr_compatible_data_types(t1, t2))
1202     {
1203         hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
1204                 "expression data types are incompatible");
1205         return NULL;
1206     }
1207 
1208     if (t1->base_type == t2->base_type)
1209         base = t1->base_type;
1210     else
1211         base = expr_common_base_type(t1->base_type, t2->base_type);
1212 
1213     if (t1->dimx == 1 && t1->dimy == 1)
1214     {
1215         type = t2->type;
1216         dimx = t2->dimx;
1217         dimy = t2->dimy;
1218     }
1219     else if (t2->dimx == 1 && t2->dimy == 1)
1220     {
1221         type = t1->type;
1222         dimx = t1->dimx;
1223         dimy = t1->dimy;
1224     }
1225     else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX)
1226     {
1227         type = HLSL_CLASS_MATRIX;
1228         dimx = min(t1->dimx, t2->dimx);
1229         dimy = min(t1->dimy, t2->dimy);
1230     }
1231     else
1232     {
1233         /* Two vectors or a vector and a matrix (matrix must be 1xn or nx1) */
1234         unsigned int max_dim_1, max_dim_2;
1235 
1236         max_dim_1 = max(t1->dimx, t1->dimy);
1237         max_dim_2 = max(t2->dimx, t2->dimy);
1238         if (t1->dimx * t1->dimy == t2->dimx * t2->dimy)
1239         {
1240             type = HLSL_CLASS_VECTOR;
1241             dimx = max(t1->dimx, t2->dimx);
1242             dimy = 1;
1243         }
1244         else if (max_dim_1 <= max_dim_2)
1245         {
1246             type = t1->type;
1247             if (type == HLSL_CLASS_VECTOR)
1248             {
1249                 dimx = max_dim_1;
1250                 dimy = 1;
1251             }
1252             else
1253             {
1254                 dimx = t1->dimx;
1255                 dimy = t1->dimy;
1256             }
1257         }
1258         else
1259         {
1260             type = t2->type;
1261             if (type == HLSL_CLASS_VECTOR)
1262             {
1263                 dimx = max_dim_2;
1264                 dimy = 1;
1265             }
1266             else
1267             {
1268                 dimx = t2->dimx;
1269                 dimy = t2->dimy;
1270             }
1271         }
1272     }
1273 
1274     return new_hlsl_type(NULL, type, base, dimx, dimy);
1275 }
1276 
1277 static struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *type,
1278         struct source_location *loc)
1279 {
1280     if (compare_hlsl_types(node->data_type, type))
1281         return node;
1282     TRACE("Implicit conversion of expression to %s\n", debug_hlsl_type(type));
1283     return &new_cast(node, type, loc)->node;
1284 }
1285 
1286 struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
1287         struct source_location *loc)
1288 {
1289     struct hlsl_ir_expr *expr = d3dcompiler_alloc(sizeof(*expr));
1290     struct hlsl_type *type;
1291     unsigned int i;
1292 
1293     if (!expr)
1294     {
1295         ERR("Out of memory\n");
1296         return NULL;
1297     }
1298     expr->node.type = HLSL_IR_EXPR;
1299     expr->node.loc = *loc;
1300     type = operands[0]->data_type;
1301     for (i = 1; i <= 2; ++i)
1302     {
1303         if (!operands[i])
1304             break;
1305         type = expr_common_type(type, operands[i]->data_type, loc);
1306         if (!type)
1307         {
1308             d3dcompiler_free(expr);
1309             return NULL;
1310         }
1311     }
1312     for (i = 0; i <= 2; ++i)
1313     {
1314         if (!operands[i])
1315             break;
1316         if (compare_hlsl_types(operands[i]->data_type, type))
1317             continue;
1318         TRACE("Implicitly converting %s into %s in an expression\n", debug_hlsl_type(operands[i]->data_type), debug_hlsl_type(type));
1319         if (operands[i]->data_type->dimx * operands[i]->data_type->dimy != 1
1320                 && operands[i]->data_type->dimx * operands[i]->data_type->dimy != type->dimx * type->dimy)
1321         {
1322             hlsl_report_message(operands[i]->loc.file,
1323                     operands[i]->loc.line, operands[i]->loc.col, HLSL_LEVEL_WARNING,
1324                     "implicit truncation of vector/matrix type");
1325         }
1326         operands[i] = implicit_conversion(operands[i], type, &operands[i]->loc);
1327         if (!operands[i])
1328         {
1329             ERR("Impossible to convert expression operand %u to %s\n", i + 1, debug_hlsl_type(type));
1330             d3dcompiler_free(expr);
1331             return NULL;
1332         }
1333     }
1334     expr->node.data_type = type;
1335     expr->op = op;
1336     expr->operands[0] = operands[0];
1337     expr->operands[1] = operands[1];
1338     expr->operands[2] = operands[2];
1339 
1340     return expr;
1341 }
1342 
1343 struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
1344         struct source_location *loc)
1345 {
1346     struct hlsl_ir_node *cast;
1347 
1348     cast = new_unary_expr(HLSL_IR_UNOP_CAST, node, *loc);
1349     if (cast)
1350         cast->data_type = type;
1351     return expr_from_node(cast);
1352 }
1353 
1354 struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
1355 {
1356     struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1357 
1358     if (!deref)
1359     {
1360         ERR("Out of memory.\n");
1361         return NULL;
1362     }
1363     deref->node.type = HLSL_IR_DEREF;
1364     deref->node.data_type = var->data_type;
1365     deref->type = HLSL_IR_DEREF_VAR;
1366     deref->v.var = var;
1367     return deref;
1368 }
1369 
1370 struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field)
1371 {
1372     struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1373 
1374     if (!deref)
1375     {
1376         ERR("Out of memory.\n");
1377         return NULL;
1378     }
1379     deref->node.type = HLSL_IR_DEREF;
1380     deref->node.data_type = field->type;
1381     deref->type = HLSL_IR_DEREF_RECORD;
1382     deref->v.record.record = record;
1383     deref->v.record.field = field;
1384     return deref;
1385 }
1386 
1387 static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
1388 {
1389     static const enum hlsl_ir_expr_op ops[] =
1390     {
1391         0,
1392         HLSL_IR_BINOP_ADD,
1393         HLSL_IR_BINOP_SUB,
1394         HLSL_IR_BINOP_MUL,
1395         HLSL_IR_BINOP_DIV,
1396         HLSL_IR_BINOP_MOD,
1397         HLSL_IR_BINOP_LSHIFT,
1398         HLSL_IR_BINOP_RSHIFT,
1399         HLSL_IR_BINOP_BIT_AND,
1400         HLSL_IR_BINOP_BIT_OR,
1401         HLSL_IR_BINOP_BIT_XOR,
1402     };
1403 
1404     return ops[op];
1405 }
1406 
1407 struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assign_op assign_op,
1408         DWORD writemask, struct hlsl_ir_node *right)
1409 {
1410     struct hlsl_ir_assignment *assign = d3dcompiler_alloc(sizeof(*assign));
1411     struct hlsl_type *type;
1412     struct hlsl_ir_node *lhs, *rhs;
1413 
1414     if (!assign)
1415     {
1416         ERR("Out of memory\n");
1417         return NULL;
1418     }
1419 
1420     TRACE("Creating proper assignment expression.\n");
1421     rhs = right;
1422     if (writemask == BWRITERSP_WRITEMASK_ALL)
1423         type = left->data_type;
1424     else
1425     {
1426         unsigned int dimx = 0;
1427         DWORD bitmask;
1428         enum hlsl_type_class type_class;
1429 
1430         if (left->data_type->type > HLSL_CLASS_LAST_NUMERIC)
1431         {
1432             hlsl_report_message(left->loc.file, left->loc.line, left->loc.col, HLSL_LEVEL_ERROR,
1433                     "writemask on a non scalar/vector/matrix type");
1434             d3dcompiler_free(assign);
1435             return NULL;
1436         }
1437         bitmask = writemask & ((1 << left->data_type->dimx) - 1);
1438         while (bitmask)
1439         {
1440             if (bitmask & 1)
1441                 dimx++;
1442             bitmask >>= 1;
1443         }
1444         if (left->data_type->type == HLSL_CLASS_MATRIX)
1445             FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n");
1446         if (dimx == 1)
1447             type_class = HLSL_CLASS_SCALAR;
1448         else
1449             type_class = left->data_type->type;
1450         type = new_hlsl_type(NULL, type_class, left->data_type->base_type, dimx, 1);
1451     }
1452     assign->node.type = HLSL_IR_ASSIGNMENT;
1453     assign->node.loc = left->loc;
1454     assign->node.data_type = type;
1455     assign->writemask = writemask;
1456     FIXME("Check for casts in the lhs.\n");
1457 
1458     lhs = left;
1459     /* FIXME: check for invalid writemasks on the lhs. */
1460 
1461     if (!compare_hlsl_types(type, rhs->data_type))
1462     {
1463         struct hlsl_ir_node *converted_rhs;
1464 
1465         if (!implicit_compatible_data_types(rhs->data_type, type))
1466         {
1467             hlsl_report_message(rhs->loc.file, rhs->loc.line, rhs->loc.col, HLSL_LEVEL_ERROR,
1468                     "can't implicitly convert %s to %s",
1469                     debug_hlsl_type(rhs->data_type), debug_hlsl_type(type));
1470             free_instr(lhs);
1471             free_instr(rhs);
1472             d3dcompiler_free(assign);
1473             return NULL;
1474         }
1475         if (lhs->data_type->dimx * lhs->data_type->dimy < rhs->data_type->dimx * rhs->data_type->dimy)
1476             hlsl_report_message(rhs->loc.file, rhs->loc.line, rhs->loc.col, HLSL_LEVEL_WARNING,
1477                     "implicit truncation of vector type");
1478 
1479         converted_rhs = implicit_conversion(rhs, type, &rhs->loc);
1480         if (!converted_rhs)
1481         {
1482             ERR("Couldn't implicitly convert expression to %s.\n", debug_hlsl_type(type));
1483             free_instr(lhs);
1484             free_instr(rhs);
1485             d3dcompiler_free(assign);
1486             return NULL;
1487         }
1488         rhs = converted_rhs;
1489     }
1490 
1491     assign->lhs = lhs;
1492     if (assign_op != ASSIGN_OP_ASSIGN)
1493     {
1494         enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
1495         struct hlsl_ir_node *expr;
1496 
1497         if (lhs->type != HLSL_IR_DEREF || deref_from_node(lhs)->type != HLSL_IR_DEREF_VAR)
1498         {
1499             FIXME("LHS expression not supported in compound assignments yet.\n");
1500             assign->rhs = rhs;
1501         }
1502         else
1503         {
1504             struct hlsl_ir_deref *lhs_deref = deref_from_node(lhs), *new_deref;
1505 
1506             TRACE("Adding an expression for the compound assignment.\n");
1507             new_deref = new_var_deref(lhs_deref->v.var);
1508             expr = new_binary_expr(op, &new_deref->node, rhs, left->loc);
1509             assign->rhs = expr;
1510         }
1511     }
1512     else
1513         assign->rhs = rhs;
1514 
1515     return &assign->node;
1516 }
1517 
1518 static int compare_hlsl_types_rb(const void *key, const struct wine_rb_entry *entry)
1519 {
1520     const char *name = key;
1521     const struct hlsl_type *type = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_type, scope_entry);
1522 
1523     if (name == type->name)
1524         return 0;
1525 
1526     if (!name || !type->name)
1527     {
1528         ERR("hlsl_type without a name in a scope?\n");
1529         return -1;
1530     }
1531     return strcmp(name, type->name);
1532 }
1533 
1534 void push_scope(struct hlsl_parse_ctx *ctx)
1535 {
1536     struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope));
1537 
1538     if (!new_scope)
1539     {
1540         ERR("Out of memory!\n");
1541         return;
1542     }
1543     TRACE("Pushing a new scope\n");
1544     list_init(&new_scope->vars);
1545     wine_rb_init(&new_scope->types, compare_hlsl_types_rb);
1546     new_scope->upper = ctx->cur_scope;
1547     ctx->cur_scope = new_scope;
1548     list_add_tail(&ctx->scopes, &new_scope->entry);
1549 }
1550 
1551 BOOL pop_scope(struct hlsl_parse_ctx *ctx)
1552 {
1553     struct hlsl_scope *prev_scope = ctx->cur_scope->upper;
1554     if (!prev_scope)
1555         return FALSE;
1556 
1557     TRACE("Popping current scope\n");
1558     ctx->cur_scope = prev_scope;
1559     return TRUE;
1560 }
1561 
1562 struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, struct list *parameters)
1563 {
1564     struct hlsl_ir_function_decl *decl;
1565 
1566     decl = d3dcompiler_alloc(sizeof(*decl));
1567     if (!decl)
1568     {
1569         ERR("Out of memory.\n");
1570         return NULL;
1571     }
1572     decl->return_type = return_type;
1573     decl->parameters = parameters;
1574 
1575     return decl;
1576 }
1577 
1578 static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
1579 {
1580     if (t1->type != t2->type)
1581     {
1582         if (!((t1->type == HLSL_CLASS_SCALAR && t2->type == HLSL_CLASS_VECTOR)
1583                 || (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_SCALAR)))
1584             return t1->type - t2->type;
1585     }
1586     if (t1->base_type != t2->base_type)
1587         return t1->base_type - t2->base_type;
1588     if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim)
1589         return t1->sampler_dim - t2->sampler_dim;
1590     if (t1->dimx != t2->dimx)
1591         return t1->dimx - t2->dimx;
1592     if (t1->dimy != t2->dimy)
1593         return t1->dimx - t2->dimx;
1594     if (t1->type == HLSL_CLASS_STRUCT)
1595     {
1596         struct list *t1cur, *t2cur;
1597         struct hlsl_struct_field *t1field, *t2field;
1598         int r;
1599 
1600         t1cur = list_head(t1->e.elements);
1601         t2cur = list_head(t2->e.elements);
1602         while (t1cur && t2cur)
1603         {
1604             t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry);
1605             t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry);
1606             if ((r = compare_param_hlsl_types(t1field->type, t2field->type)))
1607                 return r;
1608             if ((r = strcmp(t1field->name, t2field->name)))
1609                 return r;
1610             t1cur = list_next(t1->e.elements, t1cur);
1611             t2cur = list_next(t2->e.elements, t2cur);
1612         }
1613         if (t1cur != t2cur)
1614             return t1cur ? 1 : -1;
1615         return 0;
1616     }
1617     if (t1->type == HLSL_CLASS_ARRAY)
1618     {
1619         if (t1->e.array.elements_count != t2->e.array.elements_count)
1620             return t1->e.array.elements_count - t2->e.array.elements_count;
1621         return compare_param_hlsl_types(t1->e.array.type, t2->e.array.type);
1622     }
1623 
1624     return 0;
1625 }
1626 
1627 static int compare_function_decl_rb(const void *key, const struct wine_rb_entry *entry)
1628 {
1629     const struct list *params = key;
1630     const struct hlsl_ir_function_decl *decl = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry);
1631     int params_count = params ? list_count(params) : 0;
1632     int decl_params_count = decl->parameters ? list_count(decl->parameters) : 0;
1633     int r;
1634     struct list *p1cur, *p2cur;
1635 
1636     if (params_count != decl_params_count)
1637         return params_count - decl_params_count;
1638 
1639     p1cur = params ? list_head(params) : NULL;
1640     p2cur = decl->parameters ? list_head(decl->parameters) : NULL;
1641     while (p1cur && p2cur)
1642     {
1643         struct hlsl_ir_var *p1, *p2;
1644         p1 = LIST_ENTRY(p1cur, struct hlsl_ir_var, param_entry);
1645         p2 = LIST_ENTRY(p2cur, struct hlsl_ir_var, param_entry);
1646         if ((r = compare_param_hlsl_types(p1->data_type, p2->data_type)))
1647             return r;
1648         p1cur = list_next(params, p1cur);
1649         p2cur = list_next(decl->parameters, p2cur);
1650     }
1651     return 0;
1652 }
1653 
1654 static int compare_function_rb(const void *key, const struct wine_rb_entry *entry)
1655 {
1656     const char *name = key;
1657     const struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry);
1658 
1659     return strcmp(name, func->name);
1660 }
1661 
1662 void init_functions_tree(struct wine_rb_tree *funcs)
1663 {
1664     wine_rb_init(&hlsl_ctx.functions, compare_function_rb);
1665 }
1666 
1667 static const char *debug_base_type(const struct hlsl_type *type)
1668 {
1669     const char *name = "(unknown)";
1670 
1671     switch (type->base_type)
1672     {
1673         case HLSL_TYPE_FLOAT:        name = "float";         break;
1674         case HLSL_TYPE_HALF:         name = "half";          break;
1675         case HLSL_TYPE_DOUBLE:       name = "double";        break;
1676         case HLSL_TYPE_INT:          name = "int";           break;
1677         case HLSL_TYPE_UINT:         name = "uint";          break;
1678         case HLSL_TYPE_BOOL:         name = "bool";          break;
1679         case HLSL_TYPE_SAMPLER:
1680             switch (type->sampler_dim)
1681             {
1682                 case HLSL_SAMPLER_DIM_GENERIC: name = "sampler";       break;
1683                 case HLSL_SAMPLER_DIM_1D:      name = "sampler1D";     break;
1684                 case HLSL_SAMPLER_DIM_2D:      name = "sampler2D";     break;
1685                 case HLSL_SAMPLER_DIM_3D:      name = "sampler3D";     break;
1686                 case HLSL_SAMPLER_DIM_CUBE:    name = "samplerCUBE";   break;
1687             }
1688             break;
1689         default:
1690             FIXME("Unhandled case %u\n", type->base_type);
1691     }
1692     return name;
1693 }
1694 
1695 const char *debug_hlsl_type(const struct hlsl_type *type)
1696 {
1697     const char *name;
1698 
1699     if (type->name)
1700         return debugstr_a(type->name);
1701 
1702     if (type->type == HLSL_CLASS_STRUCT)
1703         return "<anonymous struct>";
1704 
1705     if (type->type == HLSL_CLASS_ARRAY)
1706     {
1707         name = debug_base_type(type->e.array.type);
1708         return wine_dbg_sprintf("%s[%u]", name, type->e.array.elements_count);
1709     }
1710 
1711     name = debug_base_type(type);
1712 
1713     if (type->type == HLSL_CLASS_SCALAR)
1714         return wine_dbg_sprintf("%s", name);
1715     if (type->type == HLSL_CLASS_VECTOR)
1716         return wine_dbg_sprintf("%s%u", name, type->dimx);
1717     if (type->type == HLSL_CLASS_MATRIX)
1718         return wine_dbg_sprintf("%s%ux%u", name, type->dimx, type->dimy);
1719     return "unexpected_type";
1720 }
1721 
1722 const char *debug_modifiers(DWORD modifiers)
1723 {
1724     char string[110];
1725 
1726     string[0] = 0;
1727     if (modifiers & HLSL_STORAGE_EXTERN)
1728         strcat(string, " extern");                       /* 7 */
1729     if (modifiers & HLSL_STORAGE_NOINTERPOLATION)
1730         strcat(string, " nointerpolation");              /* 16 */
1731     if (modifiers & HLSL_MODIFIER_PRECISE)
1732         strcat(string, " precise");                      /* 8 */
1733     if (modifiers & HLSL_STORAGE_SHARED)
1734         strcat(string, " shared");                       /* 7 */
1735     if (modifiers & HLSL_STORAGE_GROUPSHARED)
1736         strcat(string, " groupshared");                  /* 12 */
1737     if (modifiers & HLSL_STORAGE_STATIC)
1738         strcat(string, " static");                       /* 7 */
1739     if (modifiers & HLSL_STORAGE_UNIFORM)
1740         strcat(string, " uniform");                      /* 8 */
1741     if (modifiers & HLSL_STORAGE_VOLATILE)
1742         strcat(string, " volatile");                     /* 9 */
1743     if (modifiers & HLSL_MODIFIER_CONST)
1744         strcat(string, " const");                        /* 6 */
1745     if (modifiers & HLSL_MODIFIER_ROW_MAJOR)
1746         strcat(string, " row_major");                    /* 10 */
1747     if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
1748         strcat(string, " column_major");                 /* 13 */
1749     if ((modifiers & (HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT)) == (HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT))
1750         strcat(string, " inout");                        /* 6 */
1751     else if (modifiers & HLSL_MODIFIER_IN)
1752         strcat(string, " in");                           /* 3 */
1753     else if (modifiers & HLSL_MODIFIER_OUT)
1754         strcat(string, " out");                          /* 4 */
1755 
1756     return wine_dbg_sprintf("%s", string[0] ? string + 1 : "");
1757 }
1758 
1759 static const char *debug_node_type(enum hlsl_ir_node_type type)
1760 {
1761     static const char * const names[] =
1762     {
1763         "HLSL_IR_ASSIGNMENT",
1764         "HLSL_IR_CONSTANT",
1765         "HLSL_IR_CONSTRUCTOR",
1766         "HLSL_IR_DEREF",
1767         "HLSL_IR_EXPR",
1768         "HLSL_IR_IF",
1769         "HLSL_IR_JUMP",
1770         "HLSL_IR_SWIZZLE",
1771     };
1772 
1773     if (type >= ARRAY_SIZE(names))
1774         return "Unexpected node type";
1775     return names[type];
1776 }
1777 
1778 static void debug_dump_instr(const struct hlsl_ir_node *instr);
1779 
1780 static void debug_dump_instr_list(const struct list *list)
1781 {
1782     struct hlsl_ir_node *instr;
1783 
1784     LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
1785     {
1786         debug_dump_instr(instr);
1787         TRACE("\n");
1788     }
1789 }
1790 
1791 static void debug_dump_ir_var(const struct hlsl_ir_var *var)
1792 {
1793     if (var->modifiers)
1794         TRACE("%s ", debug_modifiers(var->modifiers));
1795     TRACE("%s %s", debug_hlsl_type(var->data_type), var->name);
1796     if (var->semantic)
1797         TRACE(" : %s", debugstr_a(var->semantic));
1798 }
1799 
1800 static void debug_dump_ir_deref(const struct hlsl_ir_deref *deref)
1801 {
1802     switch (deref->type)
1803     {
1804         case HLSL_IR_DEREF_VAR:
1805             TRACE("deref(");
1806             debug_dump_ir_var(deref->v.var);
1807             TRACE(")");
1808             break;
1809         case HLSL_IR_DEREF_ARRAY:
1810             debug_dump_instr(deref->v.array.array);
1811             TRACE("[");
1812             debug_dump_instr(deref->v.array.index);
1813             TRACE("]");
1814             break;
1815         case HLSL_IR_DEREF_RECORD:
1816             debug_dump_instr(deref->v.record.record);
1817             TRACE(".%s", debugstr_a(deref->v.record.field->name));
1818             break;
1819     }
1820 }
1821 
1822 static void debug_dump_ir_constant(const struct hlsl_ir_constant *constant)
1823 {
1824     struct hlsl_type *type = constant->node.data_type;
1825     unsigned int x, y;
1826 
1827     if (type->dimy != 1)
1828         TRACE("{");
1829     for (y = 0; y < type->dimy; ++y)
1830     {
1831         if (type->dimx != 1)
1832             TRACE("{");
1833         for (x = 0; x < type->dimx; ++x)
1834         {
1835             switch (type->base_type)
1836             {
1837                 case HLSL_TYPE_FLOAT:
1838                     TRACE("%g ", (double)constant->v.value.f[y * type->dimx + x]);
1839                     break;
1840                 case HLSL_TYPE_DOUBLE:
1841                     TRACE("%g ", constant->v.value.d[y * type->dimx + x]);
1842                     break;
1843                 case HLSL_TYPE_INT:
1844                     TRACE("%d ", constant->v.value.i[y * type->dimx + x]);
1845                     break;
1846                 case HLSL_TYPE_UINT:
1847                     TRACE("%u ", constant->v.value.u[y * type->dimx + x]);
1848                     break;
1849                 case HLSL_TYPE_BOOL:
1850                     TRACE("%s ", constant->v.value.b[y * type->dimx + x] == FALSE ? "false" : "true");
1851                     break;
1852                 default:
1853                     TRACE("Constants of type %s not supported\n", debug_base_type(type));
1854             }
1855         }
1856         if (type->dimx != 1)
1857             TRACE("}");
1858     }
1859     if (type->dimy != 1)
1860         TRACE("}");
1861 }
1862 
1863 static const char *debug_expr_op(const struct hlsl_ir_expr *expr)
1864 {
1865     static const char * const op_names[] =
1866     {
1867         "~",
1868         "!",
1869         "-",
1870         "abs",
1871         "sign",
1872         "rcp",
1873         "rsq",
1874         "sqrt",
1875         "nrm",
1876         "exp2",
1877         "log2",
1878 
1879         "cast",
1880 
1881         "fract",
1882 
1883         "sin",
1884         "cos",
1885         "sin_reduced",
1886         "cos_reduced",
1887 
1888         "dsx",
1889         "dsy",
1890 
1891         "sat",
1892 
1893         "pre++",
1894         "pre--",
1895         "post++",
1896         "post--",
1897 
1898         "+",
1899         "-",
1900         "*",
1901         "/",
1902 
1903         "%",
1904 
1905         "<",
1906         ">",
1907         "<=",
1908         ">=",
1909         "==",
1910         "!=",
1911 
1912         "&&",
1913         "||",
1914 
1915         "<<",
1916         ">>",
1917         "&",
1918         "|",
1919         "^",
1920 
1921         "dot",
1922         "crs",
1923         "min",
1924         "max",
1925 
1926         "pow",
1927 
1928         "lerp",
1929 
1930         ",",
1931     };
1932 
1933     if (expr->op == HLSL_IR_UNOP_CAST)
1934         return debug_hlsl_type(expr->node.data_type);
1935 
1936     return op_names[expr->op];
1937 }
1938 
1939 /* Dumps the expression in a prefix "operator (operands)" form */
1940 static void debug_dump_ir_expr(const struct hlsl_ir_expr *expr)
1941 {
1942     unsigned int i;
1943 
1944     TRACE("%s (", debug_expr_op(expr));
1945     for (i = 0; i < 3 && expr->operands[i]; ++i)
1946     {
1947         debug_dump_instr(expr->operands[i]);
1948         TRACE(" ");
1949     }
1950     TRACE(")");
1951 }
1952 
1953 static void debug_dump_ir_constructor(const struct hlsl_ir_constructor *constructor)
1954 {
1955     unsigned int i;
1956 
1957     TRACE("%s (", debug_hlsl_type(constructor->node.data_type));
1958     for (i = 0; i < constructor->args_count; ++i)
1959     {
1960         debug_dump_instr(constructor->args[i]);
1961         TRACE(" ");
1962     }
1963     TRACE(")");
1964 }
1965 
1966 static const char *debug_writemask(DWORD writemask)
1967 {
1968     static const char components[] = {'x', 'y', 'z', 'w'};
1969     char string[5];
1970     unsigned int i = 0, pos = 0;
1971 
1972     assert(!(writemask & ~BWRITERSP_WRITEMASK_ALL));
1973 
1974     while (writemask)
1975     {
1976         if (writemask & 1)
1977             string[pos++] = components[i];
1978         writemask >>= 1;
1979         i++;
1980     }
1981     string[pos] = '\0';
1982     return wine_dbg_sprintf(".%s", string);
1983 }
1984 
1985 static void debug_dump_ir_assignment(const struct hlsl_ir_assignment *assign)
1986 {
1987     TRACE("= (");
1988     debug_dump_instr(assign->lhs);
1989     if (assign->writemask != BWRITERSP_WRITEMASK_ALL)
1990         TRACE("%s", debug_writemask(assign->writemask));
1991     TRACE(" ");
1992     debug_dump_instr(assign->rhs);
1993     TRACE(")");
1994 }
1995 
1996 static void debug_dump_ir_swizzle(const struct hlsl_ir_swizzle *swizzle)
1997 {
1998     unsigned int i;
1999 
2000     debug_dump_instr(swizzle->val);
2001     TRACE(".");
2002     if (swizzle->val->data_type->dimy > 1)
2003     {
2004         for (i = 0; i < swizzle->node.data_type->dimx; ++i)
2005             TRACE("_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf);
2006     }
2007     else
2008     {
2009         static const char c[] = {'x', 'y', 'z', 'w'};
2010 
2011         for (i = 0; i < swizzle->node.data_type->dimx; ++i)
2012             TRACE("%c", c[(swizzle->swizzle >> i * 2) & 0x3]);
2013     }
2014 }
2015 
2016 static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
2017 {
2018     switch (jump->type)
2019     {
2020         case HLSL_IR_JUMP_BREAK:
2021             TRACE("break");
2022             break;
2023         case HLSL_IR_JUMP_CONTINUE:
2024             TRACE("continue");
2025             break;
2026         case HLSL_IR_JUMP_DISCARD:
2027             TRACE("discard");
2028             break;
2029         case HLSL_IR_JUMP_RETURN:
2030             TRACE("return ");
2031             if (jump->return_value)
2032                 debug_dump_instr(jump->return_value);
2033             TRACE(";");
2034             break;
2035     }
2036 }
2037 
2038 static void debug_dump_ir_if(const struct hlsl_ir_if *if_node)
2039 {
2040     TRACE("if (");
2041     debug_dump_instr(if_node->condition);
2042     TRACE(")\n{\n");
2043     debug_dump_instr_list(if_node->then_instrs);
2044     TRACE("}\n");
2045     if (if_node->else_instrs)
2046     {
2047         TRACE("else\n{\n");
2048         debug_dump_instr_list(if_node->else_instrs);
2049         TRACE("}\n");
2050     }
2051 }
2052 
2053 static void debug_dump_instr(const struct hlsl_ir_node *instr)
2054 {
2055     switch (instr->type)
2056     {
2057         case HLSL_IR_EXPR:
2058             debug_dump_ir_expr(expr_from_node(instr));
2059             break;
2060         case HLSL_IR_DEREF:
2061             debug_dump_ir_deref(deref_from_node(instr));
2062             break;
2063         case HLSL_IR_CONSTANT:
2064             debug_dump_ir_constant(constant_from_node(instr));
2065             break;
2066         case HLSL_IR_ASSIGNMENT:
2067             debug_dump_ir_assignment(assignment_from_node(instr));
2068             break;
2069         case HLSL_IR_SWIZZLE:
2070             debug_dump_ir_swizzle(swizzle_from_node(instr));
2071             break;
2072         case HLSL_IR_CONSTRUCTOR:
2073             debug_dump_ir_constructor(constructor_from_node(instr));
2074             break;
2075         case HLSL_IR_JUMP:
2076             debug_dump_ir_jump(jump_from_node(instr));
2077             break;
2078         case HLSL_IR_IF:
2079             debug_dump_ir_if(if_from_node(instr));
2080             break;
2081         default:
2082             TRACE("<No dump function for %s>", debug_node_type(instr->type));
2083     }
2084 }
2085 
2086 void debug_dump_ir_function_decl(const struct hlsl_ir_function_decl *func)
2087 {
2088     struct hlsl_ir_var *param;
2089 
2090     TRACE("Dumping function %s.\n", debugstr_a(func->func->name));
2091     TRACE("Function parameters:\n");
2092     LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, param_entry)
2093     {
2094         debug_dump_ir_var(param);
2095         TRACE("\n");
2096     }
2097     if (func->semantic)
2098         TRACE("Function semantic: %s\n", debugstr_a(func->semantic));
2099     if (func->body)
2100     {
2101         debug_dump_instr_list(func->body);
2102     }
2103 }
2104 
2105 void free_hlsl_type(struct hlsl_type *type)
2106 {
2107     struct hlsl_struct_field *field, *next_field;
2108 
2109     d3dcompiler_free((void *)type->name);
2110     if (type->type == HLSL_CLASS_STRUCT)
2111     {
2112         LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry)
2113         {
2114             d3dcompiler_free((void *)field->name);
2115             d3dcompiler_free((void *)field->semantic);
2116             d3dcompiler_free(field);
2117         }
2118     }
2119     d3dcompiler_free(type);
2120 }
2121 
2122 void free_instr_list(struct list *list)
2123 {
2124     struct hlsl_ir_node *node, *next_node;
2125 
2126     if (!list)
2127         return;
2128     LIST_FOR_EACH_ENTRY_SAFE(node, next_node, list, struct hlsl_ir_node, entry)
2129         free_instr(node);
2130     d3dcompiler_free(list);
2131 }
2132 
2133 static void free_ir_constant(struct hlsl_ir_constant *constant)
2134 {
2135     struct hlsl_type *type = constant->node.data_type;
2136     unsigned int i;
2137     struct hlsl_ir_constant *field, *next_field;
2138 
2139     switch (type->type)
2140     {
2141         case HLSL_CLASS_ARRAY:
2142             for (i = 0; i < type->e.array.elements_count; ++i)
2143                 free_ir_constant(&constant->v.array_elements[i]);
2144             d3dcompiler_free(constant->v.array_elements);
2145             break;
2146         case HLSL_CLASS_STRUCT:
2147             LIST_FOR_EACH_ENTRY_SAFE(field, next_field, constant->v.struct_elements, struct hlsl_ir_constant, node.entry)
2148                 free_ir_constant(field);
2149             break;
2150         default:
2151             break;
2152     }
2153     d3dcompiler_free(constant);
2154 }
2155 
2156 static void free_ir_deref(struct hlsl_ir_deref *deref)
2157 {
2158     switch (deref->type)
2159     {
2160         case HLSL_IR_DEREF_VAR:
2161             /* Variables are shared among nodes in the tree. */
2162             break;
2163         case HLSL_IR_DEREF_ARRAY:
2164             free_instr(deref->v.array.array);
2165             free_instr(deref->v.array.index);
2166             break;
2167         case HLSL_IR_DEREF_RECORD:
2168             free_instr(deref->v.record.record);
2169             break;
2170     }
2171     d3dcompiler_free(deref);
2172 }
2173 
2174 static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
2175 {
2176     free_instr(swizzle->val);
2177     d3dcompiler_free(swizzle);
2178 }
2179 
2180 static void free_ir_constructor(struct hlsl_ir_constructor *constructor)
2181 {
2182     unsigned int i;
2183     for (i = 0; i < constructor->args_count; ++i)
2184         free_instr(constructor->args[i]);
2185     d3dcompiler_free(constructor);
2186 }
2187 
2188 static void free_ir_expr(struct hlsl_ir_expr *expr)
2189 {
2190     unsigned int i;
2191 
2192     for (i = 0; i < 3; ++i)
2193     {
2194         if (!expr->operands[i])
2195             break;
2196         free_instr(expr->operands[i]);
2197     }
2198     free_instr_list(expr->subexpressions);
2199     d3dcompiler_free(expr);
2200 }
2201 
2202 static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
2203 {
2204     free_instr(assignment->lhs);
2205     free_instr(assignment->rhs);
2206     d3dcompiler_free(assignment);
2207 }
2208 
2209 static void free_ir_if(struct hlsl_ir_if *if_node)
2210 {
2211     free_instr(if_node->condition);
2212     free_instr_list(if_node->then_instrs);
2213     free_instr_list(if_node->else_instrs);
2214     d3dcompiler_free(if_node);
2215 }
2216 
2217 static void free_ir_jump(struct hlsl_ir_jump *jump)
2218 {
2219     if (jump->type == HLSL_IR_JUMP_RETURN)
2220         free_instr(jump->return_value);
2221     d3dcompiler_free(jump);
2222 }
2223 
2224 void free_instr(struct hlsl_ir_node *node)
2225 {
2226     switch (node->type)
2227     {
2228         case HLSL_IR_CONSTANT:
2229             free_ir_constant(constant_from_node(node));
2230             break;
2231         case HLSL_IR_DEREF:
2232             free_ir_deref(deref_from_node(node));
2233             break;
2234         case HLSL_IR_SWIZZLE:
2235             free_ir_swizzle(swizzle_from_node(node));
2236             break;
2237         case HLSL_IR_CONSTRUCTOR:
2238             free_ir_constructor(constructor_from_node(node));
2239             break;
2240         case HLSL_IR_EXPR:
2241             free_ir_expr(expr_from_node(node));
2242             break;
2243         case HLSL_IR_ASSIGNMENT:
2244             free_ir_assignment(assignment_from_node(node));
2245             break;
2246         case HLSL_IR_IF:
2247             free_ir_if(if_from_node(node));
2248             break;
2249         case HLSL_IR_JUMP:
2250             free_ir_jump(jump_from_node(node));
2251             break;
2252         default:
2253             FIXME("Unsupported node type %s\n", debug_node_type(node->type));
2254     }
2255 }
2256 
2257 static void free_function_decl(struct hlsl_ir_function_decl *decl)
2258 {
2259     d3dcompiler_free((void *)decl->semantic);
2260     d3dcompiler_free(decl->parameters);
2261     free_instr_list(decl->body);
2262     d3dcompiler_free(decl);
2263 }
2264 
2265 static void free_function_decl_rb(struct wine_rb_entry *entry, void *context)
2266 {
2267     free_function_decl(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry));
2268 }
2269 
2270 static void free_function(struct hlsl_ir_function *func)
2271 {
2272     wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL);
2273     d3dcompiler_free((void *)func->name);
2274     d3dcompiler_free(func);
2275 }
2276 
2277 void free_function_rb(struct wine_rb_entry *entry, void *context)
2278 {
2279     free_function(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry));
2280 }
2281 
2282 void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, BOOL intrinsic)
2283 {
2284     struct hlsl_ir_function *func;
2285     struct wine_rb_entry *func_entry, *old_entry;
2286 
2287     func_entry = wine_rb_get(funcs, name);
2288     if (func_entry)
2289     {
2290         func = WINE_RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry);
2291         if (intrinsic != func->intrinsic)
2292         {
2293             if (intrinsic)
2294             {
2295                 ERR("Redeclaring a user defined function as an intrinsic.\n");
2296                 return;
2297             }
2298             TRACE("Function %s redeclared as a user defined function.\n", debugstr_a(name));
2299             func->intrinsic = intrinsic;
2300             wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL);
2301             wine_rb_init(&func->overloads, compare_function_decl_rb);
2302         }
2303         decl->func = func;
2304         if ((old_entry = wine_rb_get(&func->overloads, decl->parameters)))
2305         {
2306             struct hlsl_ir_function_decl *old_decl =
2307                     WINE_RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry);
2308 
2309             if (!decl->body)
2310             {
2311                 free_function_decl(decl);
2312                 d3dcompiler_free(name);
2313                 return;
2314             }
2315             wine_rb_remove(&func->overloads, old_entry);
2316             free_function_decl(old_decl);
2317         }
2318         wine_rb_put(&func->overloads, decl->parameters, &decl->entry);
2319         d3dcompiler_free(name);
2320         return;
2321     }
2322     func = d3dcompiler_alloc(sizeof(*func));
2323     func->name = name;
2324     wine_rb_init(&func->overloads, compare_function_decl_rb);
2325     decl->func = func;
2326     wine_rb_put(&func->overloads, decl->parameters, &decl->entry);
2327     func->intrinsic = intrinsic;
2328     wine_rb_put(funcs, func->name, &func->entry);
2329 }
2330