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