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