[CRT] crtdefs.h: Wrap localeinfo_struct in ifdef
[reactos.git] / dll / directx / wine / 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 <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 }