hlslParseables.cpp 87 KB

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