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