1 // 2 // Copyright (C) 2016 LunarG, Inc. 3 // 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions 8 // are met: 9 // 10 // Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // 13 // Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following 15 // disclaimer in the documentation and/or other materials provided 16 // with the distribution. 17 // 18 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 19 // contributors may be used to endorse or promote products derived 20 // from this software without specific prior written permission. 21 // 22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 // POSSIBILITY OF SUCH DAMAGE. 34 // 35 36 // 37 // Create strings that declare built-in definitions, add built-ins programmatically 38 // that cannot be expressed in the strings, and establish mappings between 39 // built-in functions and operators. 40 // 41 // Where to put a built-in: 42 // TBuiltInParseablesHlsl::initialize(version,profile) context-independent textual built-ins; add them to the right string 43 // TBuiltInParseablesHlsl::initialize(resources,...) context-dependent textual built-ins; add them to the right string 44 // TBuiltInParseablesHlsl::identifyBuiltIns(...,symbolTable) context-independent programmatic additions/mappings to the symbol table, 45 // including identifying what extensions are needed if a version does not allow a symbol 46 // TBuiltInParseablesHlsl::identifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the 47 // symbol table, including identifying what extensions are needed if a version does 48 // not allow a symbol 49 // 50 51 #include "hlslParseables.h" 52 #include "hlslParseHelper.h" 53 #include <cctype> 54 #include <utility> 55 #include <algorithm> 56 57 namespace { // anonymous namespace functions 58 59 const bool UseHlslTypes = true; 60 61 const char* BaseTypeName(const char argOrder, const char* scalarName, const char* vecName, const char* matName) 62 { 63 switch (argOrder) { 64 case 'S': return scalarName; 65 case 'V': return vecName; 66 case 'M': return matName; 67 default: return "UNKNOWN_TYPE"; 68 } 69 } 70 71 bool IsSamplerType(const char argType) { return argType == 'S' || argType == 's'; } 72 bool IsArrayed(const char argOrder) { return argOrder == '@' || argOrder == '&' || argOrder == '#'; } 73 bool IsTextureMS(const char argOrder) { return argOrder == '$' || argOrder == '&'; } 74 bool IsBuffer(const char argOrder) { return argOrder == '*' || argOrder == '~'; } 75 bool IsImage(const char argOrder) { return argOrder == '!' || argOrder == '#' || argOrder == '~'; } 76 bool IsTextureType(const char argOrder) 77 { 78 return argOrder == '%' || argOrder == '@' || IsTextureMS(argOrder) || IsBuffer(argOrder) | IsImage(argOrder); 79 } 80 81 // Reject certain combinations that are illegal sample methods. For example, 82 // 3D arrays. 83 bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim0) 84 { 85 const bool isArrayed = IsArrayed(*argOrder); 86 const bool isMS = IsTextureMS(*argOrder); 87 const bool isBuffer = IsBuffer(*argOrder); 88 89 // there are no 3D arrayed textures, or 3D SampleCmp(LevelZero) 90 if (dim0 == 3 && (isArrayed || name == "SampleCmp" || name == "SampleCmpLevelZero")) 91 return true; 92 93 const int numArgs = int(std::count(argOrder, argOrder + strlen(argOrder), ',')) + 1; 94 95 // Reject invalid offset forms with cubemaps 96 if (dim0 == 4) { 97 if ((name == "Sample" && numArgs >= 4) || 98 (name == "SampleBias" && numArgs >= 5) || 99 (name == "SampleCmp" && numArgs >= 5) || 100 (name == "SampleCmpLevelZero" && numArgs >= 5) || 101 (name == "SampleGrad" && numArgs >= 6) || 102 (name == "SampleLevel" && numArgs >= 5)) 103 return true; 104 } 105 106 const bool isGather = 107 (name == "Gather" || 108 name == "GatherRed" || 109 name == "GatherGreen" || 110 name == "GatherBlue" || 111 name == "GatherAlpha"); 112 113 const bool isGatherCmp = 114 (name == "GatherCmp" || 115 name == "GatherCmpRed" || 116 name == "GatherCmpGreen" || 117 name == "GatherCmpBlue" || 118 name == "GatherCmpAlpha"); 119 120 // Reject invalid Gathers 121 if (isGather || isGatherCmp) { 122 if (dim0 == 1 || dim0 == 3) // there are no 1D or 3D gathers 123 return true; 124 125 // no offset on cube or cube array gathers 126 if (dim0 == 4) { 127 if ((isGather && numArgs > 3) || (isGatherCmp && numArgs > 4)) 128 return true; 129 } 130 } 131 132 // Reject invalid Loads 133 if (name == "Load" && dim0 == 4) 134 return true; // Load does not support any cubemaps, arrayed or not. 135 136 // Multisample formats are only 2D and 2Darray 137 if (isMS && dim0 != 2) 138 return true; 139 140 // Buffer are only 1D 141 if (isBuffer && dim0 != 1) 142 return true; 143 144 return false; 145 } 146 147 // Return the number of the coordinate arg, if any 148 int CoordinateArgPos(const glslang::TString& name, bool isTexture) 149 { 150 if (!isTexture || (name == "GetDimensions")) 151 return -1; // has none 152 else if (name == "Load") 153 return 1; 154 else 155 return 2; // other texture methods are 2 156 } 157 158 // Some texture methods use an addition coordinate dimension for the mip 159 bool HasMipInCoord(const glslang::TString& name, bool isMS, bool isBuffer, bool isImage) 160 { 161 return name == "Load" && !isMS && !isBuffer && !isImage; 162 } 163 164 // LOD calculations don't pass the array level in the coordinate. 165 bool NoArrayCoord(const glslang::TString& name) 166 { 167 return name == "CalculateLevelOfDetail" || name == "CalculateLevelOfDetailUnclamped"; 168 } 169 170 // Handle IO params marked with > or < 171 const char* IoParam(glslang::TString& s, const char* nthArgOrder) 172 { 173 if (*nthArgOrder == '>') { // output params 174 ++nthArgOrder; 175 s.append("out "); 176 } else if (*nthArgOrder == '<') { // input params 177 ++nthArgOrder; 178 s.append("in "); 179 } 180 181 return nthArgOrder; 182 } 183 184 // Handle repeated args 185 void HandleRepeatArg(const char*& arg, const char*& prev, const char* current) 186 { 187 if (*arg == ',' || *arg == '\0') 188 arg = prev; 189 else 190 prev = current; 191 } 192 193 // Return true for the end of a single argument key, which can be the end of the string, or 194 // the comma separator. 195 inline bool IsEndOfArg(const char* arg) 196 { 197 return arg == nullptr || *arg == '\0' || *arg == ','; 198 } 199 200 // If this is a fixed vector size, such as V3, return the size. Else return 0. 201 int FixedVecSize(const char* arg) 202 { 203 while (!IsEndOfArg(arg)) { 204 if (isdigit(*arg)) 205 return *arg - '0'; 206 ++arg; 207 } 208 209 return 0; // none found. 210 } 211 212 // Create and return a type name. This is done in GLSL, not HLSL conventions, until such 213 // time as builtins are parsed using the HLSL parser. 214 // 215 // order: S = scalar, V = vector, M = matrix 216 // argType: F = float, D = double, I = int, U = uint, B = bool, S = sampler 217 // dim0 = vector dimension, or matrix 1st dimension 218 // dim1 = matrix 2nd dimension 219 glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, const char* argType, int dim0, int dim1) 220 { 221 const bool isTranspose = (argOrder[0] == '^'); 222 const bool isTexture = IsTextureType(argOrder[0]); 223 const bool isArrayed = IsArrayed(argOrder[0]); 224 const bool isSampler = IsSamplerType(argType[0]); 225 const bool isMS = IsTextureMS(argOrder[0]); 226 const bool isBuffer = IsBuffer(argOrder[0]); 227 const bool isImage = IsImage(argOrder[0]); 228 229 char type = *argType; 230 231 if (isTranspose) { // Take transpose of matrix dimensions 232 std::swap(dim0, dim1); 233 } else if (isTexture) { 234 if (type == 'F') // map base type to texture of that type. 235 type = 'T'; // e.g, int -> itexture, uint -> utexture, etc. 236 else if (type == 'I') 237 type = 'i'; 238 else if (type == 'U') 239 type = 'u'; 240 } 241 242 if (isTranspose) 243 ++argOrder; 244 245 char order = *argOrder; 246 247 if (UseHlslTypes) { 248 switch (type) { 249 case '-': s += "void"; break; 250 case 'F': s += "float"; break; 251 case 'D': s += "double"; break; 252 case 'I': s += "int"; break; 253 case 'U': s += "uint"; break; 254 case 'B': s += "bool"; break; 255 case 'S': s += "sampler"; break; 256 case 's': s += "SamplerComparisonState"; break; 257 case 'T': s += ((isBuffer && isImage) ? "RWBuffer" : 258 isBuffer ? "Buffer" : 259 isImage ? "RWTexture" : "Texture"); break; 260 case 'i': s += ((isBuffer && isImage) ? "RWBuffer" : 261 isBuffer ? "Buffer" : 262 isImage ? "RWTexture" : "Texture"); break; 263 case 'u': s += ((isBuffer && isImage) ? "RWBuffer" : 264 isBuffer ? "Buffer" : 265 isImage ? "RWTexture" : "Texture"); break; 266 default: s += "UNKNOWN_TYPE"; break; 267 } 268 } else { 269 switch (type) { 270 case '-': s += "void"; break; 271 case 'F': s += BaseTypeName(order, "float", "vec", "mat"); break; 272 case 'D': s += BaseTypeName(order, "double", "dvec", "dmat"); break; 273 case 'I': s += BaseTypeName(order, "int", "ivec", "imat"); break; 274 case 'U': s += BaseTypeName(order, "uint", "uvec", "umat"); break; 275 case 'B': s += BaseTypeName(order, "bool", "bvec", "bmat"); break; 276 case 'S': s += "sampler"; break; 277 case 's': s += "samplerShadow"; break; 278 case 'T': // fall through 279 case 'i': // ... 280 case 'u': // ... 281 if (type != 'T') // create itexture, utexture, etc 282 s += type; 283 284 s += ((isImage && isBuffer) ? "imageBuffer" : 285 isImage ? "image" : 286 isBuffer ? "samplerBuffer" : 287 "texture"); 288 break; 289 290 default: s += "UNKNOWN_TYPE"; break; 291 } 292 } 293 294 // handle fixed vector sizes, such as float3, and only ever 3. 295 const int fixedVecSize = FixedVecSize(argOrder); 296 if (fixedVecSize != 0) 297 dim0 = dim1 = fixedVecSize; 298 299 // Add sampler dimensions 300 if (isSampler || isTexture) { 301 if ((order == 'V' || isTexture) && !isBuffer) { 302 switch (dim0) { 303 case 1: s += "1D"; break; 304 case 2: s += (isMS ? "2DMS" : "2D"); break; 305 case 3: s += "3D"; break; 306 case 4: s += "Cube"; break; 307 default: s += "UNKNOWN_SAMPLER"; break; 308 } 309 } 310 } else { 311 // Non-sampler type: 312 // verify dimensions 313 if (((order == 'V' || order == 'M') && (dim0 < 1 || dim0 > 4)) || 314 (order == 'M' && (dim1 < 1 || dim1 > 4))) { 315 s += "UNKNOWN_DIMENSION"; 316 return s; 317 } 318 319 switch (order) { 320 case '-': break; // no dimensions for voids 321 case 'S': break; // no dimensions on scalars 322 case 'V': 323 s += ('0' + char(dim0)); 324 break; 325 case 'M': 326 s += ('0' + char(dim0)); 327 s += 'x'; 328 s += ('0' + char(dim1)); 329 break; 330 default: 331 break; 332 } 333 } 334 335 // handle arrayed textures 336 if (isArrayed) 337 s += "Array"; 338 339 // For HLSL, append return type for texture types 340 if (UseHlslTypes) { 341 switch (type) { 342 case 'i': s += "<int4>"; break; 343 case 'u': s += "<uint4>"; break; 344 case 'T': s += "<float4>"; break; 345 default: break; 346 } 347 } 348 349 return s; 350 } 351 352 // The GLSL parser can be used to parse a subset of HLSL prototypes. However, many valid HLSL prototypes 353 // are not valid GLSL prototypes. This rejects the invalid ones. Thus, there is a single switch below 354 // to enable creation of the entire HLSL space. 355 inline bool IsValid(const char* cname, char retOrder, char retType, char argOrder, char argType, int dim0, int dim1) 356 { 357 const bool isVec = (argOrder == 'V'); 358 const bool isMat = (argOrder == 'M'); 359 360 const std::string name(cname); 361 362 // these do not have vec1 versions 363 if (dim0 == 1 && (name == "normalize" || name == "reflect" || name == "refract")) 364 return false; 365 366 if (!IsTextureType(argOrder) && (isVec && dim0 == 1)) // avoid vec1 367 return false; 368 369 if (UseHlslTypes) { 370 // NO further restrictions for HLSL 371 } else { 372 // GLSL parser restrictions 373 if ((isMat && (argType == 'I' || argType == 'U' || argType == 'B')) || 374 (retOrder == 'M' && (retType == 'I' || retType == 'U' || retType == 'B'))) 375 return false; 376 377 if (isMat && dim0 == 1 && dim1 == 1) // avoid mat1x1 378 return false; 379 380 if (isMat && dim1 == 1) // TODO: avoid mat Nx1 until we find the right GLSL profile 381 return false; 382 383 if (name == "GetRenderTargetSamplePosition" || 384 name == "tex1D" || 385 name == "tex1Dgrad") 386 return false; 387 } 388 389 return true; 390 } 391 392 // return position of end of argument specifier 393 inline const char* FindEndOfArg(const char* arg) 394 { 395 while (!IsEndOfArg(arg)) 396 ++arg; 397 398 return *arg == '\0' ? nullptr : arg; 399 } 400 401 // Return pointer to beginning of Nth argument specifier in the string. 402 inline const char* NthArg(const char* arg, int n) 403 { 404 for (int x=0; x<n && arg; ++x) 405 if ((arg = FindEndOfArg(arg)) != nullptr) 406 ++arg; // skip arg separator 407 408 return arg; 409 } 410 411 inline void FindVectorMatrixBounds(const char* argOrder, int fixedVecSize, int& dim0Min, int& dim0Max, int& /*dim1Min*/, int& dim1Max) 412 { 413 for (int arg = 0; ; ++arg) { 414 const char* nthArgOrder(NthArg(argOrder, arg)); 415 if (nthArgOrder == nullptr) 416 break; 417 else if (*nthArgOrder == 'V') 418 dim0Max = 4; 419 else if (*nthArgOrder == 'M') 420 dim0Max = dim1Max = 4; 421 } 422 423 if (fixedVecSize > 0) // handle fixed sized vectors 424 dim0Min = dim0Max = fixedVecSize; 425 } 426 427 } // end anonymous namespace 428 429 namespace glslang { 430 431 TBuiltInParseablesHlsl::TBuiltInParseablesHlsl() 432 { 433 } 434 435 // 436 // Handle creation of mat*mat specially, since it doesn't fall conveniently out of 437 // the generic prototype creation code below. 438 // 439 void TBuiltInParseablesHlsl::createMatTimesMat() 440 { 441 TString& s = commonBuiltins; 442 443 const int first = (UseHlslTypes ? 1 : 2); 444 445 for (int xRows = first; xRows <=4; xRows++) { 446 for (int xCols = first; xCols <=4; xCols++) { 447 const int yRows = xCols; 448 for (int yCols = first; yCols <=4; yCols++) { 449 const int retRows = xRows; 450 const int retCols = yCols; 451 452 // Create a mat * mat of the appropriate dimensions 453 AppendTypeName(s, "M", "F", retRows, retCols); // add return type 454 s.append(" "); // space between type and name 455 s.append("mul"); // intrinsic name 456 s.append("("); // open paren 457 458 AppendTypeName(s, "M", "F", xRows, xCols); // add X input 459 s.append(", "); 460 AppendTypeName(s, "M", "F", yRows, yCols); // add Y input 461 462 s.append(");\n"); // close paren 463 } 464 465 // Create M*V 466 AppendTypeName(s, "V", "F", xRows, 1); // add return type 467 s.append(" "); // space between type and name 468 s.append("mul"); // intrinsic name 469 s.append("("); // open paren 470 471 AppendTypeName(s, "M", "F", xRows, xCols); // add X input 472 s.append(", "); 473 AppendTypeName(s, "V", "F", xCols, 1); // add Y input 474 475 s.append(");\n"); // close paren 476 477 // Create V*M 478 AppendTypeName(s, "V", "F", xCols, 1); // add return type 479 s.append(" "); // space between type and name 480 s.append("mul"); // intrinsic name 481 s.append("("); // open paren 482 483 AppendTypeName(s, "V", "F", xRows, 1); // add Y input 484 s.append(", "); 485 AppendTypeName(s, "M", "F", xRows, xCols); // add X input 486 487 s.append(");\n"); // close paren 488 } 489 } 490 } 491 492 // 493 // Add all context-independent built-in functions and variables that are present 494 // for the given version and profile. Share common ones across stages, otherwise 495 // make stage-specific entries. 496 // 497 // Most built-ins variables can be added as simple text strings. Some need to 498 // be added programmatically, which is done later in IdentifyBuiltIns() below. 499 // 500 void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/) 501 { 502 static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1); 503 504 // These are the actual stage masks defined in the documentation, in case they are 505 // needed for future validation. For now, they are commented out, and set below 506 // to EShLangAll, to allow any intrinsic to be used in any shader, which is legal 507 // if it is not called. 508 // 509 // static const EShLanguageMask EShLangPSCS = EShLanguageMask(EShLangFragmentMask | EShLangComputeMask); 510 // static const EShLanguageMask EShLangVSPSGS = EShLanguageMask(EShLangVertexMask | EShLangFragmentMask | EShLangGeometryMask); 511 // static const EShLanguageMask EShLangCS = EShLangComputeMask; 512 // static const EShLanguageMask EShLangPS = EShLangFragmentMask; 513 // static const EShLanguageMask EShLangHS = EShLangTessControlMask; 514 515 // This set uses EShLangAll for everything. 516 static const EShLanguageMask EShLangPSCS = EShLangAll; 517 static const EShLanguageMask EShLangVSPSGS = EShLangAll; 518 static const EShLanguageMask EShLangCS = EShLangAll; 519 static const EShLanguageMask EShLangPS = EShLangAll; 520 static const EShLanguageMask EShLangHS = EShLangAll; 521 static const EShLanguageMask EShLangGS = EShLangAll; 522 523 // This structure encodes the prototype information for each HLSL intrinsic. 524 // Because explicit enumeration would be cumbersome, it's procedurally generated. 525 // orderKey can be: 526 // S = scalar, V = vector, M = matrix, - = void 527 // typekey can be: 528 // D = double, F = float, U = uint, I = int, B = bool, S = sampler, s = shadowSampler 529 // An empty order or type key repeats the first one. E.g: SVM,, means 3 args each of SVM. 530 // '>' as first letter of order creates an output parameter 531 // '<' as first letter of order creates an input parameter 532 // '^' as first letter of order takes transpose dimensions 533 // '%' as first letter of order creates texture of given F/I/U type (texture, itexture, etc) 534 // '@' as first letter of order creates arrayed texture of given type 535 // '$' / '&' as first letter of order creates 2DMS / 2DMSArray textures 536 // '*' as first letter of order creates buffer object 537 // '!' as first letter of order creates image object 538 // '#' as first letter of order creates arrayed image object 539 // '~' as first letter of order creates an image buffer object 540 541 static const struct { 542 const char* name; // intrinsic name 543 const char* retOrder; // return type key: empty matches order of 1st argument 544 const char* retType; // return type key: empty matches type of 1st argument 545 const char* argOrder; // argument order key 546 const char* argType; // argument type key 547 unsigned int stage; // stage mask 548 bool method; // true if it's a method. 549 } hlslIntrinsics[] = { 550 // name retOrd retType argOrder argType stage mask 551 // ----------------------------------------------------------------------------------------------- 552 { "abort", nullptr, nullptr, "-", "-", EShLangAll, false }, 553 { "abs", nullptr, nullptr, "SVM", "DFUI", EShLangAll, false }, 554 { "acos", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 555 { "all", "S", "B", "SVM", "BFIU", EShLangAll, false }, 556 { "AllMemoryBarrier", nullptr, nullptr, "-", "-", EShLangCS, false }, 557 { "AllMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS, false }, 558 { "any", "S", "B", "SVM", "BFIU", EShLangAll, false }, 559 { "asdouble", "S", "D", "S,", "UI,", EShLangAll, false }, 560 { "asdouble", "V2", "D", "V2,", "UI,", EShLangAll, false }, 561 { "asfloat", nullptr, "F", "SVM", "BFIU", EShLangAll, false }, 562 { "asin", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 563 { "asint", nullptr, "I", "SVM", "FU", EShLangAll, false }, 564 { "asuint", nullptr, "U", "SVM", "FU", EShLangAll, false }, 565 { "atan", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 566 { "atan2", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 567 { "ceil", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 568 { "CheckAccessFullyMapped", "S", "B" , "S", "U", EShLangPSCS, false }, 569 { "clamp", nullptr, nullptr, "SVM,,", "FUI,,", EShLangAll, false }, 570 { "clip", "-", "-", "SVM", "F", EShLangPS, false }, 571 { "cos", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 572 { "cosh", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 573 { "countbits", nullptr, nullptr, "SV", "UI", EShLangAll, false }, 574 { "cross", nullptr, nullptr, "V3,", "F,", EShLangAll, false }, 575 { "D3DCOLORtoUBYTE4", "V4", "I", "V4", "F", EShLangAll, false }, 576 { "ddx", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 577 { "ddx_coarse", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 578 { "ddx_fine", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 579 { "ddy", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 580 { "ddy_coarse", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 581 { "ddy_fine", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 582 { "degrees", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 583 { "determinant", "S", "F", "M", "F", EShLangAll, false }, 584 { "DeviceMemoryBarrier", nullptr, nullptr, "-", "-", EShLangPSCS, false }, 585 { "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS, false }, 586 { "distance", "S", "F", "V,", "F,", EShLangAll, false }, 587 { "dot", "S", nullptr, "SV,", "FI,", EShLangAll, false }, 588 { "dst", nullptr, nullptr, "V4,", "F,", EShLangAll, false }, 589 // { "errorf", "-", "-", "", "", EShLangAll, false }, TODO: varargs 590 { "EvaluateAttributeAtCentroid", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 591 { "EvaluateAttributeAtSample", nullptr, nullptr, "SVM,S", "F,U", EShLangPS, false }, 592 { "EvaluateAttributeSnapped", nullptr, nullptr, "SVM,V2", "F,I", EShLangPS, false }, 593 { "exp", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 594 { "exp2", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 595 { "f16tof32", nullptr, "F", "SV", "U", EShLangAll, false }, 596 { "f32tof16", nullptr, "U", "SV", "F", EShLangAll, false }, 597 { "faceforward", nullptr, nullptr, "V,,", "F,,", EShLangAll, false }, 598 { "firstbithigh", nullptr, nullptr, "SV", "UI", EShLangAll, false }, 599 { "firstbitlow", nullptr, nullptr, "SV", "UI", EShLangAll, false }, 600 { "floor", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 601 { "fma", nullptr, nullptr, "SVM,,", "D,,", EShLangAll, false }, 602 { "fmod", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 603 { "frac", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 604 { "frexp", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 605 { "fwidth", nullptr, nullptr, "SVM", "F", EShLangPS, false }, 606 { "GetRenderTargetSampleCount", "S", "U", "-", "-", EShLangAll, false }, 607 { "GetRenderTargetSamplePosition", "V2", "F", "V1", "I", EShLangAll, false }, 608 { "GroupMemoryBarrier", nullptr, nullptr, "-", "-", EShLangCS, false }, 609 { "GroupMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS, false }, 610 { "InterlockedAdd", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 611 { "InterlockedAdd", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 612 { "InterlockedAnd", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 613 { "InterlockedAnd", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 614 { "InterlockedCompareExchange", "-", "-", "SVM,,,>", "UI,,,", EShLangPSCS, false }, 615 { "InterlockedCompareStore", "-", "-", "SVM,,", "UI,,", EShLangPSCS, false }, 616 { "InterlockedExchange", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 617 { "InterlockedMax", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 618 { "InterlockedMax", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 619 { "InterlockedMin", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 620 { "InterlockedMin", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 621 { "InterlockedOr", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 622 { "InterlockedOr", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 623 { "InterlockedXor", "-", "-", "SVM,,>", "UI,,", EShLangPSCS, false }, 624 { "InterlockedXor", "-", "-", "SVM,", "UI,", EShLangPSCS, false }, 625 { "isfinite", nullptr, "B" , "SVM", "F", EShLangAll, false }, 626 { "isinf", nullptr, "B" , "SVM", "F", EShLangAll, false }, 627 { "isnan", nullptr, "B" , "SVM", "F", EShLangAll, false }, 628 { "ldexp", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 629 { "length", "S", "F", "SV", "F", EShLangAll, false }, 630 { "lerp", nullptr, nullptr, "VM,,", "F,,", EShLangAll, false }, 631 { "lerp", nullptr, nullptr, "SVM,,S", "F,,", EShLangAll, false }, 632 { "lit", "V4", "F", "S,,", "F,,", EShLangAll, false }, 633 { "log", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 634 { "log10", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 635 { "log2", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 636 { "mad", nullptr, nullptr, "SVM,,", "DFUI,,", EShLangAll, false }, 637 { "max", nullptr, nullptr, "SVM,", "FIU,", EShLangAll, false }, 638 { "min", nullptr, nullptr, "SVM,", "FIU,", EShLangAll, false }, 639 { "modf", nullptr, nullptr, "SVM,>", "FIU,", EShLangAll, false }, 640 { "msad4", "V4", "U", "S,V2,V4", "U,,", EShLangAll, false }, 641 { "mul", "S", nullptr, "S,S", "FI,", EShLangAll, false }, 642 { "mul", "V", nullptr, "S,V", "FI,", EShLangAll, false }, 643 { "mul", "M", nullptr, "S,M", "FI,", EShLangAll, false }, 644 { "mul", "V", nullptr, "V,S", "FI,", EShLangAll, false }, 645 { "mul", "S", nullptr, "V,V", "FI,", EShLangAll, false }, 646 { "mul", "M", nullptr, "M,S", "FI,", EShLangAll, false }, 647 // mat*mat form of mul is handled in createMatTimesMat() 648 { "noise", "S", "F", "V", "F", EShLangPS, false }, 649 { "normalize", nullptr, nullptr, "V", "F", EShLangAll, false }, 650 { "pow", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 651 // { "printf", "-", "-", "", "", EShLangAll, false }, TODO: varargs 652 { "Process2DQuadTessFactorsAvg", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false }, 653 { "Process2DQuadTessFactorsMax", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false }, 654 { "Process2DQuadTessFactorsMin", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false }, 655 { "ProcessIsolineTessFactors", "-", "-", "S,,>,>", "F,,,", EShLangHS, false }, 656 { "ProcessQuadTessFactorsAvg", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS, false }, 657 { "ProcessQuadTessFactorsMax", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS, false }, 658 { "ProcessQuadTessFactorsMin", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS, false }, 659 { "ProcessTriTessFactorsAvg", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS, false }, 660 { "ProcessTriTessFactorsMax", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS, false }, 661 { "ProcessTriTessFactorsMin", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS, false }, 662 { "radians", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 663 { "rcp", nullptr, nullptr, "SVM", "FD", EShLangAll, false }, 664 { "reflect", nullptr, nullptr, "V,", "F,", EShLangAll, false }, 665 { "refract", nullptr, nullptr, "V,V,S", "F,,", EShLangAll, false }, 666 { "reversebits", nullptr, nullptr, "SV", "UI", EShLangAll, false }, 667 { "round", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 668 { "rsqrt", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 669 { "saturate", nullptr, nullptr , "SVM", "F", EShLangAll, false }, 670 { "sign", nullptr, nullptr, "SVM", "FI", EShLangAll, false }, 671 { "sin", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 672 { "sincos", "-", "-", "SVM,>,>", "F,,", EShLangAll, false }, 673 { "sinh", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 674 { "smoothstep", nullptr, nullptr, "SVM,,", "F,,", EShLangAll, false }, 675 { "sqrt", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 676 { "step", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, 677 { "tan", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 678 { "tanh", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 679 { "tex1D", "V4", "F", "V1,S", "S,F", EShLangPS, false }, 680 { "tex1D", "V4", "F", "V1,S,V1,", "S,F,,", EShLangPS, false }, 681 { "tex1Dbias", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, 682 { "tex1Dgrad", "V4", "F", "V1,,,", "S,F,,", EShLangPS, false }, 683 { "tex1Dlod", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, 684 { "tex1Dproj", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, 685 { "tex2D", "V4", "F", "V2,", "S,F", EShLangPS, false }, 686 { "tex2D", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, 687 { "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, 688 { "tex2Dgrad", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, 689 { "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, 690 { "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, 691 { "tex3D", "V4", "F", "V3,", "S,F", EShLangPS, false }, 692 { "tex3D", "V4", "F", "V3,,,", "S,F,,", EShLangPS, false }, 693 { "tex3Dbias", "V4", "F", "V3,V4", "S,F", EShLangPS, false }, 694 { "tex3Dgrad", "V4", "F", "V3,,,", "S,F,,", EShLangPS, false }, 695 { "tex3Dlod", "V4", "F", "V3,V4", "S,F", EShLangPS, false }, 696 { "tex3Dproj", "V4", "F", "V3,V4", "S,F", EShLangPS, false }, 697 { "texCUBE", "V4", "F", "V4,V3", "S,F", EShLangPS, false }, 698 { "texCUBE", "V4", "F", "V4,V3,,", "S,F,,", EShLangPS, false }, 699 { "texCUBEbias", "V4", "F", "V4,", "S,F", EShLangPS, false }, 700 { "texCUBEgrad", "V4", "F", "V4,V3,,", "S,F,,", EShLangPS, false }, 701 { "texCUBElod", "V4", "F", "V4,", "S,F", EShLangPS, false }, 702 { "texCUBEproj", "V4", "F", "V4,", "S,F", EShLangPS, false }, 703 { "transpose", "^M", nullptr, "M", "FUIB", EShLangAll, false }, 704 { "trunc", nullptr, nullptr, "SVM", "F", EShLangAll, false }, 705 706 // Texture object methods. Return type can be overridden by shader declaration. 707 // !O = no offset, O = offset 708 { "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS, true }, 709 { "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS, true }, 710 711 { "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS, true }, 712 { "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS, true }, 713 714 // TODO: FXC accepts int/uint samplers here. unclear what that means. 715 { "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS, true }, 716 { "SampleCmp", /* O*/ "S", "F", "%@,S,V,S,V", "FIU,s,F,,I", EShLangPS, true }, 717 718 // TODO: FXC accepts int/uint samplers here. unclear what that means. 719 { "SampleCmpLevelZero", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,F", EShLangPS, true }, 720 { "SampleCmpLevelZero", /* O*/ "S", "F", "%@,S,V,S,V", "FIU,s,F,F,I", EShLangPS, true }, 721 722 { "SampleGrad", /*!O*/ "V4", nullptr, "%@,S,V,,", "FIU,S,F,,", EShLangAll, true }, 723 { "SampleGrad", /* O*/ "V4", nullptr, "%@,S,V,,,", "FIU,S,F,,,I", EShLangAll, true }, 724 725 { "SampleLevel", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangAll, true }, 726 { "SampleLevel", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangAll, true }, 727 728 { "Load", /*!O*/ "V4", nullptr, "%@,V", "FIU,I", EShLangAll, true }, 729 { "Load", /* O*/ "V4", nullptr, "%@,V,V", "FIU,I,I", EShLangAll, true }, 730 { "Load", /* +sampleidex*/ "V4", nullptr, "$&,V,S", "FIU,I,I", EShLangAll, true }, 731 { "Load", /* +samplindex, offset*/ "V4", nullptr, "$&,V,S,V", "FIU,I,I,I", EShLangAll, true }, 732 733 // RWTexture loads 734 { "Load", "V4", nullptr, "!#,V", "FIU,I", EShLangAll, true }, 735 // (RW)Buffer loads 736 { "Load", "V4", nullptr, "~*1,V", "FIU,I", EShLangAll, true }, 737 738 { "Gather", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll, true }, 739 { "Gather", /* O*/ "V4", nullptr, "%@,S,V,V", "FIU,S,F,I", EShLangAll, true }, 740 741 { "CalculateLevelOfDetail", "S", "F", "%@,S,V", "FUI,S,F", EShLangPS, true }, 742 { "CalculateLevelOfDetailUnclamped", "S", "F", "%@,S,V", "FUI,S,F", EShLangPS, true }, 743 744 { "GetSamplePosition", "V2", "F", "$&2,S", "FUI,I", EShLangVSPSGS,true }, 745 746 // 747 // UINT Width 748 // UINT MipLevel, UINT Width, UINT NumberOfLevels 749 { "GetDimensions", /* 1D */ "-", "-", "%!~1,>S", "FUI,U", EShLangAll, true }, 750 { "GetDimensions", /* 1D */ "-", "-", "%!~1,>S", "FUI,F", EShLangAll, true }, 751 { "GetDimensions", /* 1D */ "-", "-", "%1,S,>S,", "FUI,U,,", EShLangAll, true }, 752 { "GetDimensions", /* 1D */ "-", "-", "%1,S,>S,", "FUI,U,F,", EShLangAll, true }, 753 754 // UINT Width, UINT Elements 755 // UINT MipLevel, UINT Width, UINT Elements, UINT NumberOfLevels 756 { "GetDimensions", /* 1DArray */ "-", "-", "@#1,>S,", "FUI,U,", EShLangAll, true }, 757 { "GetDimensions", /* 1DArray */ "-", "-", "@#1,>S,", "FUI,F,", EShLangAll, true }, 758 { "GetDimensions", /* 1DArray */ "-", "-", "@1,S,>S,,", "FUI,U,,,", EShLangAll, true }, 759 { "GetDimensions", /* 1DArray */ "-", "-", "@1,S,>S,,", "FUI,U,F,,", EShLangAll, true }, 760 761 // UINT Width, UINT Height 762 // UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels 763 { "GetDimensions", /* 2D */ "-", "-", "%!2,>S,", "FUI,U,", EShLangAll, true }, 764 { "GetDimensions", /* 2D */ "-", "-", "%!2,>S,", "FUI,F,", EShLangAll, true }, 765 { "GetDimensions", /* 2D */ "-", "-", "%2,S,>S,,", "FUI,U,,,", EShLangAll, true }, 766 { "GetDimensions", /* 2D */ "-", "-", "%2,S,>S,,", "FUI,U,F,,", EShLangAll, true }, 767 768 // UINT Width, UINT Height, UINT Elements 769 // UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels 770 { "GetDimensions", /* 2DArray */ "-", "-", "@#2,>S,,", "FUI,U,,", EShLangAll, true }, 771 { "GetDimensions", /* 2DArray */ "-", "-", "@#2,>S,,", "FUI,F,F,F", EShLangAll, true }, 772 { "GetDimensions", /* 2DArray */ "-", "-", "@2,S,>S,,,", "FUI,U,,,,", EShLangAll, true }, 773 { "GetDimensions", /* 2DArray */ "-", "-", "@2,S,>S,,,", "FUI,U,F,,,", EShLangAll, true }, 774 775 // UINT Width, UINT Height, UINT Depth 776 // UINT MipLevel, UINT Width, UINT Height, UINT Depth, UINT NumberOfLevels 777 { "GetDimensions", /* 3D */ "-", "-", "%!3,>S,,", "FUI,U,,", EShLangAll, true }, 778 { "GetDimensions", /* 3D */ "-", "-", "%!3,>S,,", "FUI,F,,", EShLangAll, true }, 779 { "GetDimensions", /* 3D */ "-", "-", "%3,S,>S,,,", "FUI,U,,,,", EShLangAll, true }, 780 { "GetDimensions", /* 3D */ "-", "-", "%3,S,>S,,,", "FUI,U,F,,,", EShLangAll, true }, 781 782 // UINT Width, UINT Height 783 // UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels 784 { "GetDimensions", /* Cube */ "-", "-", "%4,>S,", "FUI,U,", EShLangAll, true }, 785 { "GetDimensions", /* Cube */ "-", "-", "%4,>S,", "FUI,F,", EShLangAll, true }, 786 { "GetDimensions", /* Cube */ "-", "-", "%4,S,>S,,", "FUI,U,,,", EShLangAll, true }, 787 { "GetDimensions", /* Cube */ "-", "-", "%4,S,>S,,", "FUI,U,F,,", EShLangAll, true }, 788 789 // UINT Width, UINT Height, UINT Elements 790 // UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels 791 { "GetDimensions", /* CubeArray */ "-", "-", "@4,>S,,", "FUI,U,,", EShLangAll, true }, 792 { "GetDimensions", /* CubeArray */ "-", "-", "@4,>S,,", "FUI,F,,", EShLangAll, true }, 793 { "GetDimensions", /* CubeArray */ "-", "-", "@4,S,>S,,,", "FUI,U,,,,", EShLangAll, true }, 794 { "GetDimensions", /* CubeArray */ "-", "-", "@4,S,>S,,,", "FUI,U,F,,,", EShLangAll, true }, 795 796 // UINT Width, UINT Height, UINT Samples 797 // UINT Width, UINT Height, UINT Elements, UINT Samples 798 { "GetDimensions", /* 2DMS */ "-", "-", "$2,>S,,", "FUI,U,,", EShLangAll, true }, 799 { "GetDimensions", /* 2DMS */ "-", "-", "$2,>S,,", "FUI,U,,", EShLangAll, true }, 800 { "GetDimensions", /* 2DMSArray */ "-", "-", "&2,>S,,,", "FUI,U,,,", EShLangAll, true }, 801 { "GetDimensions", /* 2DMSArray */ "-", "-", "&2,>S,,,", "FUI,U,,,", EShLangAll, true }, 802 803 // SM5 texture methods 804 { "GatherRed", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll, true }, 805 { "GatherRed", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll, true }, 806 { "GatherRed", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll, true }, 807 { "GatherRed", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll, true }, 808 { "GatherRed", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U", EShLangAll, true }, 809 810 { "GatherGreen", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll, true }, 811 { "GatherGreen", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll, true }, 812 { "GatherGreen", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll, true }, 813 { "GatherGreen", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll, true }, 814 { "GatherGreen", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U", EShLangAll, true }, 815 816 { "GatherBlue", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll, true }, 817 { "GatherBlue", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll, true }, 818 { "GatherBlue", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll, true }, 819 { "GatherBlue", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll, true }, 820 { "GatherBlue", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U", EShLangAll, true }, 821 822 { "GatherAlpha", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll, true }, 823 { "GatherAlpha", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll, true }, 824 { "GatherAlpha", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll, true }, 825 { "GatherAlpha", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll, true }, 826 { "GatherAlpha", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U", EShLangAll, true }, 827 828 { "GatherCmp", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll, true }, 829 { "GatherCmp", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll, true }, 830 { "GatherCmp", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll, true }, 831 { "GatherCmp", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll, true }, 832 { "GatherCmp", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,V,S","FIU,s,F,,I,,,,U",EShLangAll, true }, 833 834 { "GatherCmpRed", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll, true }, 835 { "GatherCmpRed", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll, true }, 836 { "GatherCmpRed", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll, true }, 837 { "GatherCmpRed", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll, true }, 838 { "GatherCmpRed", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,V,S","FIU,s,F,,I,,,,U",EShLangAll, true }, 839 840 { "GatherCmpGreen", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll, true }, 841 { "GatherCmpGreen", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll, true }, 842 { "GatherCmpGreen", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll, true }, 843 { "GatherCmpGreen", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll, true }, 844 { "GatherCmpGreen", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll, true }, 845 846 { "GatherCmpBlue", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll, true }, 847 { "GatherCmpBlue", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll, true }, 848 { "GatherCmpBlue", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll, true }, 849 { "GatherCmpBlue", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll, true }, 850 { "GatherCmpBlue", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll, true }, 851 852 { "GatherCmpAlpha", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll, true }, 853 { "GatherCmpAlpha", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll, true }, 854 { "GatherCmpAlpha", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll, true }, 855 { "GatherCmpAlpha", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll, true }, 856 { "GatherCmpAlpha", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll, true }, 857 858 // geometry methods 859 { "Append", "-", "-", "-", "-", EShLangGS , true }, 860 { "RestartStrip", "-", "-", "-", "-", EShLangGS , true }, 861 862 // Methods for structurebuffers. TODO: wildcard type matching. 863 { "Load", nullptr, nullptr, "-", "-", EShLangAll, true }, 864 { "Load2", nullptr, nullptr, "-", "-", EShLangAll, true }, 865 { "Load3", nullptr, nullptr, "-", "-", EShLangAll, true }, 866 { "Load4", nullptr, nullptr, "-", "-", EShLangAll, true }, 867 { "Store", nullptr, nullptr, "-", "-", EShLangAll, true }, 868 { "Store2", nullptr, nullptr, "-", "-", EShLangAll, true }, 869 { "Store3", nullptr, nullptr, "-", "-", EShLangAll, true }, 870 { "Store4", nullptr, nullptr, "-", "-", EShLangAll, true }, 871 { "GetDimensions", nullptr, nullptr, "-", "-", EShLangAll, true }, 872 { "InterlockedAdd", nullptr, nullptr, "-", "-", EShLangAll, true }, 873 { "InterlockedAnd", nullptr, nullptr, "-", "-", EShLangAll, true }, 874 { "InterlockedCompareExchange", nullptr, nullptr, "-", "-", EShLangAll, true }, 875 { "InterlockedCompareStore", nullptr, nullptr, "-", "-", EShLangAll, true }, 876 { "InterlockedExchange", nullptr, nullptr, "-", "-", EShLangAll, true }, 877 { "InterlockedMax", nullptr, nullptr, "-", "-", EShLangAll, true }, 878 { "InterlockedMin", nullptr, nullptr, "-", "-", EShLangAll, true }, 879 { "InterlockedOr", nullptr, nullptr, "-", "-", EShLangAll, true }, 880 { "InterlockedXor", nullptr, nullptr, "-", "-", EShLangAll, true }, 881 { "IncrementCounter", nullptr, nullptr, "-", "-", EShLangAll, true }, 882 { "DecrementCounter", nullptr, nullptr, "-", "-", EShLangAll, true }, 883 { "Consume", nullptr, nullptr, "-", "-", EShLangAll, true }, 884 885 // Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet. 886 { nullptr, nullptr, nullptr, nullptr, nullptr, 0, false }, 887 }; 888 889 // Create prototypes for the intrinsics. TODO: Avoid ranged based for until all compilers can handle it. 890 for (int icount = 0; hlslIntrinsics[icount].name; ++icount) { 891 const auto& intrinsic = hlslIntrinsics[icount]; 892 893 for (int stage = 0; stage < EShLangCount; ++stage) { // for each stage... 894 if ((intrinsic.stage & (1<<stage)) == 0) // skip inapplicable stages 895 continue; 896 897 // reference to either the common builtins, or stage specific builtins. 898 TString& s = (intrinsic.stage == EShLangAll) ? commonBuiltins : stageBuiltins[stage]; 899 900 for (const char* argOrder = intrinsic.argOrder; !IsEndOfArg(argOrder); ++argOrder) { // for each order... 901 const bool isTexture = IsTextureType(*argOrder); 902 const bool isArrayed = IsArrayed(*argOrder); 903 const bool isMS = IsTextureMS(*argOrder); 904 const bool isBuffer = IsBuffer(*argOrder); 905 const bool isImage = IsImage(*argOrder); 906 const bool mipInCoord = HasMipInCoord(intrinsic.name, isMS, isBuffer, isImage); 907 const int fixedVecSize = FixedVecSize(argOrder); 908 const int coordArg = CoordinateArgPos(intrinsic.name, isTexture); 909 910 // calculate min and max vector and matrix dimensions 911 int dim0Min = 1; 912 int dim0Max = 1; 913 int dim1Min = 1; 914 int dim1Max = 1; 915 916 FindVectorMatrixBounds(argOrder, fixedVecSize, dim0Min, dim0Max, dim1Min, dim1Max); 917 918 for (const char* argType = intrinsic.argType; !IsEndOfArg(argType); ++argType) { // for each type... 919 for (int dim0 = dim0Min; dim0 <= dim0Max; ++dim0) { // for each dim 0... 920 for (int dim1 = dim1Min; dim1 <= dim1Max; ++dim1) { // for each dim 1... 921 const char* retOrder = intrinsic.retOrder ? intrinsic.retOrder : argOrder; 922 const char* retType = intrinsic.retType ? intrinsic.retType : argType; 923 924 if (!IsValid(intrinsic.name, *retOrder, *retType, *argOrder, *argType, dim0, dim1)) 925 continue; 926 927 // Reject some forms of sample methods that don't exist. 928 if (isTexture && IsIllegalSample(intrinsic.name, argOrder, dim0)) 929 continue; 930 931 AppendTypeName(s, retOrder, retType, dim0, dim1); // add return type 932 s.append(" "); // space between type and name 933 934 // methods have a prefix. TODO: it would be better as an invalid identifier character, 935 // but that requires a scanner change. 936 if (intrinsic.method) 937 s.append(BUILTIN_PREFIX); 938 939 s.append(intrinsic.name); // intrinsic name 940 s.append("("); // open paren 941 942 const char* prevArgOrder = nullptr; 943 const char* prevArgType = nullptr; 944 945 // Append argument types, if any. 946 for (int arg = 0; ; ++arg) { 947 const char* nthArgOrder(NthArg(argOrder, arg)); 948 const char* nthArgType(NthArg(argType, arg)); 949 950 if (nthArgOrder == nullptr || nthArgType == nullptr) 951 break; 952 953 // cube textures use vec3 coordinates 954 int argDim0 = isTexture && arg > 0 ? std::min(dim0, 3) : dim0; 955 956 s.append(arg > 0 ? ", ": ""); // comma separator if needed 957 958 const char* orderBegin = nthArgOrder; 959 nthArgOrder = IoParam(s, nthArgOrder); 960 961 // Comma means use the previous argument order and type. 962 HandleRepeatArg(nthArgOrder, prevArgOrder, orderBegin); 963 HandleRepeatArg(nthArgType, prevArgType, nthArgType); 964 965 // In case the repeated arg has its own I/O marker 966 nthArgOrder = IoParam(s, nthArgOrder); 967 968 // arrayed textures have one extra coordinate dimension, except for 969 // the CalculateLevelOfDetail family. 970 if (isArrayed && arg == coordArg && !NoArrayCoord(intrinsic.name)) 971 argDim0++; 972 973 // Some texture methods use an addition arg dimension to hold mip 974 if (arg == coordArg && mipInCoord) 975 argDim0++; 976 977 // For textures, the 1D case isn't a 1-vector, but a scalar. 978 if (isTexture && argDim0 == 1 && arg > 0 && *nthArgOrder == 'V') 979 nthArgOrder = "S"; 980 981 AppendTypeName(s, nthArgOrder, nthArgType, argDim0, dim1); // Add arguments 982 } 983 984 s.append(");\n"); // close paren and trailing semicolon 985 } // dim 1 loop 986 } // dim 0 loop 987 } // arg type loop 988 989 // skip over special characters 990 if (isTexture && isalpha(argOrder[1])) 991 ++argOrder; 992 if (isdigit(argOrder[1])) 993 ++argOrder; 994 } // arg order loop 995 996 if (intrinsic.stage == EShLangAll) // common builtins are only added once. 997 break; 998 } 999 } 1000 1001 createMatTimesMat(); // handle this case separately, for convenience 1002 1003 // printf("Common:\n%s\n", getCommonString().c_str()); 1004 // printf("Frag:\n%s\n", getStageString(EShLangFragment).c_str()); 1005 // printf("Vertex:\n%s\n", getStageString(EShLangVertex).c_str()); 1006 // printf("Geo:\n%s\n", getStageString(EShLangGeometry).c_str()); 1007 // printf("TessCtrl:\n%s\n", getStageString(EShLangTessControl).c_str()); 1008 // printf("TessEval:\n%s\n", getStageString(EShLangTessEvaluation).c_str()); 1009 // printf("Compute:\n%s\n", getStageString(EShLangCompute).c_str()); 1010 } 1011 1012 // 1013 // Add context-dependent built-in functions and variables that are present 1014 // for the given version and profile. All the results are put into just the 1015 // commonBuiltins, because it is called for just a specific stage. So, 1016 // add stage-specific entries to the commonBuiltins, and only if that stage 1017 // was requested. 1018 // 1019 void TBuiltInParseablesHlsl::initialize(const TBuiltInResource& /*resources*/, int /*version*/, EProfile /*profile*/, 1020 const SpvVersion& /*spvVersion*/, EShLanguage /*language*/) 1021 { 1022 } 1023 1024 // 1025 // Finish adding/processing context-independent built-in symbols. 1026 // 1) Programmatically add symbols that could not be added by simple text strings above. 1027 // 2) Map built-in functions to operators, for those that will turn into an operation node 1028 // instead of remaining a function call. 1029 // 3) Tag extension-related symbols added to their base version with their extensions, so 1030 // that if an early version has the extension turned off, there is an error reported on use. 1031 // 1032 void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/, 1033 TSymbolTable& symbolTable) 1034 { 1035 // symbolTable.relateToOperator("abort", EOpAbort); 1036 symbolTable.relateToOperator("abs", EOpAbs); 1037 symbolTable.relateToOperator("acos", EOpAcos); 1038 symbolTable.relateToOperator("all", EOpAll); 1039 symbolTable.relateToOperator("AllMemoryBarrier", EOpMemoryBarrier); 1040 symbolTable.relateToOperator("AllMemoryBarrierWithGroupSync", EOpAllMemoryBarrierWithGroupSync); 1041 symbolTable.relateToOperator("any", EOpAny); 1042 symbolTable.relateToOperator("asdouble", EOpAsDouble); 1043 symbolTable.relateToOperator("asfloat", EOpIntBitsToFloat); 1044 symbolTable.relateToOperator("asin", EOpAsin); 1045 symbolTable.relateToOperator("asint", EOpFloatBitsToInt); 1046 symbolTable.relateToOperator("asuint", EOpFloatBitsToUint); 1047 symbolTable.relateToOperator("atan", EOpAtan); 1048 symbolTable.relateToOperator("atan2", EOpAtan); 1049 symbolTable.relateToOperator("ceil", EOpCeil); 1050 // symbolTable.relateToOperator("CheckAccessFullyMapped"); 1051 symbolTable.relateToOperator("clamp", EOpClamp); 1052 symbolTable.relateToOperator("clip", EOpClip); 1053 symbolTable.relateToOperator("cos", EOpCos); 1054 symbolTable.relateToOperator("cosh", EOpCosh); 1055 symbolTable.relateToOperator("countbits", EOpBitCount); 1056 symbolTable.relateToOperator("cross", EOpCross); 1057 symbolTable.relateToOperator("D3DCOLORtoUBYTE4", EOpD3DCOLORtoUBYTE4); 1058 symbolTable.relateToOperator("ddx", EOpDPdx); 1059 symbolTable.relateToOperator("ddx_coarse", EOpDPdxCoarse); 1060 symbolTable.relateToOperator("ddx_fine", EOpDPdxFine); 1061 symbolTable.relateToOperator("ddy", EOpDPdy); 1062 symbolTable.relateToOperator("ddy_coarse", EOpDPdyCoarse); 1063 symbolTable.relateToOperator("ddy_fine", EOpDPdyFine); 1064 symbolTable.relateToOperator("degrees", EOpDegrees); 1065 symbolTable.relateToOperator("determinant", EOpDeterminant); 1066 symbolTable.relateToOperator("DeviceMemoryBarrier", EOpGroupMemoryBarrier); 1067 symbolTable.relateToOperator("DeviceMemoryBarrierWithGroupSync", EOpGroupMemoryBarrierWithGroupSync); // ... 1068 symbolTable.relateToOperator("distance", EOpDistance); 1069 symbolTable.relateToOperator("dot", EOpDot); 1070 symbolTable.relateToOperator("dst", EOpDst); 1071 // symbolTable.relateToOperator("errorf", EOpErrorf); 1072 symbolTable.relateToOperator("EvaluateAttributeAtCentroid", EOpInterpolateAtCentroid); 1073 symbolTable.relateToOperator("EvaluateAttributeAtSample", EOpInterpolateAtSample); 1074 symbolTable.relateToOperator("EvaluateAttributeSnapped", EOpEvaluateAttributeSnapped); 1075 symbolTable.relateToOperator("exp", EOpExp); 1076 symbolTable.relateToOperator("exp2", EOpExp2); 1077 symbolTable.relateToOperator("f16tof32", EOpF16tof32); 1078 symbolTable.relateToOperator("f32tof16", EOpF32tof16); 1079 symbolTable.relateToOperator("faceforward", EOpFaceForward); 1080 symbolTable.relateToOperator("firstbithigh", EOpFindMSB); 1081 symbolTable.relateToOperator("firstbitlow", EOpFindLSB); 1082 symbolTable.relateToOperator("floor", EOpFloor); 1083 symbolTable.relateToOperator("fma", EOpFma); 1084 symbolTable.relateToOperator("fmod", EOpMod); 1085 symbolTable.relateToOperator("frac", EOpFract); 1086 symbolTable.relateToOperator("frexp", EOpFrexp); 1087 symbolTable.relateToOperator("fwidth", EOpFwidth); 1088 // symbolTable.relateToOperator("GetRenderTargetSampleCount"); 1089 // symbolTable.relateToOperator("GetRenderTargetSamplePosition"); 1090 symbolTable.relateToOperator("GroupMemoryBarrier", EOpWorkgroupMemoryBarrier); 1091 symbolTable.relateToOperator("GroupMemoryBarrierWithGroupSync", EOpWorkgroupMemoryBarrierWithGroupSync); 1092 symbolTable.relateToOperator("InterlockedAdd", EOpInterlockedAdd); 1093 symbolTable.relateToOperator("InterlockedAnd", EOpInterlockedAnd); 1094 symbolTable.relateToOperator("InterlockedCompareExchange", EOpInterlockedCompareExchange); 1095 symbolTable.relateToOperator("InterlockedCompareStore", EOpInterlockedCompareStore); 1096 symbolTable.relateToOperator("InterlockedExchange", EOpInterlockedExchange); 1097 symbolTable.relateToOperator("InterlockedMax", EOpInterlockedMax); 1098 symbolTable.relateToOperator("InterlockedMin", EOpInterlockedMin); 1099 symbolTable.relateToOperator("InterlockedOr", EOpInterlockedOr); 1100 symbolTable.relateToOperator("InterlockedXor", EOpInterlockedXor); 1101 symbolTable.relateToOperator("isfinite", EOpIsFinite); 1102 symbolTable.relateToOperator("isinf", EOpIsInf); 1103 symbolTable.relateToOperator("isnan", EOpIsNan); 1104 symbolTable.relateToOperator("ldexp", EOpLdexp); 1105 symbolTable.relateToOperator("length", EOpLength); 1106 symbolTable.relateToOperator("lerp", EOpMix); 1107 symbolTable.relateToOperator("lit", EOpLit); 1108 symbolTable.relateToOperator("log", EOpLog); 1109 symbolTable.relateToOperator("log10", EOpLog10); 1110 symbolTable.relateToOperator("log2", EOpLog2); 1111 symbolTable.relateToOperator("mad", EOpFma); 1112 symbolTable.relateToOperator("max", EOpMax); 1113 symbolTable.relateToOperator("min", EOpMin); 1114 symbolTable.relateToOperator("modf", EOpModf); 1115 // symbolTable.relateToOperator("msad4", EOpMsad4); 1116 symbolTable.relateToOperator("mul", EOpGenMul); 1117 // symbolTable.relateToOperator("noise", EOpNoise); // TODO: check return type 1118 symbolTable.relateToOperator("normalize", EOpNormalize); 1119 symbolTable.relateToOperator("pow", EOpPow); 1120 // symbolTable.relateToOperator("printf", EOpPrintf); 1121 // symbolTable.relateToOperator("Process2DQuadTessFactorsAvg"); 1122 // symbolTable.relateToOperator("Process2DQuadTessFactorsMax"); 1123 // symbolTable.relateToOperator("Process2DQuadTessFactorsMin"); 1124 // symbolTable.relateToOperator("ProcessIsolineTessFactors"); 1125 // symbolTable.relateToOperator("ProcessQuadTessFactorsAvg"); 1126 // symbolTable.relateToOperator("ProcessQuadTessFactorsMax"); 1127 // symbolTable.relateToOperator("ProcessQuadTessFactorsMin"); 1128 // symbolTable.relateToOperator("ProcessTriTessFactorsAvg"); 1129 // symbolTable.relateToOperator("ProcessTriTessFactorsMax"); 1130 // symbolTable.relateToOperator("ProcessTriTessFactorsMin"); 1131 symbolTable.relateToOperator("radians", EOpRadians); 1132 symbolTable.relateToOperator("rcp", EOpRcp); 1133 symbolTable.relateToOperator("reflect", EOpReflect); 1134 symbolTable.relateToOperator("refract", EOpRefract); 1135 symbolTable.relateToOperator("reversebits", EOpBitFieldReverse); 1136 symbolTable.relateToOperator("round", EOpRoundEven); 1137 symbolTable.relateToOperator("rsqrt", EOpInverseSqrt); 1138 symbolTable.relateToOperator("saturate", EOpSaturate); 1139 symbolTable.relateToOperator("sign", EOpSign); 1140 symbolTable.relateToOperator("sin", EOpSin); 1141 symbolTable.relateToOperator("sincos", EOpSinCos); 1142 symbolTable.relateToOperator("sinh", EOpSinh); 1143 symbolTable.relateToOperator("smoothstep", EOpSmoothStep); 1144 symbolTable.relateToOperator("sqrt", EOpSqrt); 1145 symbolTable.relateToOperator("step", EOpStep); 1146 symbolTable.relateToOperator("tan", EOpTan); 1147 symbolTable.relateToOperator("tanh", EOpTanh); 1148 symbolTable.relateToOperator("tex1D", EOpTexture); 1149 symbolTable.relateToOperator("tex1Dbias", EOpTextureBias); 1150 symbolTable.relateToOperator("tex1Dgrad", EOpTextureGrad); 1151 symbolTable.relateToOperator("tex1Dlod", EOpTextureLod); 1152 symbolTable.relateToOperator("tex1Dproj", EOpTextureProj); 1153 symbolTable.relateToOperator("tex2D", EOpTexture); 1154 symbolTable.relateToOperator("tex2Dbias", EOpTextureBias); 1155 symbolTable.relateToOperator("tex2Dgrad", EOpTextureGrad); 1156 symbolTable.relateToOperator("tex2Dlod", EOpTextureLod); 1157 symbolTable.relateToOperator("tex2Dproj", EOpTextureProj); 1158 symbolTable.relateToOperator("tex3D", EOpTexture); 1159 symbolTable.relateToOperator("tex3Dbias", EOpTextureBias); 1160 symbolTable.relateToOperator("tex3Dgrad", EOpTextureGrad); 1161 symbolTable.relateToOperator("tex3Dlod", EOpTextureLod); 1162 symbolTable.relateToOperator("tex3Dproj", EOpTextureProj); 1163 symbolTable.relateToOperator("texCUBE", EOpTexture); 1164 symbolTable.relateToOperator("texCUBEbias", EOpTextureBias); 1165 symbolTable.relateToOperator("texCUBEgrad", EOpTextureGrad); 1166 symbolTable.relateToOperator("texCUBElod", EOpTextureLod); 1167 symbolTable.relateToOperator("texCUBEproj", EOpTextureProj); 1168 symbolTable.relateToOperator("transpose", EOpTranspose); 1169 symbolTable.relateToOperator("trunc", EOpTrunc); 1170 1171 // Texture methods 1172 symbolTable.relateToOperator(BUILTIN_PREFIX "Sample", EOpMethodSample); 1173 symbolTable.relateToOperator(BUILTIN_PREFIX "SampleBias", EOpMethodSampleBias); 1174 symbolTable.relateToOperator(BUILTIN_PREFIX "SampleCmp", EOpMethodSampleCmp); 1175 symbolTable.relateToOperator(BUILTIN_PREFIX "SampleCmpLevelZero", EOpMethodSampleCmpLevelZero); 1176 symbolTable.relateToOperator(BUILTIN_PREFIX "SampleGrad", EOpMethodSampleGrad); 1177 symbolTable.relateToOperator(BUILTIN_PREFIX "SampleLevel", EOpMethodSampleLevel); 1178 symbolTable.relateToOperator(BUILTIN_PREFIX "Load", EOpMethodLoad); 1179 symbolTable.relateToOperator(BUILTIN_PREFIX "GetDimensions", EOpMethodGetDimensions); 1180 symbolTable.relateToOperator(BUILTIN_PREFIX "GetSamplePosition", EOpMethodGetSamplePosition); 1181 symbolTable.relateToOperator(BUILTIN_PREFIX "Gather", EOpMethodGather); 1182 symbolTable.relateToOperator(BUILTIN_PREFIX "CalculateLevelOfDetail", EOpMethodCalculateLevelOfDetail); 1183 symbolTable.relateToOperator(BUILTIN_PREFIX "CalculateLevelOfDetailUnclamped", EOpMethodCalculateLevelOfDetailUnclamped); 1184 1185 // Structure buffer methods (excluding associations already made above for texture methods w/ same name) 1186 symbolTable.relateToOperator(BUILTIN_PREFIX "Load2", EOpMethodLoad2); 1187 symbolTable.relateToOperator(BUILTIN_PREFIX "Load3", EOpMethodLoad3); 1188 symbolTable.relateToOperator(BUILTIN_PREFIX "Load4", EOpMethodLoad4); 1189 symbolTable.relateToOperator(BUILTIN_PREFIX "Store", EOpMethodStore); 1190 symbolTable.relateToOperator(BUILTIN_PREFIX "Store2", EOpMethodStore2); 1191 symbolTable.relateToOperator(BUILTIN_PREFIX "Store3", EOpMethodStore3); 1192 symbolTable.relateToOperator(BUILTIN_PREFIX "Store4", EOpMethodStore4); 1193 symbolTable.relateToOperator(BUILTIN_PREFIX "IncrementCounter", EOpMethodIncrementCounter); 1194 symbolTable.relateToOperator(BUILTIN_PREFIX "DecrementCounter", EOpMethodDecrementCounter); 1195 // Append is also a GS method: we don't add it twice 1196 symbolTable.relateToOperator(BUILTIN_PREFIX "Consume", EOpMethodConsume); 1197 1198 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedAdd", EOpInterlockedAdd); 1199 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedAnd", EOpInterlockedAnd); 1200 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedCompareExchange", EOpInterlockedCompareExchange); 1201 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedCompareStore", EOpInterlockedCompareStore); 1202 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedExchange", EOpInterlockedExchange); 1203 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedMax", EOpInterlockedMax); 1204 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedMin", EOpInterlockedMin); 1205 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedOr", EOpInterlockedOr); 1206 symbolTable.relateToOperator(BUILTIN_PREFIX "InterlockedXor", EOpInterlockedXor); 1207 1208 // SM5 Texture methods 1209 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherRed", EOpMethodGatherRed); 1210 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherGreen", EOpMethodGatherGreen); 1211 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherBlue", EOpMethodGatherBlue); 1212 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherAlpha", EOpMethodGatherAlpha); 1213 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherCmp", EOpMethodGatherCmpRed); // alias 1214 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherCmpRed", EOpMethodGatherCmpRed); 1215 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherCmpGreen", EOpMethodGatherCmpGreen); 1216 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherCmpBlue", EOpMethodGatherCmpBlue); 1217 symbolTable.relateToOperator(BUILTIN_PREFIX "GatherCmpAlpha", EOpMethodGatherCmpAlpha); 1218 1219 // GS methods 1220 symbolTable.relateToOperator(BUILTIN_PREFIX "Append", EOpMethodAppend); 1221 symbolTable.relateToOperator(BUILTIN_PREFIX "RestartStrip", EOpMethodRestartStrip); 1222 } 1223 1224 // 1225 // Add context-dependent (resource-specific) built-ins not handled by the above. These 1226 // would be ones that need to be programmatically added because they cannot 1227 // be added by simple text strings. For these, also 1228 // 1) Map built-in functions to operators, for those that will turn into an operation node 1229 // instead of remaining a function call. 1230 // 2) Tag extension-related symbols added to their base version with their extensions, so 1231 // that if an early version has the extension turned off, there is an error reported on use. 1232 // 1233 void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/, 1234 TSymbolTable& /*symbolTable*/, const TBuiltInResource& /*resources*/) 1235 { 1236 } 1237 1238 } // end namespace glslang 1239