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 <cctype> 53 #include <utility> 54 #include <algorithm> 55 56 namespace { // anonymous namespace functions 57 58 const bool UseHlslTypes = false; 59 60 const char* BaseTypeName(const char argOrder, const char* scalarName, const char* vecName, const char* matName) 61 { 62 switch (argOrder) { 63 case 'S': return scalarName; 64 case 'V': return vecName; 65 case 'M': return matName; 66 default: return "UNKNOWN_TYPE"; 67 } 68 } 69 70 bool IsTextureType(const char argOrder) { return argOrder == '%' || argOrder == '@'; } 71 bool IsTextureArrayed(const char argOrder) { return argOrder == '@'; } 72 bool IsTextureMS(const char /*argOrder*/) { return false; } // TODO: ... 73 74 // Reject certain combinations that are illegal sample methods. For example, 75 // 3D arrays. 76 bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim0) 77 { 78 const bool isArrayed = IsTextureArrayed(*argOrder); 79 const bool isMS = IsTextureMS(*argOrder); 80 81 // there are no 3D arrayed textures, or 3D SampleCmp 82 if (dim0 == 3 && (isArrayed || name == "SampleCmp")) 83 return true; 84 85 const int numArgs = int(std::count(argOrder, argOrder + strlen(argOrder), ',')) + 1; 86 87 // Reject invalid offset arrayed forms with cubemaps 88 if (isArrayed && dim0 == 4) { 89 if ((name == "Sample" && numArgs >= 4) || 90 (name == "SampleBias" && numArgs >= 5) || 91 (name == "SampleCmp" && numArgs >= 5) || 92 (name == "SampleCmpLevelZero" && numArgs >= 4) || 93 (name == "SampleGrad" && numArgs >= 6) || 94 (name == "SampleLevel" && numArgs >= 5)) 95 return true; 96 } 97 98 // Reject invalid Loads 99 if (name == "Load") { 100 if ((numArgs >= 3 && !isMS) || // Load with sampleindex requires multisample 101 (dim0 == 4)) // Load does not support any cubemaps, arrayed or not. 102 return true; 103 } 104 105 return false; 106 } 107 108 // Create and return a type name. This is done in GLSL, not HLSL conventions, until such 109 // time as builtins are parsed using the HLSL parser. 110 // 111 // order: S = scalar, V = vector, M = matrix 112 // argType: F = float, D = double, I = int, U = uint, B = bool, S = sampler 113 // dim0 = vector dimension, or matrix 1st dimension 114 // dim1 = matrix 2nd dimension 115 glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, const char* argType, int dim0, int dim1) 116 { 117 const bool isTranspose = (argOrder[0] == '^'); 118 const bool isMatMul = (argOrder[0] == '#'); 119 const bool isTexture = IsTextureType(argOrder[0]); 120 const bool isArrayed = IsTextureArrayed(argOrder[0]); 121 //const bool isMS = IsTextureMS(argOrder[0]); 122 123 char order = *argOrder; 124 char type = *argType; 125 126 if (isTranspose) { // Take transpose of matrix dimensions 127 order = *++argOrder; 128 std::swap(dim0, dim1); 129 } else if (isMatMul) { 130 order = *++argOrder; 131 dim0 = dim1; // set vector dimension to mat col 132 } else if (isTexture) { 133 order = *++argOrder; 134 if (type == 'F') // map base type to texture of that type. 135 type = 'T'; // e.g, int -> itexture, uint -> utexture, etc. 136 else if (type == 'I') 137 type = 'i'; 138 else if (type == 'U') 139 type = 'u'; 140 } 141 142 if (UseHlslTypes) { 143 switch (type) { 144 case '-': s += "void"; break; 145 case 'F': s += "float"; break; 146 case 'D': s += "double"; break; 147 case 'I': s += "int"; break; 148 case 'U': s += "uint"; break; 149 case 'B': s += "bool"; break; 150 case 'S': s += "sampler"; break; 151 case 'T': s += "Texture"; break; 152 case 'i': s += "Texture <int4>"; break; 153 case 'u': s += "Texture <uint4>"; break; 154 default: s += "UNKNOWN_TYPE"; break; 155 } 156 } else { 157 switch (type) { 158 case '-': s += "void"; break; 159 case 'F': s += BaseTypeName(order, "float", "vec", "mat"); break; 160 case 'D': s += BaseTypeName(order, "double", "dvec", "dmat"); break; 161 case 'I': s += BaseTypeName(order, "int", "ivec", "imat"); break; 162 case 'U': s += BaseTypeName(order, "uint", "uvec", "umat"); break; 163 case 'B': s += BaseTypeName(order, "bool", "bvec", "bmat"); break; 164 case 'S': s += "sampler"; break; 165 case 'T': // fall through 166 case 'i': // ... 167 case 'u': // ... 168 if (type != 'T') 169 s += type; 170 171 s += "texture"; 172 break; 173 174 default: s += "UNKNOWN_TYPE"; break; 175 } 176 } 177 178 // handle fixed vector sizes, such as float3, and only ever 3. 179 const int fixedVecSize = isdigit(argOrder[1]) ? (argOrder[1] - '0') : 0; 180 if (fixedVecSize != 0) 181 dim0 = dim1 = fixedVecSize; 182 183 // Add sampler dimensions 184 if (type == 'S' || isTexture) { 185 if (order == 'V') { 186 switch (dim0) { 187 case 1: s += "1D"; break; 188 case 2: s += "2D"; break; 189 case 3: s += "3D"; break; 190 case 4: s += "Cube"; break; 191 default: s += "UNKNOWN_SAMPLER"; break; 192 } 193 } 194 } else { 195 // Non-sampler type: 196 // verify dimensions 197 if (((order == 'V' || order == 'M') && (dim0 < 1 || dim0 > 4)) || 198 (order == 'M' && (dim1 < 1 || dim1 > 4))) { 199 s += "UNKNOWN_DIMENSION"; 200 return s; 201 } 202 203 switch (order) { 204 case '-': break; // no dimensions for voids 205 case 'S': break; // no dimensions on scalars 206 case 'V': s += ('0' + char(dim0)); break; 207 case 'M': 208 { 209 if (!UseHlslTypes) // GLSL has column first for mat types 210 std::swap(dim0, dim1); 211 s += ('0' + char(dim0)); 212 s += 'x'; 213 s += ('0' + char(dim1)); 214 break; 215 } 216 } 217 } 218 219 // handle arrayed textures 220 if (isArrayed) 221 s += "Array"; 222 223 return s; 224 } 225 226 // TODO: the GLSL parser is currently used to parse HLSL prototypes. However, many valid HLSL prototypes 227 // are not valid GLSL prototypes. This rejects the invalid ones. Thus, there is a single switch below 228 // to enable creation of the entire HLSL space. 229 inline bool IsValidGlsl(const char* cname, char retOrder, char retType, char argOrder, char argType, 230 int dim0, int dim1, int dim0Max, int dim1Max) 231 { 232 const bool isVec = dim0Max > 1 || argType == 'V'; 233 const bool isMat = dim1Max > 1 || argType == 'M'; 234 235 if (!IsTextureType(argOrder) && 236 ((isVec && dim0 == 1) || // avoid vec1 237 (isMat && dim0 == 1 && dim1 == 1))) // avoid mat1x1 238 return false; 239 240 const std::string name(cname); // for ease of comparison. slow, but temporary, until HLSL parser is online. 241 242 if (isMat && dim1 == 1) // TODO: avoid mat Nx1 until we find the right GLSL profile 243 return false; 244 245 if ((isMat && (argType == 'I' || argType == 'U' || argType == 'B')) || 246 (retOrder == 'M' && (retType == 'I' || retType == 'U' || retType == 'B'))) 247 return false; 248 249 if (name == "GetRenderTargetSamplePosition" || 250 name == "tex1D" || 251 name == "tex1Dgrad") 252 return false; 253 254 return true; 255 } 256 257 258 // Return true for the end of a single argument key, which can be the end of the string, or 259 // the comma separator. 260 inline bool IsEndOfArg(const char* arg) 261 { 262 return arg == nullptr || *arg == '\0' || *arg == ','; 263 } 264 265 266 // return position of end of argument specifier 267 inline const char* FindEndOfArg(const char* arg) 268 { 269 while (!IsEndOfArg(arg)) 270 ++arg; 271 272 return *arg == '\0' ? nullptr : arg; 273 } 274 275 // If this is a fixed vector size, such as V3, return the size. Else return 0. 276 int FixedVecSize(const char* arg) 277 { 278 while (!IsEndOfArg(arg)) { 279 if (isdigit(*arg)) 280 return *arg - '0'; 281 ++arg; 282 } 283 284 return 0; // none found. 285 } 286 287 288 // Return pointer to beginning of Nth argument specifier in the string. 289 inline const char* NthArg(const char* arg, int n) 290 { 291 for (int x=0; x<n && arg; ++x) 292 if ((arg = FindEndOfArg(arg)) != nullptr) 293 ++arg; // skip arg separator 294 295 return arg; 296 } 297 298 inline void FindVectorMatrixBounds(const char* argOrder, int fixedVecSize, int& dim0Min, int& dim0Max, int& /*dim1Min*/, int& dim1Max) 299 { 300 for (int arg = 0; ; ++arg) { 301 const char* nthArgOrder(NthArg(argOrder, arg)); 302 if (nthArgOrder == nullptr) 303 break; 304 else if (*nthArgOrder == 'V') 305 dim0Max = 4; 306 else if (*nthArgOrder == 'M') 307 dim0Max = dim1Max = 4; 308 } 309 310 if (fixedVecSize > 0) // handle fixed sized vectors 311 dim0Min = dim0Max = fixedVecSize; 312 } 313 314 } // end anonymous namespace 315 316 namespace glslang { 317 318 TBuiltInParseablesHlsl::TBuiltInParseablesHlsl() 319 { 320 } 321 322 323 // 324 // Handle creation of mat*mat specially, since it doesn't fall conveniently out of 325 // the generic prototype creation code below. 326 // 327 void TBuiltInParseablesHlsl::createMatTimesMat() 328 { 329 TString& s = commonBuiltins; 330 331 const int first = (UseHlslTypes ? 1 : 2); 332 333 for (int xRows = first; xRows <=4; xRows++) { 334 for (int xCols = first; xCols <=4; xCols++) { 335 const int yRows = xCols; 336 for (int yCols = first; yCols <=4; yCols++) { 337 const int retRows = xRows; 338 const int retCols = yCols; 339 340 AppendTypeName(s, "M", "F", retRows, retCols); // add return type 341 s.append(" "); // space between type and name 342 s.append("mul"); // intrinsic name 343 s.append("("); // open paren 344 345 AppendTypeName(s, "M", "F", xRows, xCols); // add X input 346 s.append(", "); 347 AppendTypeName(s, "M", "F", yRows, yCols); // add Y input 348 349 s.append(");\n"); // close paren 350 } 351 } 352 } 353 } 354 355 // 356 // Add all context-independent built-in functions and variables that are present 357 // for the given version and profile. Share common ones across stages, otherwise 358 // make stage-specific entries. 359 // 360 // Most built-ins variables can be added as simple text strings. Some need to 361 // be added programmatically, which is done later in IdentifyBuiltIns() below. 362 // 363 void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/) 364 { 365 static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1); 366 367 // This structure encodes the prototype information for each HLSL intrinsic. 368 // Because explicit enumeration would be cumbersome, it's procedurally generated. 369 // orderKey can be: 370 // S = scalar, V = vector, M = matrix, - = void 371 // typekey can be: 372 // D = double, F = float, U = uint, I = int, B = bool, S = sampler 373 // An empty order or type key repeats the first one. E.g: SVM,, means 3 args each of SVM. 374 // '>' as first letter of order creates an output parameter 375 // '<' as first letter of order creates an input parameter 376 // '^' as first letter of order takes transpose dimensions 377 // '#' as first letter of order sets rows=cols for mats 378 // '%' as first letter of order creates texture of given F/I/U type (texture, itexture, etc) 379 // '@' as first letter of order creates arrayed texture of given type 380 381 static const struct { 382 const char* name; // intrinsic name 383 const char* retOrder; // return type key: empty matches order of 1st argument 384 const char* retType; // return type key: empty matches type of 1st argument 385 const char* argOrder; // argument order key 386 const char* argType; // argument type key 387 unsigned int stage; // stage mask 388 } hlslIntrinsics[] = { 389 // name retOrd retType argOrder argType stage mask 390 // ----------------------------------------------------------------------------------------------- 391 { "abort", nullptr, nullptr, "-", "-", EShLangAll }, 392 { "abs", nullptr, nullptr, "SVM", "DFUI", EShLangAll }, 393 { "acos", nullptr, nullptr, "SVM", "F", EShLangAll }, 394 { "all", "S", "B", "SVM", "BFI", EShLangAll }, 395 { "AllMemoryBarrier", nullptr, nullptr, "-", "-", EShLangComputeMask }, 396 { "AllMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangComputeMask }, 397 { "any", "S", "B", "SVM", "BFI", EShLangAll }, 398 { "asdouble", "S", "D", "S,", "U,", EShLangAll }, 399 { "asdouble", "V2", "D", "V2,", "U,", EShLangAll }, 400 { "asfloat", nullptr, "F", "SVM", "BFIU", EShLangAll }, 401 { "asin", nullptr, nullptr, "SVM", "F", EShLangAll }, 402 { "asint", nullptr, "I", "SVM", "FU", EShLangAll }, 403 { "asuint", nullptr, "U", "SVM", "FU", EShLangAll }, 404 { "atan", nullptr, nullptr, "SVM", "F", EShLangAll }, 405 { "atan2", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 406 { "ceil", nullptr, nullptr, "SVM", "F", EShLangAll }, 407 { "CheckAccessFullyMapped", "S", "B" , "S", "U", EShLangFragmentMask | EShLangComputeMask }, 408 { "clamp", nullptr, nullptr, "SVM,,", "FUI,,", EShLangAll }, 409 { "clip", "-", "-", "SVM", "F", EShLangFragmentMask }, 410 { "cos", nullptr, nullptr, "SVM", "F", EShLangAll }, 411 { "cosh", nullptr, nullptr, "SVM", "F", EShLangAll }, 412 { "countbits", nullptr, nullptr, "SV", "U", EShLangAll }, 413 { "cross", nullptr, nullptr, "V3,", "F,", EShLangAll }, 414 { "D3DCOLORtoUBYTE4", "V4", "I", "V4", "F", EShLangAll }, 415 { "ddx", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 416 { "ddx_coarse", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 417 { "ddx_fine", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 418 { "ddy", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 419 { "ddy_coarse", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 420 { "ddy_fine", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 421 { "degrees", nullptr, nullptr, "SVM", "F", EShLangAll }, 422 { "determinant", "S", "F", "M", "F", EShLangAll }, 423 { "DeviceMemoryBarrier", nullptr, nullptr, "-", "-", EShLangFragmentMask | EShLangComputeMask }, 424 { "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangComputeMask }, 425 { "distance", "S", "F", "V,", "F,", EShLangAll }, 426 { "dot", "S", nullptr, "V,", "FI,", EShLangAll }, 427 { "dst", nullptr, nullptr, "V4,V4", "F,", EShLangAll }, 428 // { "errorf", "-", "-", "", "", EShLangAll }, TODO: varargs 429 { "EvaluateAttributeAtCentroid", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 430 { "EvaluateAttributeAtSample", nullptr, nullptr, "SVM,S", "F,U", EShLangFragmentMask }, 431 { "EvaluateAttributeSnapped", nullptr, nullptr, "SVM,V2", "F,I", EShLangFragmentMask }, 432 { "exp", nullptr, nullptr, "SVM", "F", EShLangAll }, 433 { "exp2", nullptr, nullptr, "SVM", "F", EShLangAll }, 434 { "f16tof32", nullptr, "F", "SV", "U", EShLangAll }, 435 { "f32tof16", nullptr, "U", "SV", "F", EShLangAll }, 436 { "faceforward", nullptr, nullptr, "V,,", "F,,", EShLangAll }, 437 { "firstbithigh", nullptr, nullptr, "SV", "UI", EShLangAll }, 438 { "firstbitlow", nullptr, nullptr, "SV", "UI", EShLangAll }, 439 { "floor", nullptr, nullptr, "SVM", "F", EShLangAll }, 440 { "fma", nullptr, nullptr, "SVM,,", "D,,", EShLangAll }, 441 { "fmod", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 442 { "frac", nullptr, nullptr, "SVM", "F", EShLangAll }, 443 { "frexp", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 444 { "fwidth", nullptr, nullptr, "SVM", "F", EShLangFragmentMask }, 445 { "GetRenderTargetSampleCount", "S", "U", "-", "-", EShLangAll }, 446 { "GetRenderTargetSamplePosition", "V2", "F", "V1", "I", EShLangAll }, 447 { "GroupMemoryBarrier", nullptr, nullptr, "-", "-", EShLangComputeMask }, 448 { "GroupMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangComputeMask }, 449 { "InterlockedAdd", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 450 { "InterlockedAdd", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 451 { "InterlockedAnd", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 452 { "InterlockedAnd", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 453 { "InterlockedCompareExchange", "-", "-", "SVM,,,>", "UI,,,", EShLangFragmentMask | EShLangComputeMask }, 454 { "InterlockedCompareStore", "-", "-", "SVM,,", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 455 { "InterlockedExchange", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 456 { "InterlockedMax", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 457 { "InterlockedMax", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 458 { "InterlockedMin", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 459 { "InterlockedMin", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 460 { "InterlockedOr", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 461 { "InterlockedOr", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 462 { "InterlockedXor", "-", "-", "SVM,,>", "UI,,", EShLangFragmentMask | EShLangComputeMask }, 463 { "InterlockedXor", "-", "-", "SVM,", "UI,", EShLangFragmentMask | EShLangComputeMask }, 464 { "isfinite", nullptr, "B" , "SVM", "F", EShLangAll }, 465 { "isinf", nullptr, "B" , "SVM", "F", EShLangAll }, 466 { "isnan", nullptr, "B" , "SVM", "F", EShLangAll }, 467 { "ldexp", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 468 { "length", "S", "F", "V", "F", EShLangAll }, 469 { "lerp", nullptr, nullptr, "SVM,,", "F,,", EShLangAll }, 470 { "lit", "V4", "F", "S,,", "F,,", EShLangAll }, 471 { "log", nullptr, nullptr, "SVM", "F", EShLangAll }, 472 { "log10", nullptr, nullptr, "SVM", "F", EShLangAll }, 473 { "log2", nullptr, nullptr, "SVM", "F", EShLangAll }, 474 { "mad", nullptr, nullptr, "SVM,,", "DFUI,,", EShLangAll }, 475 { "max", nullptr, nullptr, "SVM,", "FI,", EShLangAll }, 476 { "min", nullptr, nullptr, "SVM,", "FI,", EShLangAll }, 477 { "modf", nullptr, nullptr, "SVM,>", "FI,", EShLangAll }, 478 { "msad4", "V4", "U", "S,V2,V4", "U,,", EShLangAll }, 479 { "mul", "S", nullptr, "S,S", "FI,", EShLangAll }, 480 { "mul", "V", nullptr, "S,V", "FI,", EShLangAll }, 481 { "mul", "M", nullptr, "S,M", "FI,", EShLangAll }, 482 { "mul", "V", nullptr, "V,S", "FI,", EShLangAll }, 483 { "mul", "S", nullptr, "V,V", "FI,", EShLangAll }, 484 { "mul", "#V", nullptr, "V,M", "FI,", EShLangAll }, 485 { "mul", "M", nullptr, "M,S", "FI,", EShLangAll }, 486 { "mul", "V", nullptr, "M,#V", "FI,", EShLangAll }, 487 // mat*mat form of mul is handled in createMatTimesMat() 488 { "noise", "S", "F", "V", "F", EShLangFragmentMask }, 489 { "normalize", nullptr, nullptr, "V", "F", EShLangAll }, 490 { "pow", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 491 // { "printf", "-", "-", "", "", EShLangAll }, TODO: varargs 492 { "Process2DQuadTessFactorsAvg", "-", "-", "V4,V2,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 493 { "Process2DQuadTessFactorsMax", "-", "-", "V4,V2,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 494 { "Process2DQuadTessFactorsMin", "-", "-", "V4,V2,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 495 { "ProcessIsolineTessFactors", "-", "-", "S,,>,>", "F,,,", EShLangTessControlMask }, 496 { "ProcessQuadTessFactorsAvg", "-", "-", "V4,S,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 497 { "ProcessQuadTessFactorsMax", "-", "-", "V4,S,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 498 { "ProcessQuadTessFactorsMin", "-", "-", "V4,S,>V4,>V2,>V2", "F,,,,", EShLangTessControlMask }, 499 { "ProcessTriTessFactorsAvg", "-", "-", "V3,S,>V3,>S,>S", "F,,,,", EShLangTessControlMask }, 500 { "ProcessTriTessFactorsMax", "-", "-", "V3,S,>V3,>S,>S", "F,,,,", EShLangTessControlMask }, 501 { "ProcessTriTessFactorsMin", "-", "-", "V3,S,>V3,>S,>S", "F,,,,", EShLangTessControlMask }, 502 { "radians", nullptr, nullptr, "SVM", "F", EShLangAll }, 503 { "rcp", nullptr, nullptr, "SVM", "FD", EShLangAll }, 504 { "reflect", nullptr, nullptr, "V,", "F,", EShLangAll }, 505 { "refract", nullptr, nullptr, "V,V,S", "F,,", EShLangAll }, 506 { "reversebits", nullptr, nullptr, "SV", "U", EShLangAll }, 507 { "round", nullptr, nullptr, "SVM", "F", EShLangAll }, 508 { "rsqrt", nullptr, nullptr, "SVM", "F", EShLangAll }, 509 { "saturate", nullptr, nullptr , "SVM", "F", EShLangAll }, 510 { "sign", nullptr, nullptr, "SVM", "FI", EShLangAll }, 511 { "sin", nullptr, nullptr, "SVM", "F", EShLangAll }, 512 { "sincos", "-", "-", "SVM,>,>", "F,,", EShLangAll }, 513 { "sinh", nullptr, nullptr, "SVM", "F", EShLangAll }, 514 { "smoothstep", nullptr, nullptr, "SVM,,", "F,,", EShLangAll }, 515 { "sqrt", nullptr, nullptr, "SVM", "F", EShLangAll }, 516 { "step", nullptr, nullptr, "SVM,", "F,", EShLangAll }, 517 { "tan", nullptr, nullptr, "SVM", "F", EShLangAll }, 518 { "tanh", nullptr, nullptr, "SVM", "F", EShLangAll }, 519 { "tex1D", "V4", "F", "V1,S", "S,F", EShLangFragmentMask }, 520 { "tex1D", "V4", "F", "V1,S,V1,V1", "S,F,F,F",EShLangFragmentMask }, 521 { "tex1Dbias", "V4", "F", "V1,V4", "S,F", EShLangFragmentMask }, 522 { "tex1Dgrad", "V4", "F", "V1,V1,V1,V1","S,F,F,F",EShLangFragmentMask }, 523 { "tex1Dlod", "V4", "F", "V1,V4", "S,F", EShLangFragmentMask }, 524 { "tex1Dproj", "V4", "F", "V1,V4", "S,F", EShLangFragmentMask }, 525 { "tex2D", "V4", "F", "V2,V2", "S,F", EShLangFragmentMask }, 526 { "tex2D", "V4", "F", "V2,V2,V2,V2","S,F,F,F",EShLangFragmentMask }, 527 { "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangFragmentMask }, 528 { "tex2Dgrad", "V4", "F", "V2,V2,V2,V2","S,F,F,F",EShLangFragmentMask }, 529 { "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangFragmentMask }, 530 { "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangFragmentMask }, 531 { "tex3D", "V4", "F", "V3,V3", "S,F", EShLangFragmentMask }, 532 { "tex3D", "V4", "F", "V3,V3,V3,V3","S,F,F,F",EShLangFragmentMask }, 533 { "tex3Dbias", "V4", "F", "V3,V4", "S,F", EShLangFragmentMask }, 534 { "tex3Dgrad", "V4", "F", "V3,V3,V3,V3","S,F,F,F",EShLangFragmentMask }, 535 { "tex3Dlod", "V4", "F", "V3,V4", "S,F", EShLangFragmentMask }, 536 { "tex3Dproj", "V4", "F", "V3,V4", "S,F", EShLangFragmentMask }, 537 { "texCUBE", "V4", "F", "V4,V3", "S,F", EShLangFragmentMask }, 538 { "texCUBE", "V4", "F", "V4,V3,V3,V3","S,F,F,F",EShLangFragmentMask }, 539 { "texCUBEbias", "V4", "F", "V4,V4", "S,F", EShLangFragmentMask }, 540 { "texCUBEgrad", "V4", "F", "V4,V3,V3,V3","S,F,F,F",EShLangFragmentMask }, 541 { "texCUBElod", "V4", "F", "V4,V4", "S,F", EShLangFragmentMask }, 542 { "texCUBEproj", "V4", "F", "V4,V4", "S,F", EShLangFragmentMask }, 543 { "transpose", "^M", nullptr, "M", "F", EShLangAll }, 544 { "trunc", nullptr, nullptr, "SVM", "F", EShLangAll }, 545 546 // Texture object methods. Return type can be overridden by shader declaration. 547 // !O = no offset, O = offset, !A = no array, A = array 548 { "Sample", /*!O !A*/ "V4", nullptr, "%V,S,V", "FIU,S,F", EShLangFragmentMask }, 549 { "Sample", /* O !A*/ "V4", nullptr, "%V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, 550 { "Sample", /*!O A*/ "V4", nullptr, "@V,S,V", "FIU,S,F", EShLangFragmentMask }, 551 { "Sample", /* O A*/ "V4", nullptr, "@V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, 552 553 { "SampleBias", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 554 { "SampleBias", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 555 { "SampleBias", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 556 { "SampleBias", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 557 558 // { "SampleCmp", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 559 // { "SampleCmp", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 560 // { "SampleCmp", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 561 // { "SampleCmp", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 562 563 // { "SampleCmpLevelZero", /*!O !A*/ "V4", nullptr, "%V,S,V", "FIU,S,F", EShLangFragmentMask }, 564 // { "SampleCmpLevelZero", /* O !A*/ "V4", nullptr, "%V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, 565 // { "SampleCmpLevelZero", /*!O A*/ "V4", nullptr, "@V,S,V", "FIU,S,F", EShLangFragmentMask }, 566 // { "SampleCmpLevelZero", /* O A*/ "V4", nullptr, "@V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, 567 568 { "SampleGrad", /*!O !A*/ "V4", nullptr, "%V,S,V,V,V", "FIU,S,F,F,F", EShLangAll }, 569 { "SampleGrad", /* O !A*/ "V4", nullptr, "%V,S,V,V,V,V", "FIU,S,F,F,F,I", EShLangAll }, 570 { "SampleGrad", /*!O A*/ "V4", nullptr, "@V,S,V,V,V", "FIU,S,F,F,F", EShLangAll }, 571 { "SampleGrad", /* O A*/ "V4", nullptr, "@V,S,V,V,V,V", "FIU,S,F,F,F,I", EShLangAll }, 572 573 // { "SampleLevel", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 574 // { "SampleLevel", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 575 // { "SampleLevel", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask }, 576 // { "SampleLevel", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask }, 577 578 // TODO: ... 579 // { "Load", "V4", nullptr, "%V,V", "FIU,I", EShLangFragmentMask }, 580 // { "Load", /* +sampleidex*/ "V4", nullptr, "%V,V,S", "FIU,I,I", EShLangFragmentMask }, 581 // { "Load", /* +samplindex, offset*/ "V4", nullptr, "%V,V,S,V", "FIU,I,I,I", EShLangFragmentMask }, 582 // { "Load", "V4", nullptr, "@V,V", "FIU,I", EShLangFragmentMask }, 583 // { "Load", /* +sampleidex*/ "V4", nullptr, "@V,V,S", "FIU,I,I", EShLangFragmentMask }, 584 // { "Load", /* +samplindex, offset*/ "V4", nullptr, "@V,V,S,V", "FIU,I,I,I", EShLangFragmentMask }, 585 586 // table of overloads from: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509693(v=vs.85).aspx 587 // 588 // UINT Width 589 // UINT MipLevel, UINT Width, UINT NumberOfLevels 590 { "GetDimensions", /* 1D */ "-", "-", "%V1,>S", "FUI,U", EShLangAll }, 591 { "GetDimensions", /* 1D */ "-", "-", "%V1,>S", "FUI,F", EShLangAll }, 592 { "GetDimensions", /* 1D */ "-", "-", "%V1,S,>S,>S", "FUI,U,U,U", EShLangAll }, 593 { "GetDimensions", /* 1D */ "-", "-", "%V1,S,>S,>S", "FUI,U,F,F", EShLangAll }, 594 595 // UINT Width, UINT Elements 596 // UINT MipLevel, UINT Width, UINT Elements, UINT NumberOfLevels 597 { "GetDimensions", /* 1DArray */ "-", "-", "@V1,>S,>S", "FUI,U,U", EShLangAll }, 598 { "GetDimensions", /* 1DArray */ "-", "-", "@V1,>S,>S", "FUI,F,F", EShLangAll }, 599 { "GetDimensions", /* 1DArray */ "-", "-", "@V1,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll }, 600 { "GetDimensions", /* 1DArray */ "-", "-", "@V1,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll }, 601 602 // UINT Width, UINT Height 603 // UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels 604 { "GetDimensions", /* 2D */ "-", "-", "%V2,>S,>S", "FUI,U,U", EShLangAll }, 605 { "GetDimensions", /* 2D */ "-", "-", "%V2,>S,>S", "FUI,F,F", EShLangAll }, 606 { "GetDimensions", /* 2D */ "-", "-", "%V2,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll }, 607 { "GetDimensions", /* 2D */ "-", "-", "%V2,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll }, 608 609 // UINT Width, UINT Height, UINT Elements 610 // UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels 611 { "GetDimensions", /* 2DArray */ "-", "-", "@V2,>S,>S,>S", "FUI,U,U,U", EShLangAll }, 612 { "GetDimensions", /* 2DArray */ "-", "-", "@V2,>S,>S,>S", "FUI,F,F,F", EShLangAll }, 613 { "GetDimensions", /* 2DArray */ "-", "-", "@V2,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll }, 614 { "GetDimensions", /* 2DArray */ "-", "-", "@V2,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll }, 615 616 // UINT Width, UINT Height, UINT Depth 617 // UINT MipLevel, UINT Width, UINT Height, UINT Depth, UINT NumberOfLevels 618 { "GetDimensions", /* 3D */ "-", "-", "%V3,>S,>S,>S", "FUI,U,U,U", EShLangAll }, 619 { "GetDimensions", /* 3D */ "-", "-", "%V3,>S,>S,>S", "FUI,F,F,F", EShLangAll }, 620 { "GetDimensions", /* 3D */ "-", "-", "%V3,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll }, 621 { "GetDimensions", /* 3D */ "-", "-", "%V3,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll }, 622 623 // UINT Width, UINT Height 624 // UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels 625 { "GetDimensions", /* Cube */ "-", "-", "%V4,>S,>S", "FUI,U,U", EShLangAll }, 626 { "GetDimensions", /* Cube */ "-", "-", "%V4,>S,>S", "FUI,F,F", EShLangAll }, 627 { "GetDimensions", /* Cube */ "-", "-", "%V4,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll }, 628 { "GetDimensions", /* Cube */ "-", "-", "%V4,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll }, 629 630 // UINT Width, UINT Height, UINT Elements 631 // UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels 632 { "GetDimensions", /* CubeArray */ "-", "-", "@V4,>S,>S,>S", "FUI,U,U,U", EShLangAll }, 633 { "GetDimensions", /* CubeArray */ "-", "-", "@V4,>S,>S,>S", "FUI,F,F,F", EShLangAll }, 634 { "GetDimensions", /* CubeArray */ "-", "-", "@V4,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll }, 635 { "GetDimensions", /* CubeArray */ "-", "-", "@V4,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll }, 636 637 // TODO: GetDimensions for Texture2DMS, Texture2DMSArray 638 // UINT Width, UINT Height, UINT Samples 639 // UINT Width, UINT Height, UINT Elements, UINT Samples 640 641 // Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet. 642 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }, 643 }; 644 645 // Set this to true to avoid generating prototypes that will be invalid for the GLSL parser. 646 // TODO: turn it off (and remove the code) when the HLSL parser can be used to parse builtins. 647 static const bool skipInvalidGlsl = true; 648 649 // Create prototypes for the intrinsics. TODO: Avoid ranged based for until all compilers can handle it. 650 for (int icount = 0; hlslIntrinsics[icount].name; ++icount) { 651 const auto& intrinsic = hlslIntrinsics[icount]; 652 653 for (int stage = 0; stage < EShLangCount; ++stage) { // for each stage... 654 if ((intrinsic.stage & (1<<stage)) == 0) // skip inapplicable stages 655 continue; 656 657 // reference to either the common builtins, or stage specific builtins. 658 TString& s = (intrinsic.stage == EShLangAll) ? commonBuiltins : stageBuiltins[stage]; 659 660 for (const char* argOrder = intrinsic.argOrder; !IsEndOfArg(argOrder); ++argOrder) { // for each order... 661 const bool isTexture = IsTextureType(*argOrder); 662 const bool isArrayed = IsTextureArrayed(*argOrder); 663 const int fixedVecSize = FixedVecSize(argOrder); 664 665 // calculate min and max vector and matrix dimensions 666 int dim0Min = 1; 667 int dim0Max = 1; 668 int dim1Min = 1; 669 int dim1Max = 1; 670 671 FindVectorMatrixBounds(argOrder, fixedVecSize, dim0Min, dim0Max, dim1Min, dim1Max); 672 673 for (const char* argType = intrinsic.argType; !IsEndOfArg(argType); ++argType) { // for each type... 674 for (int dim0 = dim0Min; dim0 <= dim0Max; ++dim0) { // for each dim 0... 675 for (int dim1 = dim1Min; dim1 <= dim1Max; ++dim1) { // for each dim 1... 676 const char* retOrder = intrinsic.retOrder ? intrinsic.retOrder : argOrder; 677 const char* retType = intrinsic.retType ? intrinsic.retType : argType; 678 679 if (skipInvalidGlsl && !IsValidGlsl(intrinsic.name, *retOrder, *retType, *argOrder, *argType, 680 dim0, dim1, dim0Max, dim1Max)) 681 continue; 682 683 // Reject some forms of sample methods that don't exist. 684 if (isTexture && IsIllegalSample(intrinsic.name, argOrder, dim0)) 685 continue; 686 687 AppendTypeName(s, retOrder, retType, dim0, dim1); // add return type 688 s.append(" "); // space between type and name 689 s.append(intrinsic.name); // intrinsic name 690 s.append("("); // open paren 691 692 // Append argument types, if any. 693 for (int arg = 0; ; ++arg) { 694 const char* nthArgOrder(NthArg(argOrder, arg)); 695 const char* nthArgType(NthArg(argType, arg)); 696 697 if (nthArgOrder == nullptr || nthArgType == nullptr) 698 break; 699 700 // cube textures use vec3 coordinates 701 int argDim0 = isTexture && arg > 0 ? std::min(dim0, 3) : dim0; 702 703 // arrayed textures have one extra coordinate dimension 704 if (isArrayed && arg == 2) 705 argDim0++; 706 707 // For textures, the 1D case isn't a 1-vector, but a scalar. 708 if (isTexture && argDim0 == 1 && arg > 0 && *nthArgOrder == 'V') 709 nthArgOrder = "S"; 710 711 s.append(arg > 0 ? ", ": ""); // comma separator if needed 712 713 if (*nthArgOrder == '>') { // output params 714 ++nthArgOrder; 715 s.append("out "); 716 } else if (*nthArgOrder == '<') { // input params 717 ++nthArgOrder; 718 s.append("in "); 719 } 720 721 // Comma means use the 1st argument order and type. 722 if (*nthArgOrder == ',' || *nthArgOrder == '\0') nthArgOrder = argOrder; 723 if (*nthArgType == ',' || *nthArgType == '\0') nthArgType = argType; 724 725 AppendTypeName(s, nthArgOrder, nthArgType, argDim0, dim1); // Add arguments 726 } 727 728 s.append(");\n"); // close paren and trailing semicolon 729 } 730 } 731 } 732 733 // skip over special characters 734 if (isTexture) 735 ++argOrder; 736 if (isdigit(argOrder[1])) 737 ++argOrder; 738 } 739 740 if (intrinsic.stage == EShLangAll) // common builtins are only added once. 741 break; 742 } 743 } 744 745 createMatTimesMat(); // handle this case separately, for convenience 746 747 // printf("Common:\n%s\n", getCommonString().c_str()); 748 // printf("Frag:\n%s\n", getStageString(EShLangFragment).c_str()); 749 // printf("Vertex:\n%s\n", getStageString(EShLangVertex).c_str()); 750 // printf("Geo:\n%s\n", getStageString(EShLangGeometry).c_str()); 751 // printf("TessCtrl:\n%s\n", getStageString(EShLangTessControl).c_str()); 752 // printf("TessEval:\n%s\n", getStageString(EShLangTessEvaluation).c_str()); 753 // printf("Compute:\n%s\n", getStageString(EShLangCompute).c_str()); 754 } 755 756 // 757 // Add context-dependent built-in functions and variables that are present 758 // for the given version and profile. All the results are put into just the 759 // commonBuiltins, because it is called for just a specific stage. So, 760 // add stage-specific entries to the commonBuiltins, and only if that stage 761 // was requested. 762 // 763 void TBuiltInParseablesHlsl::initialize(const TBuiltInResource& /*resources*/, int /*version*/, EProfile /*profile*/, 764 const SpvVersion& /*spvVersion*/, EShLanguage /*language*/) 765 { 766 } 767 768 769 // 770 // Finish adding/processing context-independent built-in symbols. 771 // 1) Programmatically add symbols that could not be added by simple text strings above. 772 // 2) Map built-in functions to operators, for those that will turn into an operation node 773 // instead of remaining a function call. 774 // 3) Tag extension-related symbols added to their base version with their extensions, so 775 // that if an early version has the extension turned off, there is an error reported on use. 776 // 777 void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/, 778 TSymbolTable& symbolTable) 779 { 780 // symbolTable.relateToOperator("abort", EOpAbort); 781 symbolTable.relateToOperator("abs", EOpAbs); 782 symbolTable.relateToOperator("acos", EOpAcos); 783 symbolTable.relateToOperator("all", EOpAll); 784 symbolTable.relateToOperator("AllMemoryBarrier", EOpMemoryBarrier); 785 symbolTable.relateToOperator("AllMemoryBarrierWithGroupSync", EOpAllMemoryBarrierWithGroupSync); 786 symbolTable.relateToOperator("any", EOpAny); 787 symbolTable.relateToOperator("asdouble", EOpAsDouble); 788 symbolTable.relateToOperator("asfloat", EOpIntBitsToFloat); 789 symbolTable.relateToOperator("asin", EOpAsin); 790 symbolTable.relateToOperator("asint", EOpFloatBitsToInt); 791 symbolTable.relateToOperator("asuint", EOpFloatBitsToUint); 792 symbolTable.relateToOperator("atan", EOpAtan); 793 symbolTable.relateToOperator("atan2", EOpAtan); 794 symbolTable.relateToOperator("ceil", EOpCeil); 795 // symbolTable.relateToOperator("CheckAccessFullyMapped"); 796 symbolTable.relateToOperator("clamp", EOpClamp); 797 symbolTable.relateToOperator("clip", EOpClip); 798 symbolTable.relateToOperator("cos", EOpCos); 799 symbolTable.relateToOperator("cosh", EOpCosh); 800 symbolTable.relateToOperator("countbits", EOpBitCount); 801 symbolTable.relateToOperator("cross", EOpCross); 802 // symbolTable.relateToOperator("D3DCOLORtoUBYTE4", EOpD3DCOLORtoUBYTE4); 803 symbolTable.relateToOperator("ddx", EOpDPdx); 804 symbolTable.relateToOperator("ddx_coarse", EOpDPdxCoarse); 805 symbolTable.relateToOperator("ddx_fine", EOpDPdxFine); 806 symbolTable.relateToOperator("ddy", EOpDPdy); 807 symbolTable.relateToOperator("ddy_coarse", EOpDPdyCoarse); 808 symbolTable.relateToOperator("ddy_fine", EOpDPdyFine); 809 symbolTable.relateToOperator("degrees", EOpDegrees); 810 symbolTable.relateToOperator("determinant", EOpDeterminant); 811 symbolTable.relateToOperator("DeviceMemoryBarrier", EOpGroupMemoryBarrier); 812 symbolTable.relateToOperator("DeviceMemoryBarrierWithGroupSync", EOpGroupMemoryBarrierWithGroupSync); // ... 813 symbolTable.relateToOperator("distance", EOpDistance); 814 symbolTable.relateToOperator("dot", EOpDot); 815 symbolTable.relateToOperator("dst", EOpDst); 816 // symbolTable.relateToOperator("errorf", EOpErrorf); 817 symbolTable.relateToOperator("EvaluateAttributeAtCentroid", EOpInterpolateAtCentroid); 818 symbolTable.relateToOperator("EvaluateAttributeAtSample", EOpInterpolateAtSample); 819 symbolTable.relateToOperator("EvaluateAttributeSnapped", EOpEvaluateAttributeSnapped); 820 symbolTable.relateToOperator("exp", EOpExp); 821 symbolTable.relateToOperator("exp2", EOpExp2); 822 symbolTable.relateToOperator("f16tof32", EOpF16tof32); 823 symbolTable.relateToOperator("f32tof16", EOpF32tof16); 824 symbolTable.relateToOperator("faceforward", EOpFaceForward); 825 symbolTable.relateToOperator("firstbithigh", EOpFindMSB); 826 symbolTable.relateToOperator("firstbitlow", EOpFindLSB); 827 symbolTable.relateToOperator("floor", EOpFloor); 828 symbolTable.relateToOperator("fma", EOpFma); 829 symbolTable.relateToOperator("fmod", EOpMod); 830 symbolTable.relateToOperator("frac", EOpFract); 831 symbolTable.relateToOperator("frexp", EOpFrexp); 832 symbolTable.relateToOperator("fwidth", EOpFwidth); 833 // symbolTable.relateToOperator("GetRenderTargetSampleCount"); 834 // symbolTable.relateToOperator("GetRenderTargetSamplePosition"); 835 symbolTable.relateToOperator("GroupMemoryBarrier", EOpWorkgroupMemoryBarrier); 836 symbolTable.relateToOperator("GroupMemoryBarrierWithGroupSync", EOpWorkgroupMemoryBarrierWithGroupSync); 837 symbolTable.relateToOperator("InterlockedAdd", EOpInterlockedAdd); 838 symbolTable.relateToOperator("InterlockedAnd", EOpInterlockedAnd); 839 symbolTable.relateToOperator("InterlockedCompareExchange", EOpInterlockedCompareExchange); 840 symbolTable.relateToOperator("InterlockedCompareStore", EOpInterlockedCompareStore); 841 symbolTable.relateToOperator("InterlockedExchange", EOpInterlockedExchange); 842 symbolTable.relateToOperator("InterlockedMax", EOpInterlockedMax); 843 symbolTable.relateToOperator("InterlockedMin", EOpInterlockedMin); 844 symbolTable.relateToOperator("InterlockedOr", EOpInterlockedOr); 845 symbolTable.relateToOperator("InterlockedXor", EOpInterlockedXor); 846 symbolTable.relateToOperator("isfinite", EOpIsFinite); 847 symbolTable.relateToOperator("isinf", EOpIsInf); 848 symbolTable.relateToOperator("isnan", EOpIsNan); 849 symbolTable.relateToOperator("ldexp", EOpLdexp); 850 symbolTable.relateToOperator("length", EOpLength); 851 symbolTable.relateToOperator("lerp", EOpMix); 852 symbolTable.relateToOperator("lit", EOpLit); 853 symbolTable.relateToOperator("log", EOpLog); 854 symbolTable.relateToOperator("log10", EOpLog10); 855 symbolTable.relateToOperator("log2", EOpLog2); 856 symbolTable.relateToOperator("mad", EOpFma); 857 symbolTable.relateToOperator("max", EOpMax); 858 symbolTable.relateToOperator("min", EOpMin); 859 symbolTable.relateToOperator("modf", EOpModf); 860 // symbolTable.relateToOperator("msad4", EOpMsad4); 861 symbolTable.relateToOperator("mul", EOpGenMul); 862 // symbolTable.relateToOperator("noise", EOpNoise); // TODO: check return type 863 symbolTable.relateToOperator("normalize", EOpNormalize); 864 symbolTable.relateToOperator("pow", EOpPow); 865 // symbolTable.relateToOperator("printf", EOpPrintf); 866 // symbolTable.relateToOperator("Process2DQuadTessFactorsAvg"); 867 // symbolTable.relateToOperator("Process2DQuadTessFactorsMax"); 868 // symbolTable.relateToOperator("Process2DQuadTessFactorsMin"); 869 // symbolTable.relateToOperator("ProcessIsolineTessFactors"); 870 // symbolTable.relateToOperator("ProcessQuadTessFactorsAvg"); 871 // symbolTable.relateToOperator("ProcessQuadTessFactorsMax"); 872 // symbolTable.relateToOperator("ProcessQuadTessFactorsMin"); 873 // symbolTable.relateToOperator("ProcessTriTessFactorsAvg"); 874 // symbolTable.relateToOperator("ProcessTriTessFactorsMax"); 875 // symbolTable.relateToOperator("ProcessTriTessFactorsMin"); 876 symbolTable.relateToOperator("radians", EOpRadians); 877 symbolTable.relateToOperator("rcp", EOpRcp); 878 symbolTable.relateToOperator("reflect", EOpReflect); 879 symbolTable.relateToOperator("refract", EOpRefract); 880 symbolTable.relateToOperator("reversebits", EOpBitFieldReverse); 881 symbolTable.relateToOperator("round", EOpRoundEven); 882 symbolTable.relateToOperator("rsqrt", EOpInverseSqrt); 883 symbolTable.relateToOperator("saturate", EOpSaturate); 884 symbolTable.relateToOperator("sign", EOpSign); 885 symbolTable.relateToOperator("sin", EOpSin); 886 symbolTable.relateToOperator("sincos", EOpSinCos); 887 symbolTable.relateToOperator("sinh", EOpSinh); 888 symbolTable.relateToOperator("smoothstep", EOpSmoothStep); 889 symbolTable.relateToOperator("sqrt", EOpSqrt); 890 symbolTable.relateToOperator("step", EOpStep); 891 symbolTable.relateToOperator("tan", EOpTan); 892 symbolTable.relateToOperator("tanh", EOpTanh); 893 symbolTable.relateToOperator("tex1D", EOpTexture); 894 symbolTable.relateToOperator("tex1Dbias", EOpTextureBias); 895 symbolTable.relateToOperator("tex1Dgrad", EOpTextureGrad); 896 symbolTable.relateToOperator("tex1Dlod", EOpTextureLod); 897 symbolTable.relateToOperator("tex1Dproj", EOpTextureProj); 898 symbolTable.relateToOperator("tex2D", EOpTexture); 899 symbolTable.relateToOperator("tex2Dbias", EOpTextureBias); 900 symbolTable.relateToOperator("tex2Dgrad", EOpTextureGrad); 901 symbolTable.relateToOperator("tex2Dlod", EOpTextureLod); 902 symbolTable.relateToOperator("tex2Dproj", EOpTextureProj); 903 symbolTable.relateToOperator("tex3D", EOpTexture); 904 symbolTable.relateToOperator("tex3Dbias", EOpTextureBias); 905 symbolTable.relateToOperator("tex3Dgrad", EOpTextureGrad); 906 symbolTable.relateToOperator("tex3Dlod", EOpTextureLod); 907 symbolTable.relateToOperator("tex3Dproj", EOpTextureProj); 908 symbolTable.relateToOperator("texCUBE", EOpTexture); 909 symbolTable.relateToOperator("texCUBEbias", EOpTextureBias); 910 symbolTable.relateToOperator("texCUBEgrad", EOpTextureGrad); 911 symbolTable.relateToOperator("texCUBElod", EOpTextureLod); 912 symbolTable.relateToOperator("texCUBEproj", EOpTextureProj); 913 symbolTable.relateToOperator("transpose", EOpTranspose); 914 symbolTable.relateToOperator("trunc", EOpTrunc); 915 916 // Texture methods 917 symbolTable.relateToOperator("Sample", EOpMethodSample); 918 symbolTable.relateToOperator("SampleBias", EOpMethodSampleBias); 919 // symbolTable.relateToOperator("SampleCmp", EOpMethodSampleCmp); 920 // symbolTable.relateToOperator("SampleCmpLevelZero", EOpMethodSampleCmpLevelZero); 921 symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad); 922 // symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel); 923 // symbolTable.relateToOperator("Load", EOpMethodLoad); 924 symbolTable.relateToOperator("GetDimensions", EOpMethodGetDimensions); 925 } 926 927 // 928 // Add context-dependent (resource-specific) built-ins not handled by the above. These 929 // would be ones that need to be programmatically added because they cannot 930 // be added by simple text strings. For these, also 931 // 1) Map built-in functions to operators, for those that will turn into an operation node 932 // instead of remaining a function call. 933 // 2) Tag extension-related symbols added to their base version with their extensions, so 934 // that if an early version has the extension turned off, there is an error reported on use. 935 // 936 void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/, 937 TSymbolTable& /*symbolTable*/, const TBuiltInResource& /*resources*/) 938 { 939 } 940 941 942 } // end namespace glslang 943