* Sync up to trunk head (r65426).
[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 struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
804 enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
805 {
806 struct hlsl_type *type;
807
808 type = d3dcompiler_alloc(sizeof(*type));
809 if (!type)
810 {
811 ERR("Out of memory\n");
812 return NULL;
813 }
814 type->name = name;
815 type->type = type_class;
816 type->base_type = base_type;
817 type->dimx = dimx;
818 type->dimy = dimy;
819
820 list_add_tail(&hlsl_ctx.types, &type->entry);
821
822 return type;
823 }
824
825 struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size)
826 {
827 struct hlsl_type *type = new_hlsl_type(NULL, HLSL_CLASS_ARRAY, HLSL_TYPE_FLOAT, 1, 1);
828
829 if (!type)
830 return NULL;
831
832 type->modifiers = basic_type->modifiers;
833 type->e.array.elements_count = array_size;
834 type->e.array.type = basic_type;
835 return type;
836 }
837
838 struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive)
839 {
840 struct wine_rb_entry *entry = wine_rb_get(&scope->types, name);
841 if (entry)
842 return WINE_RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry);
843
844 if (recursive && scope->upper)
845 return get_type(scope->upper, name, recursive);
846 return NULL;
847 }
848
849 BOOL find_function(const char *name)
850 {
851 return wine_rb_get(&hlsl_ctx.functions, name) != NULL;
852 }
853
854 unsigned int components_count_type(struct hlsl_type *type)
855 {
856 unsigned int count = 0;
857 struct hlsl_struct_field *field;
858
859 if (type->type <= HLSL_CLASS_LAST_NUMERIC)
860 {
861 return type->dimx * type->dimy;
862 }
863 if (type->type == HLSL_CLASS_ARRAY)
864 {
865 return components_count_type(type->e.array.type) * type->e.array.elements_count;
866 }
867 if (type->type != HLSL_CLASS_STRUCT)
868 {
869 ERR("Unexpected data type %s.\n", debug_hlsl_type(type));
870 return 0;
871 }
872
873 LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
874 {
875 count += components_count_type(field->type);
876 }
877 return count;
878 }
879
880 BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
881 {
882 if (t1 == t2)
883 return TRUE;
884
885 if (t1->type != t2->type)
886 return FALSE;
887 if (t1->base_type != t2->base_type)
888 return FALSE;
889 if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim)
890 return FALSE;
891 if ((t1->modifiers & HLSL_MODIFIERS_COMPARISON_MASK)
892 != (t2->modifiers & HLSL_MODIFIERS_COMPARISON_MASK))
893 return FALSE;
894 if (t1->dimx != t2->dimx)
895 return FALSE;
896 if (t1->dimy != t2->dimy)
897 return FALSE;
898 if (t1->type == HLSL_CLASS_STRUCT)
899 {
900 struct list *t1cur, *t2cur;
901 struct hlsl_struct_field *t1field, *t2field;
902
903 t1cur = list_head(t1->e.elements);
904 t2cur = list_head(t2->e.elements);
905 while (t1cur && t2cur)
906 {
907 t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry);
908 t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry);
909 if (!compare_hlsl_types(t1field->type, t2field->type))
910 return FALSE;
911 if (strcmp(t1field->name, t2field->name))
912 return FALSE;
913 t1cur = list_next(t1->e.elements, t1cur);
914 t2cur = list_next(t2->e.elements, t2cur);
915 }
916 if (t1cur != t2cur)
917 return FALSE;
918 }
919 if (t1->type == HLSL_CLASS_ARRAY)
920 return t1->e.array.elements_count == t2->e.array.elements_count
921 && compare_hlsl_types(t1->e.array.type, t2->e.array.type);
922
923 return TRUE;
924 }
925
926 struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
927 {
928 struct hlsl_type *type;
929 struct hlsl_struct_field *old_field, *field;
930
931 type = d3dcompiler_alloc(sizeof(*type));
932 if (!type)
933 {
934 ERR("Out of memory\n");
935 return NULL;
936 }
937 if (old->name)
938 {
939 type->name = d3dcompiler_strdup(old->name);
940 if (!type->name)
941 {
942 d3dcompiler_free(type);
943 return NULL;
944 }
945 }
946 type->type = old->type;
947 type->base_type = old->base_type;
948 type->dimx = old->dimx;
949 type->dimy = old->dimy;
950 type->modifiers = old->modifiers;
951 type->sampler_dim = old->sampler_dim;
952 switch (old->type)
953 {
954 case HLSL_CLASS_ARRAY:
955 type->e.array.type = old->e.array.type;
956 type->e.array.elements_count = old->e.array.elements_count;
957 break;
958 case HLSL_CLASS_STRUCT:
959 type->e.elements = d3dcompiler_alloc(sizeof(*type->e.elements));
960 if (!type->e.elements)
961 {
962 d3dcompiler_free((void *)type->name);
963 d3dcompiler_free(type);
964 return NULL;
965 }
966 list_init(type->e.elements);
967 LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry)
968 {
969 field = d3dcompiler_alloc(sizeof(*field));
970 if (!field)
971 {
972 LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry)
973 {
974 d3dcompiler_free((void *)field->semantic);
975 d3dcompiler_free((void *)field->name);
976 d3dcompiler_free(field);
977 }
978 d3dcompiler_free(type->e.elements);
979 d3dcompiler_free((void *)type->name);
980 d3dcompiler_free(type);
981 return NULL;
982 }
983 field->type = clone_hlsl_type(old_field->type);
984 field->name = d3dcompiler_strdup(old_field->name);
985 if (old_field->semantic)
986 field->semantic = d3dcompiler_strdup(old_field->semantic);
987 field->modifiers = old_field->modifiers;
988 list_add_tail(type->e.elements, &field->entry);
989 }
990 break;
991 default:
992 break;
993 }
994
995 list_add_tail(&hlsl_ctx.types, &type->entry);
996 return type;
997 }
998
999 static BOOL convertible_data_type(struct hlsl_type *type)
1000 {
1001 return type->type != HLSL_CLASS_OBJECT;
1002 }
1003
1004 BOOL compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1005 {
1006 if (!convertible_data_type(t1) || !convertible_data_type(t2))
1007 return FALSE;
1008
1009 if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
1010 {
1011 /* Scalar vars can be cast to pretty much everything */
1012 if (t1->dimx == 1 && t1->dimy == 1)
1013 return TRUE;
1014
1015 if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
1016 return t1->dimx >= t2->dimx;
1017 }
1018
1019 /* The other way around is true too i.e. whatever to scalar */
1020 if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1)
1021 return TRUE;
1022
1023 if (t1->type == HLSL_CLASS_ARRAY)
1024 {
1025 if (compare_hlsl_types(t1->e.array.type, t2))
1026 /* e.g. float4[3] to float4 is allowed */
1027 return TRUE;
1028
1029 if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
1030 return components_count_type(t1) >= components_count_type(t2);
1031 else
1032 return components_count_type(t1) == components_count_type(t2);
1033 }
1034
1035 if (t1->type == HLSL_CLASS_STRUCT)
1036 return components_count_type(t1) >= components_count_type(t2);
1037
1038 if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
1039 return components_count_type(t1) == components_count_type(t2);
1040
1041 if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1042 {
1043 if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1044 return TRUE;
1045
1046 /* Matrix-vector conversion is apparently allowed if they have the same components count */
1047 if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1048 && components_count_type(t1) == components_count_type(t2))
1049 return TRUE;
1050 return FALSE;
1051 }
1052
1053 if (components_count_type(t1) >= components_count_type(t2))
1054 return TRUE;
1055 return FALSE;
1056 }
1057
1058 static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1059 {
1060 if (!convertible_data_type(t1) || !convertible_data_type(t2))
1061 return FALSE;
1062
1063 if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
1064 {
1065 /* Scalar vars can be converted to any other numeric data type */
1066 if (t1->dimx == 1 && t1->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1067 return TRUE;
1068 /* The other way around is true too */
1069 if (t2->dimx == 1 && t2->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1070 return TRUE;
1071 }
1072
1073 if (t1->type == HLSL_CLASS_ARRAY && t2->type == HLSL_CLASS_ARRAY)
1074 {
1075 return components_count_type(t1) == components_count_type(t2);
1076 }
1077
1078 if ((t1->type == HLSL_CLASS_ARRAY && t2->type <= HLSL_CLASS_LAST_NUMERIC)
1079 || (t1->type <= HLSL_CLASS_LAST_NUMERIC && t2->type == HLSL_CLASS_ARRAY))
1080 {
1081 /* e.g. float4[3] to float4 is allowed */
1082 if (t1->type == HLSL_CLASS_ARRAY && compare_hlsl_types(t1->e.array.type, t2))
1083 return TRUE;
1084 if (components_count_type(t1) == components_count_type(t2))
1085 return TRUE;
1086 return FALSE;
1087 }
1088
1089 if (t1->type <= HLSL_CLASS_VECTOR && t2->type <= HLSL_CLASS_VECTOR)
1090 {
1091 if (t1->dimx >= t2->dimx)
1092 return TRUE;
1093 return FALSE;
1094 }
1095
1096 if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1097 {
1098 if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX
1099 && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1100 return TRUE;
1101
1102 /* Matrix-vector conversion is apparently allowed if they have the same components count */
1103 if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1104 && components_count_type(t1) == components_count_type(t2))
1105 return TRUE;
1106 return FALSE;
1107 }
1108
1109 if (t1->type == HLSL_CLASS_STRUCT && t2->type == HLSL_CLASS_STRUCT)
1110 return compare_hlsl_types(t1, t2);
1111
1112 return FALSE;
1113 }
1114
1115 static BOOL expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
1116 {
1117 if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR)
1118 return FALSE;
1119
1120 /* Scalar vars can be converted to pretty much everything */
1121 if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1))
1122 return TRUE;
1123
1124 if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
1125 return TRUE;
1126
1127 if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
1128 {
1129 /* Matrix-vector conversion is apparently allowed if either they have the same components
1130 count or the matrix is nx1 or 1xn */
1131 if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
1132 {
1133 if (components_count_type(t1) == components_count_type(t2))
1134 return TRUE;
1135
1136 return (t1->type == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1))
1137 || (t2->type == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1));
1138 }
1139
1140 /* Both matrices */
1141 if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
1142 || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy))
1143 return TRUE;
1144 }
1145
1146 return FALSE;
1147 }
1148
1149 static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2)
1150 {
1151 enum hlsl_base_type types[] =
1152 {
1153 HLSL_TYPE_BOOL,
1154 HLSL_TYPE_INT,
1155 HLSL_TYPE_UINT,
1156 HLSL_TYPE_HALF,
1157 HLSL_TYPE_FLOAT,
1158 HLSL_TYPE_DOUBLE,
1159 };
1160 int t1_idx = -1, t2_idx = -1, i;
1161
1162 for (i = 0; i < sizeof(types) / sizeof(types[0]); ++i)
1163 {
1164 /* Always convert away from HLSL_TYPE_HALF */
1165 if (t1 == types[i])
1166 t1_idx = t1 == HLSL_TYPE_HALF ? i + 1 : i;
1167 if (t2 == types[i])
1168 t2_idx = t2 == HLSL_TYPE_HALF ? i + 1 : i;
1169
1170 if (t1_idx != -1 && t2_idx != -1)
1171 break;
1172 }
1173 if (t1_idx == -1 || t2_idx == -1)
1174 {
1175 FIXME("Unexpected base type.\n");
1176 return HLSL_TYPE_FLOAT;
1177 }
1178 return t1_idx >= t2_idx ? t1 : t2;
1179 }
1180
1181 static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type *t2,
1182 struct source_location *loc)
1183 {
1184 enum hlsl_type_class type;
1185 enum hlsl_base_type base;
1186 unsigned int dimx, dimy;
1187
1188 if (t1->type > HLSL_CLASS_LAST_NUMERIC || t2->type > HLSL_CLASS_LAST_NUMERIC)
1189 {
1190 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
1191 "non scalar/vector/matrix data type in expression");
1192 return NULL;
1193 }
1194
1195 if (compare_hlsl_types(t1, t2))
1196 return t1;
1197
1198 if (!expr_compatible_data_types(t1, t2))
1199 {
1200 hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
1201 "expression data types are incompatible");
1202 return NULL;
1203 }
1204
1205 if (t1->base_type == t2->base_type)
1206 base = t1->base_type;
1207 else
1208 base = expr_common_base_type(t1->base_type, t2->base_type);
1209
1210 if (t1->dimx == 1 && t1->dimy == 1)
1211 {
1212 type = t2->type;
1213 dimx = t2->dimx;
1214 dimy = t2->dimy;
1215 }
1216 else if (t2->dimx == 1 && t2->dimy == 1)
1217 {
1218 type = t1->type;
1219 dimx = t1->dimx;
1220 dimy = t1->dimy;
1221 }
1222 else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX)
1223 {
1224 type = HLSL_CLASS_MATRIX;
1225 dimx = min(t1->dimx, t2->dimx);
1226 dimy = min(t1->dimy, t2->dimy);
1227 }
1228 else
1229 {
1230 /* Two vectors or a vector and a matrix (matrix must be 1xn or nx1) */
1231 unsigned int max_dim_1, max_dim_2;
1232
1233 max_dim_1 = max(t1->dimx, t1->dimy);
1234 max_dim_2 = max(t2->dimx, t2->dimy);
1235 if (t1->dimx * t1->dimy == t2->dimx * t2->dimy)
1236 {
1237 type = HLSL_CLASS_VECTOR;
1238 dimx = max(t1->dimx, t2->dimx);
1239 dimy = 1;
1240 }
1241 else if (max_dim_1 <= max_dim_2)
1242 {
1243 type = t1->type;
1244 if (type == HLSL_CLASS_VECTOR)
1245 {
1246 dimx = max_dim_1;
1247 dimy = 1;
1248 }
1249 else
1250 {
1251 dimx = t1->dimx;
1252 dimy = t1->dimy;
1253 }
1254 }
1255 else
1256 {
1257 type = t2->type;
1258 if (type == HLSL_CLASS_VECTOR)
1259 {
1260 dimx = max_dim_2;
1261 dimy = 1;
1262 }
1263 else
1264 {
1265 dimx = t2->dimx;
1266 dimy = t2->dimy;
1267 }
1268 }
1269 }
1270
1271 return new_hlsl_type(NULL, type, base, dimx, dimy);
1272 }
1273
1274 static struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *type,
1275 struct source_location *loc)
1276 {
1277 struct hlsl_ir_expr *cast;
1278 struct hlsl_ir_node *operands[3];
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 operands[0] = node;
1284 operands[1] = operands[2] = NULL;
1285 cast = new_expr(HLSL_IR_UNOP_CAST, operands, loc);
1286 if (!cast)
1287 return NULL;
1288 cast->node.data_type = type;
1289 return &cast->node;
1290 }
1291
1292 struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
1293 struct source_location *loc)
1294 {
1295 struct hlsl_ir_expr *expr = d3dcompiler_alloc(sizeof(*expr));
1296 struct hlsl_type *type;
1297 unsigned int i;
1298
1299 if (!expr)
1300 {
1301 ERR("Out of memory\n");
1302 return NULL;
1303 }
1304 expr->node.type = HLSL_IR_EXPR;
1305 expr->node.loc = *loc;
1306 type = operands[0]->data_type;
1307 for (i = 1; i <= 2; ++i)
1308 {
1309 if (!operands[i])
1310 break;
1311 type = expr_common_type(type, operands[i]->data_type, loc);
1312 if (!type)
1313 {
1314 d3dcompiler_free(expr);
1315 return NULL;
1316 }
1317 }
1318 for (i = 0; i <= 2; ++i)
1319 {
1320 if (!operands[i])
1321 break;
1322 if (compare_hlsl_types(operands[i]->data_type, type))
1323 continue;
1324 TRACE("Implicitly converting %s into %s in an expression\n", debug_hlsl_type(operands[i]->data_type), debug_hlsl_type(type));
1325 if (operands[i]->data_type->dimx * operands[i]->data_type->dimy != 1
1326 && operands[i]->data_type->dimx * operands[i]->data_type->dimy != type->dimx * type->dimy)
1327 {
1328 hlsl_report_message(operands[i]->loc.file,
1329 operands[i]->loc.line, operands[i]->loc.col, HLSL_LEVEL_WARNING,
1330 "implicit truncation of vector/matrix type");
1331 }
1332 operands[i] = implicit_conversion(operands[i], type, &operands[i]->loc);
1333 if (!operands[i])
1334 {
1335 ERR("Impossible to convert expression operand %u to %s\n", i + 1, debug_hlsl_type(type));
1336 d3dcompiler_free(expr);
1337 return NULL;
1338 }
1339 }
1340 expr->node.data_type = type;
1341 expr->op = op;
1342 expr->operands[0] = operands[0];
1343 expr->operands[1] = operands[1];
1344 expr->operands[2] = operands[2];
1345
1346 return expr;
1347 }
1348
1349 struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
1350 struct source_location *loc)
1351 {
1352 struct hlsl_ir_expr *cast;
1353 struct hlsl_ir_node *operands[3];
1354
1355 operands[0] = node;
1356 operands[1] = operands[2] = NULL;
1357 cast = new_expr(HLSL_IR_UNOP_CAST, operands, loc);
1358 if (cast)
1359 cast->node.data_type = type;
1360 return cast;
1361 }
1362
1363 struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1364 struct source_location *loc)
1365 {
1366 struct hlsl_ir_expr *expr;
1367 struct hlsl_ir_node *ops[3];
1368
1369 ops[0] = op1;
1370 ops[1] = op2;
1371 ops[2] = NULL;
1372 expr = new_expr(HLSL_IR_BINOP_MUL, ops, loc);
1373 return expr;
1374 }
1375
1376 struct hlsl_ir_expr *hlsl_div(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1377 struct source_location *loc)
1378 {
1379 struct hlsl_ir_expr *expr;
1380 struct hlsl_ir_node *ops[3];
1381
1382 ops[0] = op1;
1383 ops[1] = op2;
1384 ops[2] = NULL;
1385 expr = new_expr(HLSL_IR_BINOP_DIV, ops, loc);
1386 return expr;
1387 }
1388
1389 struct hlsl_ir_expr *hlsl_mod(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1390 struct source_location *loc)
1391 {
1392 struct hlsl_ir_expr *expr;
1393 struct hlsl_ir_node *ops[3];
1394
1395 ops[0] = op1;
1396 ops[1] = op2;
1397 ops[2] = NULL;
1398 expr = new_expr(HLSL_IR_BINOP_MOD, ops, loc);
1399 return expr;
1400 }
1401
1402 struct hlsl_ir_expr *hlsl_add(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1403 struct source_location *loc)
1404 {
1405 struct hlsl_ir_expr *expr;
1406 struct hlsl_ir_node *ops[3];
1407
1408 ops[0] = op1;
1409 ops[1] = op2;
1410 ops[2] = NULL;
1411 expr = new_expr(HLSL_IR_BINOP_ADD, ops, loc);
1412 return expr;
1413 }
1414
1415 struct hlsl_ir_expr *hlsl_sub(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1416 struct source_location *loc)
1417 {
1418 struct hlsl_ir_expr *expr;
1419 struct hlsl_ir_node *ops[3];
1420
1421 ops[0] = op1;
1422 ops[1] = op2;
1423 ops[2] = NULL;
1424 expr = new_expr(HLSL_IR_BINOP_SUB, ops, loc);
1425 return expr;
1426 }
1427
1428 struct hlsl_ir_expr *hlsl_lt(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1429 struct source_location *loc)
1430 {
1431 struct hlsl_ir_expr *expr;
1432 struct hlsl_ir_node *ops[3];
1433
1434 ops[0] = op1;
1435 ops[1] = op2;
1436 ops[2] = NULL;
1437 expr = new_expr(HLSL_IR_BINOP_LESS, ops, loc);
1438 return expr;
1439 }
1440
1441 struct hlsl_ir_expr *hlsl_gt(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1442 struct source_location *loc)
1443 {
1444 struct hlsl_ir_expr *expr;
1445 struct hlsl_ir_node *ops[3];
1446
1447 ops[0] = op1;
1448 ops[1] = op2;
1449 ops[2] = NULL;
1450 expr = new_expr(HLSL_IR_BINOP_GREATER, ops, loc);
1451 return expr;
1452 }
1453
1454 struct hlsl_ir_expr *hlsl_le(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1455 struct source_location *loc)
1456 {
1457 struct hlsl_ir_expr *expr;
1458 struct hlsl_ir_node *ops[3];
1459
1460 ops[0] = op1;
1461 ops[1] = op2;
1462 ops[2] = NULL;
1463 expr = new_expr(HLSL_IR_BINOP_LEQUAL, ops, loc);
1464 return expr;
1465 }
1466
1467 struct hlsl_ir_expr *hlsl_ge(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1468 struct source_location *loc)
1469 {
1470 struct hlsl_ir_expr *expr;
1471 struct hlsl_ir_node *ops[3];
1472
1473 ops[0] = op1;
1474 ops[1] = op2;
1475 ops[2] = NULL;
1476 expr = new_expr(HLSL_IR_BINOP_GEQUAL, ops, loc);
1477 return expr;
1478 }
1479
1480 struct hlsl_ir_expr *hlsl_eq(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1481 struct source_location *loc)
1482 {
1483 struct hlsl_ir_expr *expr;
1484 struct hlsl_ir_node *ops[3];
1485
1486 ops[0] = op1;
1487 ops[1] = op2;
1488 ops[2] = NULL;
1489 expr = new_expr(HLSL_IR_BINOP_EQUAL, ops, loc);
1490 return expr;
1491 }
1492
1493 struct hlsl_ir_expr *hlsl_ne(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
1494 struct source_location *loc)
1495 {
1496 struct hlsl_ir_expr *expr;
1497 struct hlsl_ir_node *ops[3];
1498
1499 ops[0] = op1;
1500 ops[1] = op2;
1501 ops[2] = NULL;
1502 expr = new_expr(HLSL_IR_BINOP_NEQUAL, ops, loc);
1503 return expr;
1504 }
1505
1506 struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
1507 {
1508 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1509
1510 if (!deref)
1511 {
1512 ERR("Out of memory.\n");
1513 return NULL;
1514 }
1515 deref->node.type = HLSL_IR_DEREF;
1516 deref->node.data_type = var->node.data_type;
1517 deref->type = HLSL_IR_DEREF_VAR;
1518 deref->v.var = var;
1519 return deref;
1520 }
1521
1522 struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field)
1523 {
1524 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
1525
1526 if (!deref)
1527 {
1528 ERR("Out of memory.\n");
1529 return NULL;
1530 }
1531 deref->node.type = HLSL_IR_DEREF;
1532 deref->node.data_type = field->type;
1533 deref->type = HLSL_IR_DEREF_RECORD;
1534 if (record->type == HLSL_IR_VAR)
1535 deref->v.record.record = &new_var_deref(var_from_node(record))->node;
1536 else
1537 deref->v.record.record = record;
1538 deref->v.record.field = field;
1539 return deref;
1540 }
1541
1542 static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
1543 {
1544 static const enum hlsl_ir_expr_op ops[] =
1545 {
1546 0,
1547 HLSL_IR_BINOP_ADD,
1548 HLSL_IR_BINOP_SUB,
1549 HLSL_IR_BINOP_MUL,
1550 HLSL_IR_BINOP_DIV,
1551 HLSL_IR_BINOP_MOD,
1552 HLSL_IR_BINOP_LSHIFT,
1553 HLSL_IR_BINOP_RSHIFT,
1554 HLSL_IR_BINOP_BIT_AND,
1555 HLSL_IR_BINOP_BIT_OR,
1556 HLSL_IR_BINOP_BIT_XOR,
1557 };
1558
1559 return ops[op];
1560 }
1561
1562 struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assign_op assign_op,
1563 DWORD writemask, struct hlsl_ir_node *right)
1564 {
1565 struct hlsl_ir_expr *expr;
1566 struct hlsl_ir_assignment *assign = d3dcompiler_alloc(sizeof(*assign));
1567 struct hlsl_type *type;
1568 struct hlsl_ir_node *lhs, *rhs;
1569
1570 if (!assign)
1571 {
1572 ERR("Out of memory\n");
1573 return NULL;
1574 }
1575
1576 TRACE("Creating proper assignment expression.\n");
1577 rhs = right;
1578 if (writemask == BWRITERSP_WRITEMASK_ALL)
1579 type = left->data_type;
1580 else
1581 {
1582 FIXME("Assignments with writemasks not supported yet.\n");
1583 type = NULL;
1584 }
1585 assign->node.type = HLSL_IR_ASSIGNMENT;
1586 assign->node.loc = left->loc;
1587 assign->node.data_type = type;
1588 assign->writemask = writemask;
1589 FIXME("Check for casts in the lhs.\n");
1590
1591 lhs = left;
1592 if (lhs->type == HLSL_IR_VAR)
1593 {
1594 struct hlsl_ir_deref *lhs_deref = new_var_deref(var_from_node(lhs));
1595 lhs = &lhs_deref->node;
1596 }
1597 /* FIXME: check for invalid writemasks on the lhs. */
1598
1599 if (!compare_hlsl_types(type, rhs->data_type))
1600 {
1601 struct hlsl_ir_node *converted_rhs;
1602
1603 if (!implicit_compatible_data_types(rhs->data_type, type))
1604 {
1605 hlsl_report_message(rhs->loc.file, rhs->loc.line, rhs->loc.col, HLSL_LEVEL_ERROR,
1606 "can't implicitly convert %s to %s",
1607 debug_hlsl_type(rhs->data_type), debug_hlsl_type(type));
1608 free_instr(lhs);
1609 free_instr(rhs);
1610 d3dcompiler_free(assign);
1611 return NULL;
1612 }
1613 if (lhs->data_type->dimx * lhs->data_type->dimy < rhs->data_type->dimx * rhs->data_type->dimy)
1614 hlsl_report_message(rhs->loc.file, rhs->loc.line, rhs->loc.col, HLSL_LEVEL_WARNING,
1615 "implicit truncation of vector type");
1616
1617 converted_rhs = implicit_conversion(rhs, type, &rhs->loc);
1618 if (!converted_rhs)
1619 {
1620 ERR("Couldn't implicitly convert expression to %s.\n", debug_hlsl_type(type));
1621 free_instr(lhs);
1622 free_instr(rhs);
1623 d3dcompiler_free(assign);
1624 return NULL;
1625 }
1626 rhs = converted_rhs;
1627 }
1628
1629 assign->lhs = lhs;
1630 if (assign_op != ASSIGN_OP_ASSIGN)
1631 {
1632 struct hlsl_ir_node *operands[3];
1633 enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
1634
1635 if (lhs->type != HLSL_IR_DEREF || deref_from_node(lhs)->type != HLSL_IR_DEREF_VAR)
1636 {
1637 FIXME("LHS expression not supported in compound assignments yet.\n");
1638 assign->rhs = rhs;
1639 }
1640 else
1641 {
1642 struct hlsl_ir_deref *lhs_deref = deref_from_node(lhs), *new_deref;
1643
1644 TRACE("Adding an expression for the compound assignment.\n");
1645 new_deref = new_var_deref(lhs_deref->v.var);
1646 operands[0] = &new_deref->node;
1647 operands[1] = rhs;
1648 operands[2] = NULL;
1649 expr = new_expr(op, operands, &left->loc);
1650 assign->rhs = &expr->node;
1651 }
1652 }
1653 else
1654 assign->rhs = rhs;
1655
1656 return &assign->node;
1657 }
1658
1659 static int compare_hlsl_types_rb(const void *key, const struct wine_rb_entry *entry)
1660 {
1661 const char *name = key;
1662 const struct hlsl_type *type = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_type, scope_entry);
1663
1664 if (name == type->name)
1665 return 0;
1666
1667 if (!name || !type->name)
1668 {
1669 ERR("hlsl_type without a name in a scope?\n");
1670 return -1;
1671 }
1672 return strcmp(name, type->name);
1673 }
1674
1675 static inline void *d3dcompiler_alloc_rb(size_t size)
1676 {
1677 return d3dcompiler_alloc(size);
1678 }
1679
1680 static inline void *d3dcompiler_realloc_rb(void *ptr, size_t size)
1681 {
1682 return d3dcompiler_realloc(ptr, size);
1683 }
1684
1685 static inline void d3dcompiler_free_rb(void *ptr)
1686 {
1687 d3dcompiler_free(ptr);
1688 }
1689 static const struct wine_rb_functions hlsl_type_rb_funcs =
1690 {
1691 d3dcompiler_alloc_rb,
1692 d3dcompiler_realloc_rb,
1693 d3dcompiler_free_rb,
1694 compare_hlsl_types_rb,
1695 };
1696
1697 void push_scope(struct hlsl_parse_ctx *ctx)
1698 {
1699 struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope));
1700
1701 if (!new_scope)
1702 {
1703 ERR("Out of memory!\n");
1704 return;
1705 }
1706 TRACE("Pushing a new scope\n");
1707 list_init(&new_scope->vars);
1708 if (wine_rb_init(&new_scope->types, &hlsl_type_rb_funcs) == -1)
1709 {
1710 ERR("Failed to initialize types rbtree.\n");
1711 d3dcompiler_free(new_scope);
1712 return;
1713 }
1714 new_scope->upper = ctx->cur_scope;
1715 ctx->cur_scope = new_scope;
1716 list_add_tail(&ctx->scopes, &new_scope->entry);
1717 }
1718
1719 BOOL pop_scope(struct hlsl_parse_ctx *ctx)
1720 {
1721 struct hlsl_scope *prev_scope = ctx->cur_scope->upper;
1722 if (!prev_scope)
1723 return FALSE;
1724
1725 TRACE("Popping current scope\n");
1726 ctx->cur_scope = prev_scope;
1727 return TRUE;
1728 }
1729
1730 struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, struct list *parameters)
1731 {
1732 struct hlsl_ir_function_decl *decl;
1733
1734 decl = d3dcompiler_alloc(sizeof(*decl));
1735 if (!decl)
1736 {
1737 ERR("Out of memory.\n");
1738 return NULL;
1739 }
1740 decl->node.type = HLSL_IR_FUNCTION_DECL;
1741 decl->node.data_type = return_type;
1742 decl->parameters = parameters;
1743
1744 return decl;
1745 }
1746
1747 static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
1748 {
1749 if (t1->type != t2->type)
1750 {
1751 if (!((t1->type == HLSL_CLASS_SCALAR && t2->type == HLSL_CLASS_VECTOR)
1752 || (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_SCALAR)))
1753 return t1->type - t2->type;
1754 }
1755 if (t1->base_type != t2->base_type)
1756 return t1->base_type - t2->base_type;
1757 if (t1->base_type == HLSL_TYPE_SAMPLER && t1->sampler_dim != t2->sampler_dim)
1758 return t1->sampler_dim - t2->sampler_dim;
1759 if (t1->dimx != t2->dimx)
1760 return t1->dimx - t2->dimx;
1761 if (t1->dimy != t2->dimy)
1762 return t1->dimx - t2->dimx;
1763 if (t1->type == HLSL_CLASS_STRUCT)
1764 {
1765 struct list *t1cur, *t2cur;
1766 struct hlsl_struct_field *t1field, *t2field;
1767 int r;
1768
1769 t1cur = list_head(t1->e.elements);
1770 t2cur = list_head(t2->e.elements);
1771 while (t1cur && t2cur)
1772 {
1773 t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry);
1774 t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry);
1775 if ((r = compare_param_hlsl_types(t1field->type, t2field->type)))
1776 return r;
1777 if ((r = strcmp(t1field->name, t2field->name)))
1778 return r;
1779 t1cur = list_next(t1->e.elements, t1cur);
1780 t2cur = list_next(t2->e.elements, t2cur);
1781 }
1782 if (t1cur != t2cur)
1783 return t1cur ? 1 : -1;
1784 return 0;
1785 }
1786 if (t1->type == HLSL_CLASS_ARRAY)
1787 {
1788 if (t1->e.array.elements_count != t2->e.array.elements_count)
1789 return t1->e.array.elements_count - t2->e.array.elements_count;
1790 return compare_param_hlsl_types(t1->e.array.type, t2->e.array.type);
1791 }
1792
1793 return 0;
1794 }
1795
1796 static int compare_function_decl_rb(const void *key, const struct wine_rb_entry *entry)
1797 {
1798 const struct list *params = key;
1799 const struct hlsl_ir_function_decl *decl = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry);
1800 int params_count = params ? list_count(params) : 0;
1801 int decl_params_count = decl->parameters ? list_count(decl->parameters) : 0;
1802 int r;
1803 struct list *p1cur, *p2cur;
1804
1805 if (params_count != decl_params_count)
1806 return params_count - decl_params_count;
1807
1808 p1cur = params ? list_head(params) : NULL;
1809 p2cur = decl->parameters ? list_head(decl->parameters) : NULL;
1810 while (p1cur && p2cur)
1811 {
1812 struct hlsl_ir_var *p1, *p2;
1813 p1 = LIST_ENTRY(p1cur, struct hlsl_ir_var, node.entry);
1814 p2 = LIST_ENTRY(p2cur, struct hlsl_ir_var, node.entry);
1815 if ((r = compare_param_hlsl_types(p1->node.data_type, p2->node.data_type)))
1816 return r;
1817 p1cur = list_next(params, p1cur);
1818 p2cur = list_next(decl->parameters, p2cur);
1819 }
1820 return 0;
1821 }
1822
1823 static const struct wine_rb_functions hlsl_ir_function_decl_rb_funcs =
1824 {
1825 d3dcompiler_alloc_rb,
1826 d3dcompiler_realloc_rb,
1827 d3dcompiler_free_rb,
1828 compare_function_decl_rb,
1829 };
1830
1831 static int compare_function_rb(const void *key, const struct wine_rb_entry *entry)
1832 {
1833 const char *name = key;
1834 const struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry);
1835
1836 return strcmp(name, func->name);
1837 }
1838
1839 static const struct wine_rb_functions function_rb_funcs =
1840 {
1841 d3dcompiler_alloc_rb,
1842 d3dcompiler_realloc_rb,
1843 d3dcompiler_free_rb,
1844 compare_function_rb,
1845 };
1846
1847 void init_functions_tree(struct wine_rb_tree *funcs)
1848 {
1849 if (wine_rb_init(&hlsl_ctx.functions, &function_rb_funcs) == -1)
1850 ERR("Failed to initialize functions rbtree.\n");
1851 }
1852
1853 static const char *debug_base_type(const struct hlsl_type *type)
1854 {
1855 const char *name = "(unknown)";
1856
1857 switch (type->base_type)
1858 {
1859 case HLSL_TYPE_FLOAT: name = "float"; break;
1860 case HLSL_TYPE_HALF: name = "half"; break;
1861 case HLSL_TYPE_DOUBLE: name = "double"; break;
1862 case HLSL_TYPE_INT: name = "int"; break;
1863 case HLSL_TYPE_UINT: name = "uint"; break;
1864 case HLSL_TYPE_BOOL: name = "bool"; break;
1865 case HLSL_TYPE_SAMPLER:
1866 switch (type->sampler_dim)
1867 {
1868 case HLSL_SAMPLER_DIM_GENERIC: name = "sampler"; break;
1869 case HLSL_SAMPLER_DIM_1D: name = "sampler1D"; break;
1870 case HLSL_SAMPLER_DIM_2D: name = "sampler2D"; break;
1871 case HLSL_SAMPLER_DIM_3D: name = "sampler3D"; break;
1872 case HLSL_SAMPLER_DIM_CUBE: name = "samplerCUBE"; break;
1873 }
1874 break;
1875 default:
1876 FIXME("Unhandled case %u\n", type->base_type);
1877 }
1878 return name;
1879 }
1880
1881 const char *debug_hlsl_type(const struct hlsl_type *type)
1882 {
1883 const char *name;
1884
1885 if (type->name)
1886 return debugstr_a(type->name);
1887
1888 if (type->type == HLSL_CLASS_STRUCT)
1889 return "<anonymous struct>";
1890
1891 if (type->type == HLSL_CLASS_ARRAY)
1892 {
1893 name = debug_base_type(type->e.array.type);
1894 return wine_dbg_sprintf("%s[%u]", name, type->e.array.elements_count);
1895 }
1896
1897 name = debug_base_type(type);
1898
1899 if (type->type == HLSL_CLASS_SCALAR)
1900 return wine_dbg_sprintf("%s", name);
1901 if (type->type == HLSL_CLASS_VECTOR)
1902 return wine_dbg_sprintf("%s%u", name, type->dimx);
1903 if (type->type == HLSL_CLASS_MATRIX)
1904 return wine_dbg_sprintf("%s%ux%u", name, type->dimx, type->dimy);
1905 return "unexpected_type";
1906 }
1907
1908 const char *debug_modifiers(DWORD modifiers)
1909 {
1910 char string[110];
1911
1912 string[0] = 0;
1913 if (modifiers & HLSL_STORAGE_EXTERN)
1914 strcat(string, " extern"); /* 7 */
1915 if (modifiers & HLSL_STORAGE_NOINTERPOLATION)
1916 strcat(string, " nointerpolation"); /* 16 */
1917 if (modifiers & HLSL_MODIFIER_PRECISE)
1918 strcat(string, " precise"); /* 8 */
1919 if (modifiers & HLSL_STORAGE_SHARED)
1920 strcat(string, " shared"); /* 7 */
1921 if (modifiers & HLSL_STORAGE_GROUPSHARED)
1922 strcat(string, " groupshared"); /* 12 */
1923 if (modifiers & HLSL_STORAGE_STATIC)
1924 strcat(string, " static"); /* 7 */
1925 if (modifiers & HLSL_STORAGE_UNIFORM)
1926 strcat(string, " uniform"); /* 8 */
1927 if (modifiers & HLSL_STORAGE_VOLATILE)
1928 strcat(string, " volatile"); /* 9 */
1929 if (modifiers & HLSL_MODIFIER_CONST)
1930 strcat(string, " const"); /* 6 */
1931 if (modifiers & HLSL_MODIFIER_ROW_MAJOR)
1932 strcat(string, " row_major"); /* 10 */
1933 if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
1934 strcat(string, " column_major"); /* 13 */
1935 if ((modifiers & (HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT)) == (HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT))
1936 strcat(string, " inout"); /* 6 */
1937 else if (modifiers & HLSL_MODIFIER_IN)
1938 strcat(string, " in"); /* 3 */
1939 else if (modifiers & HLSL_MODIFIER_OUT)
1940 strcat(string, " out"); /* 4 */
1941
1942 return wine_dbg_sprintf("%s", string[0] ? string + 1 : "");
1943 }
1944
1945 static const char *debug_node_type(enum hlsl_ir_node_type type)
1946 {
1947 static const char * const names[] =
1948 {
1949 "HLSL_IR_VAR",
1950 "HLSL_IR_ASSIGNMENT",
1951 "HLSL_IR_CONSTANT",
1952 "HLSL_IR_CONSTRUCTOR",
1953 "HLSL_IR_DEREF",
1954 "HLSL_IR_EXPR",
1955 "HLSL_IR_FUNCTION_DECL",
1956 "HLSL_IR_IF",
1957 "HLSL_IR_JUMP",
1958 "HLSL_IR_SWIZZLE",
1959 };
1960
1961 if (type >= sizeof(names) / sizeof(names[0]))
1962 return "Unexpected node type";
1963 return names[type];
1964 }
1965
1966 static void debug_dump_instr(const struct hlsl_ir_node *instr);
1967
1968 static void debug_dump_instr_list(const struct list *list)
1969 {
1970 struct hlsl_ir_node *instr;
1971
1972 LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
1973 {
1974 debug_dump_instr(instr);
1975 TRACE("\n");
1976 }
1977 }
1978
1979 static void debug_dump_ir_var(const struct hlsl_ir_var *var)
1980 {
1981 if (var->modifiers)
1982 TRACE("%s ", debug_modifiers(var->modifiers));
1983 TRACE("%s %s", debug_hlsl_type(var->node.data_type), var->name);
1984 if (var->semantic)
1985 TRACE(" : %s", debugstr_a(var->semantic));
1986 }
1987
1988 static void debug_dump_ir_deref(const struct hlsl_ir_deref *deref)
1989 {
1990 switch (deref->type)
1991 {
1992 case HLSL_IR_DEREF_VAR:
1993 TRACE("deref(");
1994 debug_dump_ir_var(deref->v.var);
1995 TRACE(")");
1996 break;
1997 case HLSL_IR_DEREF_ARRAY:
1998 debug_dump_instr(deref->v.array.array);
1999 TRACE("[");
2000 debug_dump_instr(deref->v.array.index);
2001 TRACE("]");
2002 break;
2003 case HLSL_IR_DEREF_RECORD:
2004 debug_dump_instr(deref->v.record.record);
2005 TRACE(".%s", debugstr_a(deref->v.record.field->name));
2006 break;
2007 }
2008 }
2009
2010 static void debug_dump_ir_constant(const struct hlsl_ir_constant *constant)
2011 {
2012 struct hlsl_type *type = constant->node.data_type;
2013 unsigned int x, y;
2014
2015 if (type->dimy != 1)
2016 TRACE("{");
2017 for (y = 0; y < type->dimy; ++y)
2018 {
2019 if (type->dimx != 1)
2020 TRACE("{");
2021 for (x = 0; x < type->dimx; ++x)
2022 {
2023 switch (type->base_type)
2024 {
2025 case HLSL_TYPE_FLOAT:
2026 TRACE("%g ", (double)constant->v.value.f[y * type->dimx + x]);
2027 break;
2028 case HLSL_TYPE_DOUBLE:
2029 TRACE("%g ", constant->v.value.d[y * type->dimx + x]);
2030 break;
2031 case HLSL_TYPE_INT:
2032 TRACE("%d ", constant->v.value.i[y * type->dimx + x]);
2033 break;
2034 case HLSL_TYPE_UINT:
2035 TRACE("%u ", constant->v.value.u[y * type->dimx + x]);
2036 break;
2037 case HLSL_TYPE_BOOL:
2038 TRACE("%s ", constant->v.value.b[y * type->dimx + x] == FALSE ? "false" : "true");
2039 break;
2040 default:
2041 TRACE("Constants of type %s not supported\n", debug_base_type(type));
2042 }
2043 }
2044 if (type->dimx != 1)
2045 TRACE("}");
2046 }
2047 if (type->dimy != 1)
2048 TRACE("}");
2049 }
2050
2051 static const char *debug_expr_op(const struct hlsl_ir_expr *expr)
2052 {
2053 static const char * const op_names[] =
2054 {
2055 "~",
2056 "!",
2057 "-",
2058 "abs",
2059 "sign",
2060 "rcp",
2061 "rsq",
2062 "sqrt",
2063 "nrm",
2064 "exp2",
2065 "log2",
2066
2067 "cast",
2068
2069 "fract",
2070
2071 "sin",
2072 "cos",
2073 "sin_reduced",
2074 "cos_reduced",
2075
2076 "dsx",
2077 "dsy",
2078
2079 "sat",
2080
2081 "+",
2082 "-",
2083 "*",
2084 "/",
2085
2086 "%",
2087
2088 "<",
2089 ">",
2090 "<=",
2091 ">=",
2092 "==",
2093 "!=",
2094
2095 "&&",
2096 "||",
2097
2098 "<<",
2099 ">>",
2100 "&",
2101 "|",
2102 "^",
2103
2104 "dot",
2105 "crs",
2106 "min",
2107 "max",
2108
2109 "pow",
2110
2111 "pre++",
2112 "pre--",
2113 "post++",
2114 "post--",
2115
2116 "lerp",
2117
2118 ",",
2119 };
2120
2121 if (expr->op == HLSL_IR_UNOP_CAST)
2122 return debug_hlsl_type(expr->node.data_type);
2123
2124 return op_names[expr->op];
2125 }
2126
2127 /* Dumps the expression in a prefix "operator (operands)" form */
2128 static void debug_dump_ir_expr(const struct hlsl_ir_expr *expr)
2129 {
2130 unsigned int i;
2131
2132 TRACE("%s (", debug_expr_op(expr));
2133 for (i = 0; i < 3 && expr->operands[i]; ++i)
2134 {
2135 debug_dump_instr(expr->operands[i]);
2136 TRACE(" ");
2137 }
2138 TRACE(")");
2139 }
2140
2141 static void debug_dump_ir_constructor(const struct hlsl_ir_constructor *constructor)
2142 {
2143 struct hlsl_ir_node *arg;
2144
2145 TRACE("%s (", debug_hlsl_type(constructor->node.data_type));
2146 LIST_FOR_EACH_ENTRY(arg, constructor->arguments, struct hlsl_ir_node, entry)
2147 {
2148 debug_dump_instr(arg);
2149 TRACE(" ");
2150 }
2151 TRACE(")");
2152 }
2153
2154 static const char *debug_writemask(DWORD writemask)
2155 {
2156 char string[5], components[] = {'x', 'y', 'z', 'w'};
2157 unsigned int i = 0, pos = 0;
2158
2159 while (writemask)
2160 {
2161 if (writemask & 1)
2162 string[pos++] = components[i];
2163 writemask >>= 1;
2164 i++;
2165 }
2166 string[pos] = '\0';
2167 return wine_dbg_sprintf(".%s", string);
2168 }
2169
2170 static void debug_dump_ir_assignment(const struct hlsl_ir_assignment *assign)
2171 {
2172 TRACE("= (");
2173 debug_dump_instr(assign->lhs);
2174 if (assign->writemask != BWRITERSP_WRITEMASK_ALL)
2175 TRACE("%s", debug_writemask(assign->writemask));
2176 TRACE(" ");
2177 debug_dump_instr(assign->rhs);
2178 TRACE(")");
2179 }
2180
2181 static void debug_dump_ir_swizzle(const struct hlsl_ir_swizzle *swizzle)
2182 {
2183 unsigned int i;
2184
2185 debug_dump_instr(swizzle->val);
2186 TRACE(".");
2187 if (swizzle->val->data_type->dimy > 1)
2188 {
2189 for (i = 0; i < swizzle->node.data_type->dimx; ++i)
2190 TRACE("_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf);
2191 }
2192 else
2193 {
2194 char c[] = {'x', 'y', 'z', 'w'};
2195
2196 for (i = 0; i < swizzle->node.data_type->dimx; ++i)
2197 TRACE("%c", c[(swizzle->swizzle >> i * 2) & 0x3]);
2198 }
2199 }
2200
2201 static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
2202 {
2203 switch (jump->type)
2204 {
2205 case HLSL_IR_JUMP_BREAK:
2206 TRACE("break");
2207 break;
2208 case HLSL_IR_JUMP_CONTINUE:
2209 TRACE("continue");
2210 break;
2211 case HLSL_IR_JUMP_DISCARD:
2212 TRACE("discard");
2213 break;
2214 case HLSL_IR_JUMP_RETURN:
2215 TRACE("return ");
2216 if (jump->return_value)
2217 debug_dump_instr(jump->return_value);
2218 TRACE(";");
2219 break;
2220 }
2221 }
2222
2223 static void debug_dump_ir_if(const struct hlsl_ir_if *if_node)
2224 {
2225 TRACE("if (");
2226 debug_dump_instr(if_node->condition);
2227 TRACE(")\n{\n");
2228 debug_dump_instr_list(if_node->then_instrs);
2229 TRACE("}\n");
2230 if (if_node->else_instrs)
2231 {
2232 TRACE("else\n{\n");
2233 debug_dump_instr_list(if_node->else_instrs);
2234 TRACE("}\n");
2235 }
2236 }
2237
2238 static void debug_dump_instr(const struct hlsl_ir_node *instr)
2239 {
2240 switch (instr->type)
2241 {
2242 case HLSL_IR_EXPR:
2243 debug_dump_ir_expr(expr_from_node(instr));
2244 break;
2245 case HLSL_IR_DEREF:
2246 debug_dump_ir_deref(deref_from_node(instr));
2247 break;
2248 case HLSL_IR_CONSTANT:
2249 debug_dump_ir_constant(constant_from_node(instr));
2250 break;
2251 case HLSL_IR_ASSIGNMENT:
2252 debug_dump_ir_assignment(assignment_from_node(instr));
2253 break;
2254 case HLSL_IR_SWIZZLE:
2255 debug_dump_ir_swizzle(swizzle_from_node(instr));
2256 break;
2257 case HLSL_IR_CONSTRUCTOR:
2258 debug_dump_ir_constructor(constructor_from_node(instr));
2259 break;
2260 case HLSL_IR_JUMP:
2261 debug_dump_ir_jump(jump_from_node(instr));
2262 break;
2263 case HLSL_IR_IF:
2264 debug_dump_ir_if(if_from_node(instr));
2265 break;
2266 default:
2267 TRACE("<No dump function for %s>", debug_node_type(instr->type));
2268 }
2269 }
2270
2271 void debug_dump_ir_function_decl(const struct hlsl_ir_function_decl *func)
2272 {
2273 struct hlsl_ir_var *param;
2274
2275 TRACE("Dumping function %s.\n", debugstr_a(func->func->name));
2276 TRACE("Function parameters:\n");
2277 LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, node.entry)
2278 {
2279 debug_dump_ir_var(param);
2280 TRACE("\n");
2281 }
2282 if (func->semantic)
2283 TRACE("Function semantic: %s\n", debugstr_a(func->semantic));
2284 if (func->body)
2285 {
2286 debug_dump_instr_list(func->body);
2287 }
2288 }
2289
2290 void free_hlsl_type(struct hlsl_type *type)
2291 {
2292 struct hlsl_struct_field *field, *next_field;
2293
2294 d3dcompiler_free((void *)type->name);
2295 if (type->type == HLSL_CLASS_STRUCT)
2296 {
2297 LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry)
2298 {
2299 d3dcompiler_free((void *)field->name);
2300 d3dcompiler_free((void *)field->semantic);
2301 d3dcompiler_free(field);
2302 }
2303 }
2304 d3dcompiler_free(type);
2305 }
2306
2307 void free_instr_list(struct list *list)
2308 {
2309 struct hlsl_ir_node *node, *next_node;
2310
2311 if (!list)
2312 return;
2313 LIST_FOR_EACH_ENTRY_SAFE(node, next_node, list, struct hlsl_ir_node, entry)
2314 free_instr(node);
2315 d3dcompiler_free(list);
2316 }
2317
2318 static void free_ir_constant(struct hlsl_ir_constant *constant)
2319 {
2320 struct hlsl_type *type = constant->node.data_type;
2321 unsigned int i;
2322 struct hlsl_ir_constant *field, *next_field;
2323
2324 switch (type->type)
2325 {
2326 case HLSL_CLASS_ARRAY:
2327 for (i = 0; i < type->e.array.elements_count; ++i)
2328 free_ir_constant(&constant->v.array_elements[i]);
2329 d3dcompiler_free(constant->v.array_elements);
2330 break;
2331 case HLSL_CLASS_STRUCT:
2332 LIST_FOR_EACH_ENTRY_SAFE(field, next_field, constant->v.struct_elements, struct hlsl_ir_constant, node.entry)
2333 free_ir_constant(field);
2334 break;
2335 default:
2336 break;
2337 }
2338 d3dcompiler_free(constant);
2339 }
2340
2341 static void free_ir_deref(struct hlsl_ir_deref *deref)
2342 {
2343 switch (deref->type)
2344 {
2345 case HLSL_IR_DEREF_VAR:
2346 /* Variables are shared among nodes in the tree. */
2347 break;
2348 case HLSL_IR_DEREF_ARRAY:
2349 free_instr(deref->v.array.array);
2350 free_instr(deref->v.array.index);
2351 break;
2352 case HLSL_IR_DEREF_RECORD:
2353 free_instr(deref->v.record.record);
2354 break;
2355 }
2356 d3dcompiler_free(deref);
2357 }
2358
2359 static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
2360 {
2361 free_instr(swizzle->val);
2362 d3dcompiler_free(swizzle);
2363 }
2364
2365 static void free_ir_constructor(struct hlsl_ir_constructor *constructor)
2366 {
2367 free_instr_list(constructor->arguments);
2368 d3dcompiler_free(constructor);
2369 }
2370
2371 static void free_ir_expr(struct hlsl_ir_expr *expr)
2372 {
2373 unsigned int i;
2374
2375 for (i = 0; i < 3; ++i)
2376 {
2377 if (!expr->operands[i])
2378 break;
2379 free_instr(expr->operands[i]);
2380 }
2381 free_instr_list(expr->subexpressions);
2382 d3dcompiler_free(expr);
2383 }
2384
2385 static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
2386 {
2387 free_instr(assignment->lhs);
2388 free_instr(assignment->rhs);
2389 d3dcompiler_free(assignment);
2390 }
2391
2392 static void free_ir_if(struct hlsl_ir_if *if_node)
2393 {
2394 free_instr(if_node->condition);
2395 free_instr_list(if_node->then_instrs);
2396 free_instr_list(if_node->else_instrs);
2397 d3dcompiler_free(if_node);
2398 }
2399
2400 static void free_ir_jump(struct hlsl_ir_jump *jump)
2401 {
2402 if (jump->type == HLSL_IR_JUMP_RETURN)
2403 free_instr(jump->return_value);
2404 d3dcompiler_free(jump);
2405 }
2406
2407 void free_instr(struct hlsl_ir_node *node)
2408 {
2409 switch (node->type)
2410 {
2411 case HLSL_IR_VAR:
2412 /* These are freed later on from the scopes. */
2413 break;
2414 case HLSL_IR_CONSTANT:
2415 free_ir_constant(constant_from_node(node));
2416 break;
2417 case HLSL_IR_DEREF:
2418 free_ir_deref(deref_from_node(node));
2419 break;
2420 case HLSL_IR_SWIZZLE:
2421 free_ir_swizzle(swizzle_from_node(node));
2422 break;
2423 case HLSL_IR_CONSTRUCTOR:
2424 free_ir_constructor(constructor_from_node(node));
2425 break;
2426 case HLSL_IR_EXPR:
2427 free_ir_expr(expr_from_node(node));
2428 break;
2429 case HLSL_IR_ASSIGNMENT:
2430 free_ir_assignment(assignment_from_node(node));
2431 break;
2432 case HLSL_IR_IF:
2433 free_ir_if(if_from_node(node));
2434 break;
2435 case HLSL_IR_JUMP:
2436 free_ir_jump(jump_from_node(node));
2437 break;
2438 default:
2439 FIXME("Unsupported node type %s\n", debug_node_type(node->type));
2440 }
2441 }
2442
2443 static void free_function_decl(struct hlsl_ir_function_decl *func)
2444 {
2445 d3dcompiler_free((void *)func->semantic);
2446 d3dcompiler_free(func->parameters);
2447 free_instr_list(func->body);
2448 d3dcompiler_free(func);
2449 }
2450
2451 static void free_function_decl_rb(struct wine_rb_entry *entry, void *context)
2452 {
2453 free_function_decl(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry));
2454 }
2455
2456 static void free_function(struct hlsl_ir_function *func)
2457 {
2458 wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL);
2459 d3dcompiler_free((void *)func->name);
2460 }
2461
2462 void free_function_rb(struct wine_rb_entry *entry, void *context)
2463 {
2464 free_function(WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry));
2465 }
2466
2467 void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, BOOL intrinsic)
2468 {
2469 struct hlsl_ir_function *func;
2470 struct wine_rb_entry *func_entry, *old_entry;
2471
2472 func_entry = wine_rb_get(funcs, name);
2473 if (func_entry)
2474 {
2475 func = WINE_RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry);
2476 decl->func = func;
2477 if ((old_entry = wine_rb_get(&func->overloads, decl->parameters)))
2478 {
2479 struct hlsl_ir_function_decl *old_decl =
2480 WINE_RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry);
2481
2482 if (!decl->body)
2483 {
2484 free_function_decl(decl);
2485 d3dcompiler_free(name);
2486 return;
2487 }
2488 wine_rb_remove(&func->overloads, decl->parameters);
2489 free_function_decl(old_decl);
2490 }
2491 wine_rb_put(&func->overloads, decl->parameters, &decl->entry);
2492 d3dcompiler_free(name);
2493 return;
2494 }
2495 func = d3dcompiler_alloc(sizeof(*func));
2496 func->name = name;
2497 if (wine_rb_init(&func->overloads, &hlsl_ir_function_decl_rb_funcs) == -1)
2498 {
2499 ERR("Failed to initialize function rbtree.\n");
2500 d3dcompiler_free(name);
2501 d3dcompiler_free(func);
2502 return;
2503 }
2504 decl->func = func;
2505 wine_rb_put(&func->overloads, decl->parameters, &decl->entry);
2506 func->intrinsic = intrinsic;
2507 wine_rb_put(funcs, func->name, &func->entry);
2508 }