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