DeclResultIdMapper.cpp 144 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734
  1. //===--- DeclResultIdMapper.cpp - DeclResultIdMapper impl --------*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "DeclResultIdMapper.h"
  10. #include <sstream>
  11. #include "dxc/DXIL/DxilConstants.h"
  12. #include "dxc/DXIL/DxilTypeSystem.h"
  13. #include "clang/AST/Expr.h"
  14. #include "clang/AST/HlslTypes.h"
  15. #include "clang/SPIRV/AstTypeProbe.h"
  16. #include "llvm/ADT/SmallBitVector.h"
  17. #include "llvm/ADT/StringMap.h"
  18. #include "llvm/ADT/StringSet.h"
  19. #include "llvm/Support/Casting.h"
  20. #include "AlignmentSizeCalculator.h"
  21. #include "SpirvEmitter.h"
  22. namespace clang {
  23. namespace spirv {
  24. namespace {
  25. uint32_t getVkBindingAttrSet(const VKBindingAttr *attr, uint32_t defaultSet) {
  26. // If the [[vk::binding(x)]] attribute is provided without the descriptor set,
  27. // we should use the default descriptor set.
  28. if (attr->getSet() == INT_MIN) {
  29. return defaultSet;
  30. }
  31. return attr->getSet();
  32. }
  33. /// Returns the :packoffset() annotation on the given decl. Returns nullptr if
  34. /// the decl does not have one.
  35. hlsl::ConstantPacking *getPackOffset(const clang::NamedDecl *decl) {
  36. for (auto *annotation : decl->getUnusualAnnotations())
  37. if (auto *packing = llvm::dyn_cast<hlsl::ConstantPacking>(annotation))
  38. return packing;
  39. return nullptr;
  40. }
  41. /// Returns the number of binding numbers that are used up by the given type.
  42. /// An array of size N consumes N*M binding numbers where M is the number of
  43. /// binding numbers used by each array element.
  44. /// The number of binding numbers used by a structure is the sum of binding
  45. /// numbers used by its members.
  46. uint32_t getNumBindingsUsedByResourceType(QualType type) {
  47. // For custom-generated types that have SpirvType but no QualType.
  48. if (type.isNull())
  49. return 1;
  50. // For every array dimension, the number of bindings needed should be
  51. // multiplied by the array size. For example: an array of two Textures should
  52. // use 2 binding slots.
  53. uint32_t arrayFactor = 1;
  54. while (auto constArrayType = dyn_cast<ConstantArrayType>(type)) {
  55. arrayFactor *=
  56. static_cast<uint32_t>(constArrayType->getSize().getZExtValue());
  57. type = constArrayType->getElementType();
  58. }
  59. // Once we remove the arrayness, we expect the given type to be either a
  60. // resource OR a structure that only contains resources.
  61. assert(isResourceType(type) || isResourceOnlyStructure(type));
  62. // In the case of a resource, each resource takes 1 binding slot, so in total
  63. // it consumes: 1 * arrayFactor.
  64. if (isResourceType(type))
  65. return arrayFactor;
  66. // In the case of a struct of resources, we need to sum up the number of
  67. // bindings for the struct members. So in total it consumes:
  68. // sum(bindings of struct members) * arrayFactor.
  69. if (isResourceOnlyStructure(type)) {
  70. uint32_t sumOfMemberBindings = 0;
  71. const auto *structDecl = type->getAs<RecordType>()->getDecl();
  72. assert(structDecl);
  73. for (const auto *field : structDecl->fields())
  74. sumOfMemberBindings += getNumBindingsUsedByResourceType(field->getType());
  75. return sumOfMemberBindings * arrayFactor;
  76. }
  77. llvm_unreachable(
  78. "getNumBindingsUsedByResourceType was called with unknown resource type");
  79. }
  80. QualType getUintTypeWithSourceComponents(const ASTContext &astContext,
  81. QualType sourceType) {
  82. if (isScalarType(sourceType)) {
  83. return astContext.UnsignedIntTy;
  84. }
  85. uint32_t elemCount = 0;
  86. if (isVectorType(sourceType, nullptr, &elemCount)) {
  87. return astContext.getExtVectorType(astContext.UnsignedIntTy, elemCount);
  88. }
  89. llvm_unreachable("only scalar and vector types are supported in "
  90. "getUintTypeWithSourceComponents");
  91. }
  92. uint32_t getLocationCount(const ASTContext &astContext, QualType type) {
  93. // See Vulkan spec 14.1.4. Location Assignment for the complete set of rules.
  94. const auto canonicalType = type.getCanonicalType();
  95. if (canonicalType != type)
  96. return getLocationCount(astContext, canonicalType);
  97. // Inputs and outputs of the following types consume a single interface
  98. // location:
  99. // * 16-bit scalar and vector types, and
  100. // * 32-bit scalar and vector types, and
  101. // * 64-bit scalar and 2-component vector types.
  102. // 64-bit three- and four- component vectors consume two consecutive
  103. // locations.
  104. // Primitive types
  105. if (isScalarType(type))
  106. return 1;
  107. // Vector types
  108. {
  109. QualType elemType = {};
  110. uint32_t elemCount = {};
  111. if (isVectorType(type, &elemType, &elemCount)) {
  112. const auto *builtinType = elemType->getAs<BuiltinType>();
  113. switch (builtinType->getKind()) {
  114. case BuiltinType::Double:
  115. case BuiltinType::LongLong:
  116. case BuiltinType::ULongLong:
  117. if (elemCount >= 3)
  118. return 2;
  119. default:
  120. // Filter switch only interested in types occupying 2 locations.
  121. break;
  122. }
  123. return 1;
  124. }
  125. }
  126. // If the declared input or output is an n * m 16- , 32- or 64- bit matrix,
  127. // it will be assigned multiple locations starting with the location
  128. // specified. The number of locations assigned for each matrix will be the
  129. // same as for an n-element array of m-component vectors.
  130. // Matrix types
  131. {
  132. QualType elemType = {};
  133. uint32_t rowCount = 0, colCount = 0;
  134. if (isMxNMatrix(type, &elemType, &rowCount, &colCount))
  135. return getLocationCount(astContext,
  136. astContext.getExtVectorType(elemType, colCount)) *
  137. rowCount;
  138. }
  139. // Typedefs
  140. if (const auto *typedefType = type->getAs<TypedefType>())
  141. return getLocationCount(astContext, typedefType->desugar());
  142. // Reference types
  143. if (const auto *refType = type->getAs<ReferenceType>())
  144. return getLocationCount(astContext, refType->getPointeeType());
  145. // Pointer types
  146. if (const auto *ptrType = type->getAs<PointerType>())
  147. return getLocationCount(astContext, ptrType->getPointeeType());
  148. // If a declared input or output is an array of size n and each element takes
  149. // m locations, it will be assigned m * n consecutive locations starting with
  150. // the location specified.
  151. // Array types
  152. if (const auto *arrayType = astContext.getAsConstantArrayType(type))
  153. return getLocationCount(astContext, arrayType->getElementType()) *
  154. static_cast<uint32_t>(arrayType->getSize().getZExtValue());
  155. // Struct type
  156. if (type->getAs<RecordType>()) {
  157. assert(false && "all structs should already be flattened");
  158. return 0;
  159. }
  160. llvm_unreachable(
  161. "calculating number of occupied locations for type unimplemented");
  162. return 0;
  163. }
  164. bool shouldSkipInStructLayout(const Decl *decl) {
  165. // Ignore implicit generated struct declarations/constructors/destructors
  166. if (decl->isImplicit())
  167. return true;
  168. // Ignore embedded type decls
  169. if (isa<TypeDecl>(decl))
  170. return true;
  171. // Ignore embeded function decls
  172. if (isa<FunctionDecl>(decl))
  173. return true;
  174. // Ignore empty decls
  175. if (isa<EmptyDecl>(decl))
  176. return true;
  177. // For the $Globals cbuffer, we only care about externally-visible
  178. // non-resource-type variables. The rest should be filtered out.
  179. const auto *declContext = decl->getDeclContext();
  180. // $Globals' "struct" is the TranslationUnit, so we should ignore resources
  181. // in the TranslationUnit "struct" and its child namespaces.
  182. if (declContext->isTranslationUnit() || declContext->isNamespace()) {
  183. // External visibility
  184. if (const auto *declDecl = dyn_cast<DeclaratorDecl>(decl))
  185. if (!declDecl->hasExternalFormalLinkage())
  186. return true;
  187. // cbuffer/tbuffer
  188. if (isa<HLSLBufferDecl>(decl))
  189. return true;
  190. // 'groupshared' variables should not be placed in $Globals cbuffer.
  191. if (decl->hasAttr<HLSLGroupSharedAttr>())
  192. return true;
  193. // Other resource types
  194. if (const auto *valueDecl = dyn_cast<ValueDecl>(decl)) {
  195. const auto declType = valueDecl->getType();
  196. if (isResourceType(declType) || isResourceOnlyStructure(declType))
  197. return true;
  198. }
  199. }
  200. return false;
  201. }
  202. void collectDeclsInField(const Decl *field,
  203. llvm::SmallVector<const Decl *, 4> *decls) {
  204. // Case of nested namespaces.
  205. if (const auto *nsDecl = dyn_cast<NamespaceDecl>(field)) {
  206. for (const auto *decl : nsDecl->decls()) {
  207. collectDeclsInField(decl, decls);
  208. }
  209. }
  210. if (shouldSkipInStructLayout(field))
  211. return;
  212. if (!isa<DeclaratorDecl>(field)) {
  213. return;
  214. }
  215. decls->push_back(field);
  216. }
  217. llvm::SmallVector<const Decl *, 4>
  218. collectDeclsInDeclContext(const DeclContext *declContext) {
  219. llvm::SmallVector<const Decl *, 4> decls;
  220. for (const auto *field : declContext->decls()) {
  221. collectDeclsInField(field, &decls);
  222. }
  223. return decls;
  224. }
  225. /// \brief Returns true if the given decl is a boolean stage I/O variable.
  226. /// Returns false if the type is not boolean, or the decl is a built-in stage
  227. /// variable.
  228. bool isBooleanStageIOVar(const NamedDecl *decl, QualType type,
  229. const hlsl::DXIL::SemanticKind semanticKind,
  230. const hlsl::SigPoint::Kind sigPointKind) {
  231. // [[vk::builtin(...)]] makes the decl a built-in stage variable.
  232. // IsFrontFace (if used as PSIn) is the only known boolean built-in stage
  233. // variable.
  234. const bool isBooleanBuiltin =
  235. (decl->getAttr<VKBuiltInAttr>() != nullptr) ||
  236. (semanticKind == hlsl::Semantic::Kind::IsFrontFace &&
  237. sigPointKind == hlsl::SigPoint::Kind::PSIn);
  238. // TODO: support boolean matrix stage I/O variable if needed.
  239. QualType elemType = {};
  240. const bool isBooleanType =
  241. ((isScalarType(type, &elemType) || isVectorType(type, &elemType)) &&
  242. elemType->isBooleanType());
  243. return isBooleanType && !isBooleanBuiltin;
  244. }
  245. /// \brief Returns the stage variable's register assignment for the given Decl.
  246. const hlsl::RegisterAssignment *getResourceBinding(const NamedDecl *decl) {
  247. for (auto *annotation : decl->getUnusualAnnotations()) {
  248. if (auto *reg = dyn_cast<hlsl::RegisterAssignment>(annotation)) {
  249. return reg;
  250. }
  251. }
  252. return nullptr;
  253. }
  254. /// \brief Returns the stage variable's 'register(c#) assignment for the given
  255. /// Decl. Return nullptr if the given variable does not have such assignment.
  256. const hlsl::RegisterAssignment *getRegisterCAssignment(const NamedDecl *decl) {
  257. const auto *regAssignment = getResourceBinding(decl);
  258. if (regAssignment)
  259. return regAssignment->RegisterType == 'c' ? regAssignment : nullptr;
  260. return nullptr;
  261. }
  262. /// \brief Returns true if the given declaration has a primitive type qualifier.
  263. /// Returns false otherwise.
  264. inline bool hasGSPrimitiveTypeQualifier(const Decl *decl) {
  265. return decl->hasAttr<HLSLTriangleAttr>() ||
  266. decl->hasAttr<HLSLTriangleAdjAttr>() ||
  267. decl->hasAttr<HLSLPointAttr>() || decl->hasAttr<HLSLLineAttr>() ||
  268. decl->hasAttr<HLSLLineAdjAttr>();
  269. }
  270. /// \brief Deduces the parameter qualifier for the given decl.
  271. hlsl::DxilParamInputQual deduceParamQual(const DeclaratorDecl *decl,
  272. bool asInput) {
  273. const auto type = decl->getType();
  274. if (hlsl::IsHLSLInputPatchType(type))
  275. return hlsl::DxilParamInputQual::InputPatch;
  276. if (hlsl::IsHLSLOutputPatchType(type))
  277. return hlsl::DxilParamInputQual::OutputPatch;
  278. // TODO: Add support for multiple output streams.
  279. if (hlsl::IsHLSLStreamOutputType(type))
  280. return hlsl::DxilParamInputQual::OutStream0;
  281. // The inputs to the geometry shader that have a primitive type qualifier
  282. // must use 'InputPrimitive'.
  283. if (hasGSPrimitiveTypeQualifier(decl))
  284. return hlsl::DxilParamInputQual::InputPrimitive;
  285. if (decl->hasAttr<HLSLIndicesAttr>())
  286. return hlsl::DxilParamInputQual::OutIndices;
  287. if (decl->hasAttr<HLSLVerticesAttr>())
  288. return hlsl::DxilParamInputQual::OutVertices;
  289. if (decl->hasAttr<HLSLPrimitivesAttr>())
  290. return hlsl::DxilParamInputQual::OutPrimitives;
  291. if (decl->hasAttr<HLSLPayloadAttr>())
  292. return hlsl::DxilParamInputQual::InPayload;
  293. return asInput ? hlsl::DxilParamInputQual::In : hlsl::DxilParamInputQual::Out;
  294. }
  295. /// \brief Deduces the HLSL SigPoint for the given decl appearing in the given
  296. /// shader model.
  297. const hlsl::SigPoint *deduceSigPoint(const DeclaratorDecl *decl, bool asInput,
  298. const hlsl::ShaderModel::Kind kind,
  299. bool forPCF) {
  300. return hlsl::SigPoint::GetSigPoint(hlsl::SigPointFromInputQual(
  301. deduceParamQual(decl, asInput), kind, forPCF));
  302. }
  303. /// Returns the type of the given decl. If the given decl is a FunctionDecl,
  304. /// returns its result type.
  305. inline QualType getTypeOrFnRetType(const DeclaratorDecl *decl) {
  306. if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
  307. return funcDecl->getReturnType();
  308. }
  309. return decl->getType();
  310. }
  311. /// Returns the number of base classes if this type is a derived class/struct.
  312. /// Returns zero otherwise.
  313. inline uint32_t getNumBaseClasses(QualType type) {
  314. if (const auto *cxxDecl = type->getAsCXXRecordDecl())
  315. return cxxDecl->getNumBases();
  316. return 0;
  317. }
  318. /// Returns the appropriate storage class for an extern variable of the given
  319. /// type.
  320. spv::StorageClass getStorageClassForExternVar(QualType type,
  321. bool hasGroupsharedAttr) {
  322. // For CS groupshared variables
  323. if (hasGroupsharedAttr)
  324. return spv::StorageClass::Workgroup;
  325. if (isAKindOfStructuredOrByteBuffer(type))
  326. return spv::StorageClass::Uniform;
  327. return spv::StorageClass::UniformConstant;
  328. }
  329. /// Returns the appropriate layout rule for an extern variable of the given
  330. /// type.
  331. SpirvLayoutRule getLayoutRuleForExternVar(QualType type,
  332. const SpirvCodeGenOptions &opts) {
  333. if (isAKindOfStructuredOrByteBuffer(type))
  334. return opts.sBufferLayoutRule;
  335. return SpirvLayoutRule::Void;
  336. }
  337. } // anonymous namespace
  338. std::string StageVar::getSemanticStr() const {
  339. // A special case for zero index, which is equivalent to no index.
  340. // Use what is in the source code.
  341. // TODO: this looks like a hack to make the current tests happy.
  342. // Should consider remove it and fix all tests.
  343. if (semanticInfo.index == 0)
  344. return semanticInfo.str;
  345. std::ostringstream ss;
  346. ss << semanticInfo.name.str() << semanticInfo.index;
  347. return ss.str();
  348. }
  349. SpirvInstruction *CounterIdAliasPair::get(SpirvBuilder &builder,
  350. SpirvContext &spvContext) const {
  351. if (isAlias) {
  352. const auto *counterType = spvContext.getACSBufferCounterType();
  353. const auto *counterVarType =
  354. spvContext.getPointerType(counterType, spv::StorageClass::Uniform);
  355. return builder.createLoad(counterVarType, counterVar,
  356. /* SourceLocation */ {});
  357. }
  358. return counterVar;
  359. }
  360. const CounterIdAliasPair *
  361. CounterVarFields::get(const llvm::SmallVectorImpl<uint32_t> &indices) const {
  362. for (const auto &field : fields)
  363. if (field.indices == indices)
  364. return &field.counterVar;
  365. return nullptr;
  366. }
  367. bool CounterVarFields::assign(const CounterVarFields &srcFields,
  368. SpirvBuilder &builder,
  369. SpirvContext &context) const {
  370. for (const auto &field : fields) {
  371. const auto *srcField = srcFields.get(field.indices);
  372. if (!srcField)
  373. return false;
  374. field.counterVar.assign(*srcField, builder, context);
  375. }
  376. return true;
  377. }
  378. bool CounterVarFields::assign(const CounterVarFields &srcFields,
  379. const llvm::SmallVector<uint32_t, 4> &dstPrefix,
  380. const llvm::SmallVector<uint32_t, 4> &srcPrefix,
  381. SpirvBuilder &builder,
  382. SpirvContext &context) const {
  383. if (dstPrefix.empty() && srcPrefix.empty())
  384. return assign(srcFields, builder, context);
  385. llvm::SmallVector<uint32_t, 4> srcIndices = srcPrefix;
  386. // If whole has the given prefix, appends all elements after the prefix in
  387. // whole to srcIndices.
  388. const auto applyDiff =
  389. [&srcIndices](const llvm::SmallVector<uint32_t, 4> &whole,
  390. const llvm::SmallVector<uint32_t, 4> &prefix) -> bool {
  391. uint32_t i = 0;
  392. for (; i < prefix.size(); ++i)
  393. if (whole[i] != prefix[i]) {
  394. break;
  395. }
  396. if (i == prefix.size()) {
  397. for (; i < whole.size(); ++i)
  398. srcIndices.push_back(whole[i]);
  399. return true;
  400. }
  401. return false;
  402. };
  403. for (const auto &field : fields)
  404. if (applyDiff(field.indices, dstPrefix)) {
  405. const auto *srcField = srcFields.get(srcIndices);
  406. if (!srcField)
  407. return false;
  408. field.counterVar.assign(*srcField, builder, context);
  409. for (uint32_t i = srcPrefix.size(); i < srcIndices.size(); ++i)
  410. srcIndices.pop_back();
  411. }
  412. return true;
  413. }
  414. SemanticInfo DeclResultIdMapper::getStageVarSemantic(const NamedDecl *decl) {
  415. for (auto *annotation : decl->getUnusualAnnotations()) {
  416. if (auto *sema = dyn_cast<hlsl::SemanticDecl>(annotation)) {
  417. llvm::StringRef semanticStr = sema->SemanticName;
  418. llvm::StringRef semanticName;
  419. uint32_t index = 0;
  420. hlsl::Semantic::DecomposeNameAndIndex(semanticStr, &semanticName, &index);
  421. const auto *semantic = hlsl::Semantic::GetByName(semanticName);
  422. return {semanticStr, semantic, semanticName, index, sema->Loc};
  423. }
  424. }
  425. return {};
  426. }
  427. bool DeclResultIdMapper::createStageOutputVar(const DeclaratorDecl *decl,
  428. SpirvInstruction *storedValue,
  429. bool forPCF) {
  430. QualType type = getTypeOrFnRetType(decl);
  431. uint32_t arraySize = 0;
  432. // Output stream types (PointStream, LineStream, TriangleStream) are
  433. // translated as their underlying struct types.
  434. if (hlsl::IsHLSLStreamOutputType(type))
  435. type = hlsl::GetHLSLResourceResultType(type);
  436. if (decl->hasAttr<HLSLIndicesAttr>() || decl->hasAttr<HLSLVerticesAttr>() ||
  437. decl->hasAttr<HLSLPrimitivesAttr>()) {
  438. const auto *typeDecl = astContext.getAsConstantArrayType(type);
  439. type = typeDecl->getElementType();
  440. arraySize = static_cast<uint32_t>(typeDecl->getSize().getZExtValue());
  441. if (decl->hasAttr<HLSLIndicesAttr>()) {
  442. // create SPIR-V builtin array PrimitiveIndicesNV of type
  443. // "uint [MaxPrimitiveCount * verticesPerPrim]"
  444. uint32_t verticesPerPrim = 1;
  445. if (!isVectorType(type, nullptr, &verticesPerPrim)) {
  446. assert(isScalarType(type));
  447. }
  448. arraySize = arraySize * verticesPerPrim;
  449. QualType arrayType = astContext.getConstantArrayType(
  450. astContext.UnsignedIntTy, llvm::APInt(32, arraySize),
  451. clang::ArrayType::Normal, 0);
  452. stageVarInstructions[cast<DeclaratorDecl>(decl)] = getBuiltinVar(
  453. spv::BuiltIn::PrimitiveIndicesNV, arrayType, decl->getLocation());
  454. return true;
  455. }
  456. }
  457. const auto *sigPoint = deduceSigPoint(
  458. decl, /*asInput=*/false, spvContext.getCurrentShaderModelKind(), forPCF);
  459. // HS output variables are created using the other overload. For the rest,
  460. // none of them should be created as arrays.
  461. assert(sigPoint->GetKind() != hlsl::DXIL::SigPointKind::HSCPOut);
  462. SemanticInfo inheritSemantic = {};
  463. // If storedValue is 0, it means this parameter in the original source code is
  464. // not used at all. Avoid writing back.
  465. //
  466. // Write back of stage output variables in GS is manually controlled by
  467. // .Append() intrinsic method, implemented in writeBackOutputStream(). So
  468. // ignoreValue should be set to true for GS.
  469. const bool noWriteBack =
  470. storedValue == nullptr || spvContext.isGS() || spvContext.isMS();
  471. return createStageVars(sigPoint, decl, /*asInput=*/false, type, arraySize,
  472. "out.var", llvm::None, &storedValue, noWriteBack,
  473. &inheritSemantic);
  474. }
  475. bool DeclResultIdMapper::createStageOutputVar(const DeclaratorDecl *decl,
  476. uint32_t arraySize,
  477. SpirvInstruction *invocationId,
  478. SpirvInstruction *storedValue) {
  479. assert(spvContext.isHS());
  480. QualType type = getTypeOrFnRetType(decl);
  481. const auto *sigPoint =
  482. hlsl::SigPoint::GetSigPoint(hlsl::DXIL::SigPointKind::HSCPOut);
  483. SemanticInfo inheritSemantic = {};
  484. return createStageVars(sigPoint, decl, /*asInput=*/false, type, arraySize,
  485. "out.var", invocationId, &storedValue,
  486. /*noWriteBack=*/false, &inheritSemantic);
  487. }
  488. bool DeclResultIdMapper::createStageInputVar(const ParmVarDecl *paramDecl,
  489. SpirvInstruction **loadedValue,
  490. bool forPCF) {
  491. uint32_t arraySize = 0;
  492. QualType type = paramDecl->getType();
  493. // Deprive the outermost arrayness for HS/DS/GS and use arraySize
  494. // to convey that information
  495. if (hlsl::IsHLSLInputPatchType(type)) {
  496. arraySize = hlsl::GetHLSLInputPatchCount(type);
  497. type = hlsl::GetHLSLInputPatchElementType(type);
  498. } else if (hlsl::IsHLSLOutputPatchType(type)) {
  499. arraySize = hlsl::GetHLSLOutputPatchCount(type);
  500. type = hlsl::GetHLSLOutputPatchElementType(type);
  501. }
  502. if (hasGSPrimitiveTypeQualifier(paramDecl)) {
  503. const auto *typeDecl = astContext.getAsConstantArrayType(type);
  504. arraySize = static_cast<uint32_t>(typeDecl->getSize().getZExtValue());
  505. type = typeDecl->getElementType();
  506. }
  507. const auto *sigPoint =
  508. deduceSigPoint(paramDecl, /*asInput=*/true,
  509. spvContext.getCurrentShaderModelKind(), forPCF);
  510. SemanticInfo inheritSemantic = {};
  511. if (paramDecl->hasAttr<HLSLPayloadAttr>()) {
  512. spv::StorageClass sc = getStorageClassForSigPoint(sigPoint);
  513. return createPayloadStageVars(sigPoint, sc, paramDecl, /*asInput=*/true,
  514. type, "in.var", loadedValue);
  515. } else {
  516. return createStageVars(sigPoint, paramDecl, /*asInput=*/true, type,
  517. arraySize, "in.var", llvm::None, loadedValue,
  518. /*noWriteBack=*/false, &inheritSemantic);
  519. }
  520. }
  521. const DeclResultIdMapper::DeclSpirvInfo *
  522. DeclResultIdMapper::getDeclSpirvInfo(const ValueDecl *decl) const {
  523. auto it = astDecls.find(decl);
  524. if (it != astDecls.end())
  525. return &it->second;
  526. return nullptr;
  527. }
  528. SpirvInstruction *DeclResultIdMapper::getDeclEvalInfo(const ValueDecl *decl,
  529. SourceLocation loc) {
  530. const DeclSpirvInfo *info = getDeclSpirvInfo(decl);
  531. // If DeclSpirvInfo is not found for this decl, it might be because it is an
  532. // implicit VarDecl. All implicit VarDecls are lazily created in order to
  533. // avoid creating large number of unused variables/constants/enums.
  534. if (!info) {
  535. tryToCreateImplicitConstVar(decl);
  536. info = getDeclSpirvInfo(decl);
  537. }
  538. if (info) {
  539. if (info->indexInCTBuffer >= 0) {
  540. // If this is a VarDecl inside a HLSLBufferDecl, we need to do an extra
  541. // OpAccessChain to get the pointer to the variable since we created
  542. // a single variable for the whole buffer object.
  543. // Should only have VarDecls in a HLSLBufferDecl.
  544. QualType valueType = cast<VarDecl>(decl)->getType();
  545. return spvBuilder.createAccessChain(
  546. valueType, info->instr,
  547. {spvBuilder.getConstantInt(
  548. astContext.IntTy, llvm::APInt(32, info->indexInCTBuffer, true))},
  549. loc);
  550. } else if (auto *type = info->instr->getResultType()) {
  551. const auto *ptrTy = dyn_cast<HybridPointerType>(type);
  552. // If it is a local variable or function parameter with a bindless
  553. // array of an opaque type, we have to load it because we pass a
  554. // pointer of a global variable that has the bindless opaque array.
  555. if (ptrTy != nullptr && isBindlessOpaqueArray(decl->getType())) {
  556. auto *load = spvBuilder.createLoad(ptrTy, info->instr, loc);
  557. load->setRValue(false);
  558. return load;
  559. } else {
  560. return *info;
  561. }
  562. } else {
  563. return *info;
  564. }
  565. }
  566. emitFatalError("found unregistered decl", decl->getLocation())
  567. << decl->getName();
  568. emitNote("please file a bug report on "
  569. "https://github.com/Microsoft/DirectXShaderCompiler/issues with "
  570. "source code if possible",
  571. {});
  572. return 0;
  573. }
  574. SpirvFunctionParameter *
  575. DeclResultIdMapper::createFnParam(const ParmVarDecl *param,
  576. uint32_t dbgArgNumber) {
  577. const auto type = getTypeOrFnRetType(param);
  578. const auto loc = param->getLocation();
  579. const auto name = param->getName();
  580. SpirvFunctionParameter *fnParamInstr = spvBuilder.addFnParam(
  581. type, param->hasAttr<HLSLPreciseAttr>(), loc, param->getName());
  582. bool isAlias = false;
  583. (void)getTypeAndCreateCounterForPotentialAliasVar(param, &isAlias);
  584. fnParamInstr->setContainsAliasComponent(isAlias);
  585. assert(astDecls[param].instr == nullptr);
  586. astDecls[param].instr = fnParamInstr;
  587. if (spirvOptions.debugInfoRich) {
  588. // Add DebugLocalVariable information
  589. const auto &sm = astContext.getSourceManager();
  590. const uint32_t line = sm.getPresumedLineNumber(loc);
  591. const uint32_t column = sm.getPresumedColumnNumber(loc);
  592. const auto *info = theEmitter.getOrCreateRichDebugInfo(loc);
  593. // TODO: replace this with FlagIsLocal enum.
  594. uint32_t flags = 1 << 2;
  595. auto *debugLocalVar = spvBuilder.createDebugLocalVariable(
  596. type, name, info->source, line, column, info->scopeStack.back(), flags,
  597. dbgArgNumber);
  598. spvBuilder.createDebugDeclare(debugLocalVar, fnParamInstr);
  599. }
  600. return fnParamInstr;
  601. }
  602. void DeclResultIdMapper::createCounterVarForDecl(const DeclaratorDecl *decl) {
  603. const QualType declType = getTypeOrFnRetType(decl);
  604. if (!counterVars.count(decl) && isRWAppendConsumeSBuffer(declType)) {
  605. createCounterVar(decl, /*declId=*/0, /*isAlias=*/true);
  606. } else if (!fieldCounterVars.count(decl) && declType->isStructureType() &&
  607. // Exclude other resource types which are represented as structs
  608. !hlsl::IsHLSLResourceType(declType)) {
  609. createFieldCounterVars(decl);
  610. }
  611. }
  612. SpirvVariable *
  613. DeclResultIdMapper::createFnVar(const VarDecl *var,
  614. llvm::Optional<SpirvInstruction *> init) {
  615. const auto type = getTypeOrFnRetType(var);
  616. const auto loc = var->getLocation();
  617. const auto name = var->getName();
  618. const bool isPrecise = var->hasAttr<HLSLPreciseAttr>();
  619. SpirvVariable *varInstr = spvBuilder.addFnVar(
  620. type, loc, name, isPrecise, init.hasValue() ? init.getValue() : nullptr);
  621. bool isAlias = false;
  622. (void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias);
  623. varInstr->setContainsAliasComponent(isAlias);
  624. assert(astDecls[var].instr == nullptr);
  625. astDecls[var].instr = varInstr;
  626. return varInstr;
  627. }
  628. SpirvDebugGlobalVariable *DeclResultIdMapper::createDebugGlobalVariable(
  629. SpirvVariable *var, const QualType &type, const SourceLocation &loc,
  630. const StringRef &name) {
  631. if (spirvOptions.debugInfoRich) {
  632. // Add DebugGlobalVariable information
  633. const auto &sm = astContext.getSourceManager();
  634. const uint32_t line = sm.getPresumedLineNumber(loc);
  635. const uint32_t column = sm.getPresumedColumnNumber(loc);
  636. const auto *info = theEmitter.getOrCreateRichDebugInfo(loc);
  637. // TODO: replace this with FlagIsDefinition enum.
  638. uint32_t flags = 1 << 3;
  639. // TODO: update linkageName correctly.
  640. auto *dbgGlobalVar = spvBuilder.createDebugGlobalVariable(
  641. type, name, info->source, line, column, info->scopeStack.back(),
  642. /* linkageName */ name, var, flags);
  643. dbgGlobalVar->setDebugSpirvType(var->getResultType());
  644. dbgGlobalVar->setLayoutRule(var->getLayoutRule());
  645. return dbgGlobalVar;
  646. }
  647. return nullptr;
  648. }
  649. SpirvVariable *
  650. DeclResultIdMapper::createFileVar(const VarDecl *var,
  651. llvm::Optional<SpirvInstruction *> init) {
  652. const auto type = getTypeOrFnRetType(var);
  653. const auto loc = var->getLocation();
  654. const auto name = var->getName();
  655. SpirvVariable *varInstr =
  656. spvBuilder.addModuleVar(type, spv::StorageClass::Private,
  657. var->hasAttr<HLSLPreciseAttr>(), name, init, loc);
  658. bool isAlias = false;
  659. (void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias);
  660. varInstr->setContainsAliasComponent(isAlias);
  661. assert(astDecls[var].instr == nullptr);
  662. astDecls[var].instr = varInstr;
  663. createDebugGlobalVariable(varInstr, type, loc, name);
  664. return varInstr;
  665. }
  666. SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var) {
  667. const auto type = var->getType();
  668. const bool isGroupShared = var->hasAttr<HLSLGroupSharedAttr>();
  669. const bool isACRWSBuffer = isRWAppendConsumeSBuffer(type);
  670. const auto storageClass = getStorageClassForExternVar(type, isGroupShared);
  671. const auto rule = getLayoutRuleForExternVar(type, spirvOptions);
  672. const auto loc = var->getLocation();
  673. if (!isGroupShared && !isResourceType(type) &&
  674. !isResourceOnlyStructure(type)) {
  675. // We currently cannot support global structures that contain both resources
  676. // and non-resources. That would require significant work in manipulating
  677. // structure field decls, manipulating QualTypes, as well as inserting
  678. // non-resources into the Globals cbuffer which changes offset decorations
  679. // for it.
  680. if (isStructureContainingMixOfResourcesAndNonResources(type)) {
  681. emitError("global structures containing both resources and non-resources "
  682. "are not supported",
  683. loc);
  684. return nullptr;
  685. }
  686. // This is a stand-alone externally-visiable non-resource-type variable.
  687. // They should be grouped into the $Globals cbuffer. We create that cbuffer
  688. // and record all variables inside it upon seeing the first such variable.
  689. if (astDecls.count(var) == 0)
  690. createGlobalsCBuffer(var);
  691. auto *varInstr = astDecls[var].instr;
  692. return varInstr ? cast<SpirvVariable>(varInstr) : nullptr;
  693. }
  694. if (isResourceOnlyStructure(type)) {
  695. // We currently do not support global structures that contain buffers.
  696. // Supporting global structures that contain buffers has two complications:
  697. //
  698. // 1- Buffers have the Uniform storage class, whereas Textures/Samplers have
  699. // UniformConstant storage class. As a result, if a struct contains both
  700. // textures and buffers, it is not clear what storage class should be used
  701. // for the struct. Also legalization cannot deduce the proper storage class
  702. // for struct members based on the structure's storage class.
  703. //
  704. // 2- Any kind of structured buffer has associated counters. The current DXC
  705. // code is not written in a way to place associated counters inside a
  706. // structure. Changing this behavior is non-trivial. There's also
  707. // significant work to be done both in DXC (to properly generate binding
  708. // numbers for the resource and its associated counters at correct offsets)
  709. // and in spirv-opt (to flatten such strcutures and modify the binding
  710. // numbers accordingly).
  711. if (isStructureContainingAnyKindOfBuffer(type)) {
  712. emitError("global structures containing buffers are not supported", loc);
  713. return nullptr;
  714. }
  715. needsFlatteningCompositeResources = true;
  716. }
  717. const auto name = var->getName();
  718. SpirvVariable *varInstr = spvBuilder.addModuleVar(
  719. type, storageClass, var->hasAttr<HLSLPreciseAttr>(), name, llvm::None,
  720. loc);
  721. varInstr->setLayoutRule(rule);
  722. DeclSpirvInfo info(varInstr);
  723. astDecls[var] = info;
  724. createDebugGlobalVariable(varInstr, type, loc, name);
  725. // Variables in Workgroup do not need descriptor decorations.
  726. if (storageClass == spv::StorageClass::Workgroup)
  727. return varInstr;
  728. const auto *regAttr = getResourceBinding(var);
  729. const auto *bindingAttr = var->getAttr<VKBindingAttr>();
  730. const auto *counterBindingAttr = var->getAttr<VKCounterBindingAttr>();
  731. resourceVars.emplace_back(varInstr, var, loc, regAttr, bindingAttr,
  732. counterBindingAttr);
  733. if (const auto *inputAttachment = var->getAttr<VKInputAttachmentIndexAttr>())
  734. spvBuilder.decorateInputAttachmentIndex(varInstr,
  735. inputAttachment->getIndex(), loc);
  736. if (isACRWSBuffer) {
  737. // For {Append|Consume|RW}StructuredBuffer, we need to always create another
  738. // variable for its associated counter.
  739. createCounterVar(var, varInstr, /*isAlias=*/false);
  740. }
  741. return varInstr;
  742. }
  743. SpirvInstruction *
  744. DeclResultIdMapper::createOrUpdateStringVar(const VarDecl *var) {
  745. assert(hlsl::IsStringType(var->getType()) ||
  746. hlsl::IsStringLiteralType(var->getType()));
  747. // If the string variable is not initialized to a string literal, we cannot
  748. // generate an OpString for it.
  749. if (!var->hasInit()) {
  750. emitError("Found uninitialized string variable.", var->getLocation());
  751. return nullptr;
  752. }
  753. const StringLiteral *stringLiteral =
  754. dyn_cast<StringLiteral>(var->getInit()->IgnoreParenCasts());
  755. SpirvString *init = spvBuilder.getString(stringLiteral->getString());
  756. DeclSpirvInfo info(init);
  757. astDecls[var] = info;
  758. return init;
  759. }
  760. SpirvVariable *DeclResultIdMapper::createStructOrStructArrayVarOfExplicitLayout(
  761. const DeclContext *decl, int arraySize, const ContextUsageKind usageKind,
  762. llvm::StringRef typeName, llvm::StringRef varName) {
  763. // cbuffers are translated into OpTypeStruct with Block decoration.
  764. // tbuffers are translated into OpTypeStruct with BufferBlock decoration.
  765. // Push constants are translated into OpTypeStruct with Block decoration.
  766. //
  767. // Both cbuffers and tbuffers have the SPIR-V Uniform storage class.
  768. // Push constants have the SPIR-V PushConstant storage class.
  769. const bool forCBuffer = usageKind == ContextUsageKind::CBuffer;
  770. const bool forTBuffer = usageKind == ContextUsageKind::TBuffer;
  771. const bool forGlobals = usageKind == ContextUsageKind::Globals;
  772. const bool forPC = usageKind == ContextUsageKind::PushConstant;
  773. const bool forShaderRecordNV =
  774. usageKind == ContextUsageKind::ShaderRecordBufferNV;
  775. const bool forShaderRecordEXT =
  776. usageKind == ContextUsageKind::ShaderRecordBufferEXT;
  777. const auto &declGroup = collectDeclsInDeclContext(decl);
  778. // Collect the type and name for each field
  779. llvm::SmallVector<HybridStructType::FieldInfo, 4> fields;
  780. for (const auto *subDecl : declGroup) {
  781. // The field can only be FieldDecl (for normal structs) or VarDecl (for
  782. // HLSLBufferDecls).
  783. assert(isa<VarDecl>(subDecl) || isa<FieldDecl>(subDecl));
  784. const auto *declDecl = cast<DeclaratorDecl>(subDecl);
  785. // In case 'register(c#)' annotation is placed on a global variable.
  786. const hlsl::RegisterAssignment *registerC =
  787. forGlobals ? getRegisterCAssignment(declDecl) : nullptr;
  788. // All fields are qualified with const. It will affect the debug name.
  789. // We don't need it here.
  790. auto varType = declDecl->getType();
  791. varType.removeLocalConst();
  792. HybridStructType::FieldInfo info(varType, declDecl->getName(),
  793. declDecl->getAttr<VKOffsetAttr>(),
  794. getPackOffset(declDecl), registerC,
  795. declDecl->hasAttr<HLSLPreciseAttr>());
  796. fields.push_back(info);
  797. }
  798. // Get the type for the whole struct
  799. // tbuffer/TextureBuffers are non-writable SSBOs.
  800. const SpirvType *resultType = spvContext.getHybridStructType(
  801. fields, typeName, /*isReadOnly*/ forTBuffer,
  802. forTBuffer ? StructInterfaceType::StorageBuffer
  803. : StructInterfaceType::UniformBuffer);
  804. // Make an array if requested.
  805. if (arraySize > 0) {
  806. resultType = spvContext.getArrayType(resultType, arraySize,
  807. /*ArrayStride*/ llvm::None);
  808. } else if (arraySize == -1) {
  809. resultType =
  810. spvContext.getRuntimeArrayType(resultType, /*ArrayStride*/ llvm::None);
  811. }
  812. // Register the <type-id> for this decl
  813. ctBufferPCTypes[decl] = resultType;
  814. const auto sc = forPC ? spv::StorageClass::PushConstant
  815. : forShaderRecordNV
  816. ? spv::StorageClass::ShaderRecordBufferNV
  817. : forShaderRecordEXT
  818. ? spv::StorageClass::ShaderRecordBufferKHR
  819. : spv::StorageClass::Uniform;
  820. // Create the variable for the whole struct / struct array.
  821. // The fields may be 'precise', but the structure itself is not.
  822. SpirvVariable *var =
  823. spvBuilder.addModuleVar(resultType, sc, /*isPrecise*/ false, varName);
  824. const SpirvLayoutRule layoutRule =
  825. (forCBuffer || forGlobals)
  826. ? spirvOptions.cBufferLayoutRule
  827. : (forTBuffer ? spirvOptions.tBufferLayoutRule
  828. : spirvOptions.sBufferLayoutRule);
  829. var->setHlslUserType(forCBuffer ? "cbuffer" : forTBuffer ? "tbuffer" : "");
  830. var->setLayoutRule(layoutRule);
  831. return var;
  832. }
  833. void DeclResultIdMapper::createEnumConstant(const EnumConstantDecl *decl) {
  834. const auto *valueDecl = dyn_cast<ValueDecl>(decl);
  835. const auto enumConstant =
  836. spvBuilder.getConstantInt(astContext.IntTy, decl->getInitVal());
  837. SpirvVariable *varInstr = spvBuilder.addModuleVar(
  838. astContext.IntTy, spv::StorageClass::Private, /*isPrecise*/ false,
  839. decl->getName(), enumConstant, decl->getLocation());
  840. astDecls[valueDecl] = DeclSpirvInfo(varInstr);
  841. }
  842. SpirvVariable *DeclResultIdMapper::createCTBuffer(const HLSLBufferDecl *decl) {
  843. // This function handles creation of cbuffer or tbuffer.
  844. const auto usageKind =
  845. decl->isCBuffer() ? ContextUsageKind::CBuffer : ContextUsageKind::TBuffer;
  846. const std::string structName = "type." + decl->getName().str();
  847. // The front-end does not allow arrays of cbuffer/tbuffer.
  848. SpirvVariable *bufferVar = createStructOrStructArrayVarOfExplicitLayout(
  849. decl, /*arraySize*/ 0, usageKind, structName, decl->getName());
  850. // We still register all VarDecls seperately here. All the VarDecls are
  851. // mapped to the <result-id> of the buffer object, which means when querying
  852. // querying the <result-id> for a certain VarDecl, we need to do an extra
  853. // OpAccessChain.
  854. int index = 0;
  855. for (const auto *subDecl : decl->decls()) {
  856. if (shouldSkipInStructLayout(subDecl))
  857. continue;
  858. const auto *varDecl = cast<VarDecl>(subDecl);
  859. astDecls[varDecl] = DeclSpirvInfo(bufferVar, index++);
  860. }
  861. resourceVars.emplace_back(
  862. bufferVar, decl, decl->getLocation(), getResourceBinding(decl),
  863. decl->getAttr<VKBindingAttr>(), decl->getAttr<VKCounterBindingAttr>());
  864. auto *dbgGlobalVar = createDebugGlobalVariable(
  865. bufferVar, QualType(), decl->getLocation(), decl->getName());
  866. if (dbgGlobalVar != nullptr) {
  867. // C/TBuffer needs HLSLBufferDecl for debug type lowering.
  868. spvContext.registerStructDeclForSpirvType(bufferVar->getResultType(), decl);
  869. }
  870. return bufferVar;
  871. }
  872. SpirvVariable *DeclResultIdMapper::createCTBuffer(const VarDecl *decl) {
  873. // This function handles creation of ConstantBuffer<T> or TextureBuffer<T>.
  874. // The way this is represented in the AST is as follows:
  875. //
  876. // |-VarDecl MyCbuffer 'ConstantBuffer<T>':'ConstantBuffer<T>'
  877. // |-CXXRecordDecl referenced struct T definition
  878. // |-CXXRecordDecl implicit struct T
  879. // |-FieldDecl
  880. // |-...
  881. // |-FieldDecl
  882. const QualType type = decl->getType();
  883. assert(isConstantTextureBuffer(type));
  884. const RecordType *recordType = nullptr;
  885. const RecordType *templatedType = nullptr;
  886. int arraySize = 0;
  887. // In case we have an array of ConstantBuffer/TextureBuffer:
  888. if (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
  889. const QualType elemType = arrayType->getElementType();
  890. recordType = elemType->getAs<RecordType>();
  891. templatedType =
  892. hlsl::GetHLSLResourceResultType(elemType)->getAs<RecordType>();
  893. if (const auto *caType = astContext.getAsConstantArrayType(type)) {
  894. arraySize = static_cast<uint32_t>(caType->getSize().getZExtValue());
  895. } else {
  896. arraySize = -1;
  897. }
  898. } else {
  899. recordType = type->getAs<RecordType>();
  900. templatedType = hlsl::GetHLSLResourceResultType(type)->getAs<RecordType>();
  901. }
  902. if (!recordType) {
  903. emitError("constant/texture buffer type %0 unimplemented",
  904. decl->getLocStart())
  905. << type;
  906. return nullptr;
  907. }
  908. if (!templatedType) {
  909. emitError(
  910. "the underlying type for constant/texture buffer must be a struct",
  911. decl->getLocStart())
  912. << type;
  913. return nullptr;
  914. }
  915. const bool isConstBuffer = isConstantBuffer(type);
  916. const auto usageKind =
  917. isConstBuffer ? ContextUsageKind::CBuffer : ContextUsageKind::TBuffer;
  918. const std::string structName = "type." +
  919. recordType->getDecl()->getName().str() + "." +
  920. templatedType->getDecl()->getName().str();
  921. SpirvVariable *bufferVar = createStructOrStructArrayVarOfExplicitLayout(
  922. templatedType->getDecl(), arraySize, usageKind, structName,
  923. decl->getName());
  924. // We register the VarDecl here.
  925. astDecls[decl] = DeclSpirvInfo(bufferVar);
  926. resourceVars.emplace_back(
  927. bufferVar, decl, decl->getLocation(), getResourceBinding(decl),
  928. decl->getAttr<VKBindingAttr>(), decl->getAttr<VKCounterBindingAttr>());
  929. return bufferVar;
  930. }
  931. SpirvVariable *DeclResultIdMapper::createPushConstant(const VarDecl *decl) {
  932. // The front-end errors out if non-struct type push constant is used.
  933. const QualType type = decl->getType();
  934. const auto *recordType = type->getAs<RecordType>();
  935. if (isConstantBuffer(type)) {
  936. // Get the templated type for ConstantBuffer.
  937. recordType = hlsl::GetHLSLResourceResultType(type)->getAs<RecordType>();
  938. }
  939. assert(recordType);
  940. const std::string structName =
  941. "type.PushConstant." + recordType->getDecl()->getName().str();
  942. SpirvVariable *var = createStructOrStructArrayVarOfExplicitLayout(
  943. recordType->getDecl(), /*arraySize*/ 0, ContextUsageKind::PushConstant,
  944. structName, decl->getName());
  945. // Register the VarDecl
  946. astDecls[decl] = DeclSpirvInfo(var);
  947. // Do not push this variable into resourceVars since it does not need
  948. // descriptor set.
  949. return var;
  950. }
  951. SpirvVariable *
  952. DeclResultIdMapper::createShaderRecordBuffer(const VarDecl *decl,
  953. ContextUsageKind kind) {
  954. const auto *recordType =
  955. hlsl::GetHLSLResourceResultType(decl->getType())->getAs<RecordType>();
  956. assert(recordType);
  957. assert(kind == ContextUsageKind::ShaderRecordBufferEXT ||
  958. kind == ContextUsageKind::ShaderRecordBufferNV);
  959. const auto typeName = kind == ContextUsageKind::ShaderRecordBufferEXT
  960. ? "type.ShaderRecordBufferEXT."
  961. : "type.ShaderRecordBufferNV.";
  962. const std::string structName =
  963. typeName + recordType->getDecl()->getName().str();
  964. SpirvVariable *var = createStructOrStructArrayVarOfExplicitLayout(
  965. recordType->getDecl(), /*arraySize*/ 0,
  966. kind, structName, decl->getName());
  967. // Register the VarDecl
  968. astDecls[decl] = DeclSpirvInfo(var);
  969. // Do not push this variable into resourceVars since it does not need
  970. // descriptor set.
  971. return var;
  972. }
  973. SpirvVariable *
  974. DeclResultIdMapper::createShaderRecordBuffer(const HLSLBufferDecl *decl,
  975. ContextUsageKind kind) {
  976. assert(kind == ContextUsageKind::ShaderRecordBufferEXT ||
  977. kind == ContextUsageKind::ShaderRecordBufferNV);
  978. const auto typeName = kind == ContextUsageKind::ShaderRecordBufferEXT
  979. ? "type.ShaderRecordBufferEXT."
  980. : "type.ShaderRecordBufferNV.";
  981. const std::string structName =
  982. typeName + decl->getName().str();
  983. // The front-end does not allow arrays of cbuffer/tbuffer.
  984. SpirvVariable *bufferVar = createStructOrStructArrayVarOfExplicitLayout(
  985. decl, /*arraySize*/ 0, kind, structName,
  986. decl->getName());
  987. // We still register all VarDecls seperately here. All the VarDecls are
  988. // mapped to the <result-id> of the buffer object, which means when
  989. // querying the <result-id> for a certain VarDecl, we need to do an extra
  990. // OpAccessChain.
  991. int index = 0;
  992. for (const auto *subDecl : decl->decls()) {
  993. if (shouldSkipInStructLayout(subDecl))
  994. continue;
  995. const auto *varDecl = cast<VarDecl>(subDecl);
  996. astDecls[varDecl] = DeclSpirvInfo(bufferVar, index++);
  997. }
  998. return bufferVar;
  999. }
  1000. void DeclResultIdMapper::createGlobalsCBuffer(const VarDecl *var) {
  1001. if (astDecls.count(var) != 0)
  1002. return;
  1003. const auto *context = var->getTranslationUnitDecl();
  1004. SpirvVariable *globals = createStructOrStructArrayVarOfExplicitLayout(
  1005. context, /*arraySize*/ 0, ContextUsageKind::Globals, "type.$Globals",
  1006. "$Globals");
  1007. resourceVars.emplace_back(globals, /*decl*/ nullptr, SourceLocation(),
  1008. nullptr, nullptr, nullptr, /*isCounterVar*/ false,
  1009. /*isGlobalsCBuffer*/ true);
  1010. uint32_t index = 0;
  1011. for (const auto *decl : collectDeclsInDeclContext(context)) {
  1012. if (const auto *varDecl = dyn_cast<VarDecl>(decl)) {
  1013. if (!spirvOptions.noWarnIgnoredFeatures) {
  1014. if (const auto *init = varDecl->getInit())
  1015. emitWarning(
  1016. "variable '%0' will be placed in $Globals so initializer ignored",
  1017. init->getExprLoc())
  1018. << var->getName() << init->getSourceRange();
  1019. }
  1020. if (const auto *attr = varDecl->getAttr<VKBindingAttr>()) {
  1021. emitError("variable '%0' will be placed in $Globals so cannot have "
  1022. "vk::binding attribute",
  1023. attr->getLocation())
  1024. << var->getName();
  1025. return;
  1026. }
  1027. astDecls[varDecl] = DeclSpirvInfo(globals, index++);
  1028. }
  1029. }
  1030. }
  1031. SpirvFunction *DeclResultIdMapper::getOrRegisterFn(const FunctionDecl *fn) {
  1032. // Return it if it's already been created.
  1033. auto it = astFunctionDecls.find(fn);
  1034. if (it != astFunctionDecls.end()) {
  1035. return it->second;
  1036. }
  1037. bool isAlias = false;
  1038. (void)getTypeAndCreateCounterForPotentialAliasVar(fn, &isAlias);
  1039. const bool isPrecise = fn->hasAttr<HLSLPreciseAttr>();
  1040. const bool isNoInline = fn->hasAttr<NoInlineAttr>();
  1041. // Note: we do not need to worry about function parameter types at this point
  1042. // as this is used when function declarations are seen. When function
  1043. // definition is seen, the parameter types will be set properly and take into
  1044. // account whether the function is a member function of a class/struct (in
  1045. // which case a 'this' parameter is added at the beginnig).
  1046. SpirvFunction *spirvFunction =
  1047. spvBuilder.createSpirvFunction(fn->getReturnType(), fn->getLocation(),
  1048. fn->getName(), isPrecise, isNoInline);
  1049. // No need to dereference to get the pointer. Function returns that are
  1050. // stand-alone aliases are already pointers to values. All other cases should
  1051. // be normal rvalues.
  1052. if (!isAlias || !isAKindOfStructuredOrByteBuffer(fn->getReturnType()))
  1053. spirvFunction->setRValue();
  1054. spirvFunction->setConstainsAliasComponent(isAlias);
  1055. astFunctionDecls[fn] = spirvFunction;
  1056. return spirvFunction;
  1057. }
  1058. const CounterIdAliasPair *DeclResultIdMapper::getCounterIdAliasPair(
  1059. const DeclaratorDecl *decl, const llvm::SmallVector<uint32_t, 4> *indices) {
  1060. if (!decl)
  1061. return nullptr;
  1062. if (indices) {
  1063. // Indices are provided. Walk through the fields of the decl.
  1064. const auto counter = fieldCounterVars.find(decl);
  1065. if (counter != fieldCounterVars.end())
  1066. return counter->second.get(*indices);
  1067. } else {
  1068. // No indices. Check the stand-alone entities.
  1069. const auto counter = counterVars.find(decl);
  1070. if (counter != counterVars.end())
  1071. return &counter->second;
  1072. }
  1073. return nullptr;
  1074. }
  1075. const CounterVarFields *
  1076. DeclResultIdMapper::getCounterVarFields(const DeclaratorDecl *decl) {
  1077. if (!decl)
  1078. return nullptr;
  1079. const auto found = fieldCounterVars.find(decl);
  1080. if (found != fieldCounterVars.end())
  1081. return &found->second;
  1082. return nullptr;
  1083. }
  1084. void DeclResultIdMapper::registerSpecConstant(const VarDecl *decl,
  1085. SpirvInstruction *specConstant) {
  1086. specConstant->setRValue();
  1087. astDecls[decl] = DeclSpirvInfo(specConstant);
  1088. }
  1089. void DeclResultIdMapper::createCounterVar(
  1090. const DeclaratorDecl *decl, SpirvInstruction *declInstr, bool isAlias,
  1091. const llvm::SmallVector<uint32_t, 4> *indices) {
  1092. std::string counterName = "counter.var." + decl->getName().str();
  1093. if (indices) {
  1094. // Append field indices to the name
  1095. for (const auto index : *indices)
  1096. counterName += "." + std::to_string(index);
  1097. }
  1098. const SpirvType *counterType = spvContext.getACSBufferCounterType();
  1099. // {RW|Append|Consume}StructuredBuffer are all in Uniform storage class.
  1100. // Alias counter variables should be created into the Private storage class.
  1101. const spv::StorageClass sc =
  1102. isAlias ? spv::StorageClass::Private : spv::StorageClass::Uniform;
  1103. if (isAlias) {
  1104. // Apply an extra level of pointer for alias counter variable
  1105. counterType =
  1106. spvContext.getPointerType(counterType, spv::StorageClass::Uniform);
  1107. }
  1108. SpirvVariable *counterInstr = spvBuilder.addModuleVar(
  1109. counterType, sc, /*isPrecise*/ false, counterName);
  1110. if (!isAlias) {
  1111. // Non-alias counter variables should be put in to resourceVars so that
  1112. // descriptors can be allocated for them.
  1113. resourceVars.emplace_back(counterInstr, decl, decl->getLocation(),
  1114. getResourceBinding(decl),
  1115. decl->getAttr<VKBindingAttr>(),
  1116. decl->getAttr<VKCounterBindingAttr>(), true);
  1117. assert(declInstr);
  1118. spvBuilder.decorateCounterBuffer(declInstr, counterInstr,
  1119. decl->getLocation());
  1120. }
  1121. if (indices)
  1122. fieldCounterVars[decl].append(*indices, counterInstr);
  1123. else
  1124. counterVars[decl] = {counterInstr, isAlias};
  1125. }
  1126. void DeclResultIdMapper::createFieldCounterVars(
  1127. const DeclaratorDecl *rootDecl, const DeclaratorDecl *decl,
  1128. llvm::SmallVector<uint32_t, 4> *indices) {
  1129. const QualType type = getTypeOrFnRetType(decl);
  1130. const auto *recordType = type->getAs<RecordType>();
  1131. assert(recordType);
  1132. const auto *recordDecl = recordType->getDecl();
  1133. for (const auto *field : recordDecl->fields()) {
  1134. // Build up the index chain
  1135. indices->push_back(getNumBaseClasses(type) + field->getFieldIndex());
  1136. const QualType fieldType = field->getType();
  1137. if (isRWAppendConsumeSBuffer(fieldType))
  1138. createCounterVar(rootDecl, /*declId=*/0, /*isAlias=*/true, indices);
  1139. else if (fieldType->isStructureType() &&
  1140. !hlsl::IsHLSLResourceType(fieldType))
  1141. // Go recursively into all nested structs
  1142. createFieldCounterVars(rootDecl, field, indices);
  1143. indices->pop_back();
  1144. }
  1145. }
  1146. const SpirvType *
  1147. DeclResultIdMapper::getCTBufferPushConstantType(const DeclContext *decl) {
  1148. const auto found = ctBufferPCTypes.find(decl);
  1149. assert(found != ctBufferPCTypes.end());
  1150. return found->second;
  1151. }
  1152. std::vector<SpirvVariable *> DeclResultIdMapper::collectStageVars() const {
  1153. std::vector<SpirvVariable *> vars;
  1154. for (auto var : glPerVertex.getStageInVars())
  1155. vars.push_back(var);
  1156. for (auto var : glPerVertex.getStageOutVars())
  1157. vars.push_back(var);
  1158. llvm::DenseSet<SpirvInstruction *> seenVars;
  1159. for (const auto &var : stageVars) {
  1160. auto *instr = var.getSpirvInstr();
  1161. if (seenVars.count(instr) == 0) {
  1162. vars.push_back(instr);
  1163. seenVars.insert(instr);
  1164. }
  1165. }
  1166. return vars;
  1167. }
  1168. namespace {
  1169. /// A class for managing stage input/output locations to avoid duplicate uses of
  1170. /// the same location.
  1171. class LocationSet {
  1172. public:
  1173. /// Maximum number of indices supported
  1174. const static uint32_t kMaxIndex = 2;
  1175. /// Maximum number of locations supported
  1176. // Typically we won't have that many stage input or output variables.
  1177. // Using 64 should be fine here.
  1178. const static uint32_t kMaxLoc = 64;
  1179. LocationSet() {
  1180. for (uint32_t i = 0; i < kMaxIndex; ++i) {
  1181. usedLocs[i].resize(kMaxLoc);
  1182. nextLoc[i] = 0;
  1183. }
  1184. }
  1185. /// Uses the given location.
  1186. void useLoc(uint32_t loc, uint32_t index = 0) {
  1187. assert(index < kMaxIndex);
  1188. usedLocs[index].set(loc);
  1189. }
  1190. /// Uses the next |count| available location.
  1191. int useNextLocs(uint32_t count, uint32_t index = 0) {
  1192. assert(index < kMaxIndex);
  1193. auto &locs = usedLocs[index];
  1194. auto &next = nextLoc[index];
  1195. while (locs[next])
  1196. next++;
  1197. int toUse = next;
  1198. for (uint32_t i = 0; i < count; ++i) {
  1199. assert(!locs[next]);
  1200. locs.set(next++);
  1201. }
  1202. return toUse;
  1203. }
  1204. /// Returns true if the given location number is already used.
  1205. bool isLocUsed(uint32_t loc, uint32_t index = 0) {
  1206. assert(index < kMaxIndex);
  1207. return usedLocs[index][loc];
  1208. }
  1209. private:
  1210. llvm::SmallBitVector usedLocs[kMaxIndex]; ///< All previously used locations
  1211. uint32_t nextLoc[kMaxIndex]; ///< Next available location
  1212. };
  1213. /// A class for managing resource bindings to avoid duplicate uses of the same
  1214. /// set and binding number.
  1215. class BindingSet {
  1216. public:
  1217. /// Uses the given set and binding number. Returns false if the binding number
  1218. /// was already occupied in the set, and returns true otherwise.
  1219. bool useBinding(uint32_t binding, uint32_t set) {
  1220. bool inserted = false;
  1221. std::tie(std::ignore, inserted) = usedBindings[set].insert(binding);
  1222. return inserted;
  1223. }
  1224. /// Uses the next available binding number in |set|. If more than one binding
  1225. /// number is to be occupied, it finds the next available chunk that can fit
  1226. /// |numBindingsToUse| in the |set|.
  1227. uint32_t useNextBinding(uint32_t set, uint32_t numBindingsToUse = 1,
  1228. uint32_t bindingShift = 0) {
  1229. uint32_t bindingNoStart =
  1230. getNextBindingChunk(set, numBindingsToUse, bindingShift);
  1231. auto &binding = usedBindings[set];
  1232. for (uint32_t i = 0; i < numBindingsToUse; ++i)
  1233. binding.insert(bindingNoStart + i);
  1234. return bindingNoStart;
  1235. }
  1236. /// Returns the first available binding number in the |set| for which |n|
  1237. /// consecutive binding numbers are unused starting at |bindingShift|.
  1238. uint32_t getNextBindingChunk(uint32_t set, uint32_t n,
  1239. uint32_t bindingShift) {
  1240. auto &existingBindings = usedBindings[set];
  1241. // There were no bindings in this set. Can start at binding zero.
  1242. if (existingBindings.empty())
  1243. return bindingShift;
  1244. // Check whether the chunk of |n| binding numbers can be fitted at the
  1245. // very beginning of the list (start at binding 0 in the current set).
  1246. uint32_t curBinding = *existingBindings.begin();
  1247. if (curBinding >= (n + bindingShift))
  1248. return bindingShift;
  1249. auto iter = std::next(existingBindings.begin());
  1250. while (iter != existingBindings.end()) {
  1251. // There exists a next binding number that is used. Check to see if the
  1252. // gap between current binding number and next binding number is large
  1253. // enough to accommodate |n|.
  1254. uint32_t nextBinding = *iter;
  1255. if ((bindingShift > 0) && (curBinding < (bindingShift - 1)))
  1256. curBinding = bindingShift - 1;
  1257. if (curBinding < nextBinding && n <= nextBinding - curBinding - 1)
  1258. return curBinding + 1;
  1259. curBinding = nextBinding;
  1260. // Peek at the next binding that has already been used (if any).
  1261. ++iter;
  1262. }
  1263. // |curBinding| was the last binding that was used in this set. The next
  1264. // chunk of |n| bindings can start at |curBinding|+1.
  1265. return std::max(curBinding + 1, bindingShift);
  1266. }
  1267. private:
  1268. ///< set number -> set of used binding number
  1269. llvm::DenseMap<uint32_t, std::set<uint32_t>> usedBindings;
  1270. };
  1271. } // namespace
  1272. bool DeclResultIdMapper::checkSemanticDuplication(bool forInput) {
  1273. llvm::StringSet<> seenSemantics;
  1274. bool success = true;
  1275. for (const auto &var : stageVars) {
  1276. auto s = var.getSemanticStr();
  1277. if (s.empty()) {
  1278. // We translate WaveGetLaneCount(), WaveGetLaneIndex() and 'payload' param
  1279. // block declaration into builtin variables. Those variables are inserted
  1280. // into the normal stage IO processing pipeline, but with the semantics as
  1281. // empty strings.
  1282. assert(var.isSpirvBuitin());
  1283. continue;
  1284. }
  1285. // Allow builtin variables to alias each other. We already have uniqify
  1286. // mechanism in SpirvBuilder.
  1287. if (var.isSpirvBuitin())
  1288. continue;
  1289. if (forInput && var.getSigPoint()->IsInput()) {
  1290. if (seenSemantics.count(s)) {
  1291. emitError("input semantic '%0' used more than once", {}) << s;
  1292. success = false;
  1293. }
  1294. seenSemantics.insert(s);
  1295. } else if (!forInput && var.getSigPoint()->IsOutput()) {
  1296. if (seenSemantics.count(s)) {
  1297. emitError("output semantic '%0' used more than once", {}) << s;
  1298. success = false;
  1299. }
  1300. seenSemantics.insert(s);
  1301. }
  1302. }
  1303. return success;
  1304. }
  1305. bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) {
  1306. if (!checkSemanticDuplication(forInput))
  1307. return false;
  1308. // Returns false if the given StageVar is an input/output variable without
  1309. // explicit location assignment. Otherwise, returns true.
  1310. const auto locAssigned = [forInput, this](const StageVar &v) {
  1311. if (forInput == isInputStorageClass(v))
  1312. // No need to assign location for builtins. Treat as assigned.
  1313. return v.isSpirvBuitin() || v.getLocationAttr() != nullptr;
  1314. // For the ones we don't care, treat as assigned.
  1315. return true;
  1316. };
  1317. // If we have explicit location specified for all input/output variables,
  1318. // use them instead assign by ourselves.
  1319. if (std::all_of(stageVars.begin(), stageVars.end(), locAssigned)) {
  1320. LocationSet locSet;
  1321. bool noError = true;
  1322. for (const auto &var : stageVars) {
  1323. // Skip builtins & those stage variables we are not handling for this call
  1324. if (var.isSpirvBuitin() || forInput != isInputStorageClass(var))
  1325. continue;
  1326. const auto *attr = var.getLocationAttr();
  1327. const auto loc = attr->getNumber();
  1328. const auto attrLoc = attr->getLocation(); // Attr source code location
  1329. const auto idx = var.getIndexAttr() ? var.getIndexAttr()->getNumber() : 0;
  1330. if ((const unsigned)loc >= LocationSet::kMaxLoc) {
  1331. emitError("stage %select{output|input}0 location #%1 too large",
  1332. attrLoc)
  1333. << forInput << loc;
  1334. return false;
  1335. }
  1336. // Make sure the same location is not assigned more than once
  1337. if (locSet.isLocUsed(loc, idx)) {
  1338. emitError("stage %select{output|input}0 location #%1 already assigned",
  1339. attrLoc)
  1340. << forInput << loc;
  1341. noError = false;
  1342. }
  1343. locSet.useLoc(loc, idx);
  1344. spvBuilder.decorateLocation(var.getSpirvInstr(), loc);
  1345. if (var.getIndexAttr())
  1346. spvBuilder.decorateIndex(var.getSpirvInstr(), idx,
  1347. var.getSemanticInfo().loc);
  1348. }
  1349. return noError;
  1350. }
  1351. std::vector<const StageVar *> vars;
  1352. LocationSet locSet;
  1353. for (const auto &var : stageVars) {
  1354. if (var.isSpirvBuitin() || forInput != isInputStorageClass(var))
  1355. continue;
  1356. if (var.getLocationAttr()) {
  1357. // We have checked that not all of the stage variables have explicit
  1358. // location assignment.
  1359. emitError("partial explicit stage %select{output|input}0 location "
  1360. "assignment via vk::location(X) unsupported",
  1361. {})
  1362. << forInput;
  1363. return false;
  1364. }
  1365. const auto &semaInfo = var.getSemanticInfo();
  1366. // We should special rules for SV_Target: the location number comes from the
  1367. // semantic string index.
  1368. if (semaInfo.isTarget()) {
  1369. spvBuilder.decorateLocation(var.getSpirvInstr(), semaInfo.index);
  1370. locSet.useLoc(semaInfo.index);
  1371. } else {
  1372. vars.push_back(&var);
  1373. }
  1374. }
  1375. // If alphabetical ordering was requested, sort by semantic string.
  1376. // Since HS includes 2 sets of outputs (patch-constant output and
  1377. // OutputPatch), running into location mismatches between HS and DS is very
  1378. // likely. In order to avoid location mismatches between HS and DS, use
  1379. // alphabetical ordering.
  1380. if (spirvOptions.stageIoOrder == "alpha" ||
  1381. (!forInput && spvContext.isHS()) || (forInput && spvContext.isDS())) {
  1382. // Sort stage input/output variables alphabetically
  1383. std::sort(vars.begin(), vars.end(),
  1384. [](const StageVar *a, const StageVar *b) {
  1385. return a->getSemanticStr() < b->getSemanticStr();
  1386. });
  1387. }
  1388. for (const auto *var : vars)
  1389. spvBuilder.decorateLocation(var->getSpirvInstr(),
  1390. locSet.useNextLocs(var->getLocationCount()));
  1391. return true;
  1392. }
  1393. namespace {
  1394. /// A class for maintaining the binding number shift requested for descriptor
  1395. /// sets.
  1396. class BindingShiftMapper {
  1397. public:
  1398. explicit BindingShiftMapper(const llvm::SmallVectorImpl<int32_t> &shifts)
  1399. : masterShift(0) {
  1400. assert(shifts.size() % 2 == 0);
  1401. if (shifts.size() == 2 && shifts[1] == -1) {
  1402. masterShift = shifts[0];
  1403. } else {
  1404. for (uint32_t i = 0; i < shifts.size(); i += 2)
  1405. perSetShift[shifts[i + 1]] = shifts[i];
  1406. }
  1407. }
  1408. /// Returns the shift amount for the given set.
  1409. int32_t getShiftForSet(int32_t set) const {
  1410. const auto found = perSetShift.find(set);
  1411. if (found != perSetShift.end())
  1412. return found->second;
  1413. return masterShift;
  1414. }
  1415. private:
  1416. uint32_t masterShift; /// Shift amount applies to all sets.
  1417. llvm::DenseMap<int32_t, int32_t> perSetShift;
  1418. };
  1419. /// A class for maintaining the mapping from source code register attributes to
  1420. /// descriptor set and number settings.
  1421. class RegisterBindingMapper {
  1422. public:
  1423. /// Takes in the relation between register attributes and descriptor settings.
  1424. /// Each relation is represented by four strings:
  1425. /// <register-type-number> <space> <descriptor-binding> <set>
  1426. bool takeInRelation(const std::vector<std::string> &relation,
  1427. std::string *error) {
  1428. assert(relation.size() % 4 == 0);
  1429. mapping.clear();
  1430. for (uint32_t i = 0; i < relation.size(); i += 4) {
  1431. int32_t spaceNo = -1, setNo = -1, bindNo = -1;
  1432. if (StringRef(relation[i + 1]).getAsInteger(10, spaceNo) || spaceNo < 0) {
  1433. *error = "space number: " + relation[i + 1];
  1434. return false;
  1435. }
  1436. if (StringRef(relation[i + 2]).getAsInteger(10, bindNo) || bindNo < 0) {
  1437. *error = "binding number: " + relation[i + 2];
  1438. return false;
  1439. }
  1440. if (StringRef(relation[i + 3]).getAsInteger(10, setNo) || setNo < 0) {
  1441. *error = "set number: " + relation[i + 3];
  1442. return false;
  1443. }
  1444. mapping[relation[i + 1] + relation[i]] = std::make_pair(setNo, bindNo);
  1445. }
  1446. return true;
  1447. }
  1448. /// Returns true and set the correct set and binding number if we can find a
  1449. /// descriptor setting for the given register. False otherwise.
  1450. bool getSetBinding(const hlsl::RegisterAssignment *regAttr,
  1451. uint32_t defaultSpace, int *setNo, int *bindNo) const {
  1452. std::ostringstream iss;
  1453. iss << regAttr->RegisterSpace.getValueOr(defaultSpace)
  1454. << regAttr->RegisterType << regAttr->RegisterNumber;
  1455. auto found = mapping.find(iss.str());
  1456. if (found != mapping.end()) {
  1457. *setNo = found->second.first;
  1458. *bindNo = found->second.second;
  1459. return true;
  1460. }
  1461. return false;
  1462. }
  1463. private:
  1464. llvm::StringMap<std::pair<int, int>> mapping;
  1465. };
  1466. } // namespace
  1467. bool DeclResultIdMapper::decorateResourceBindings() {
  1468. // For normal resource, we support 4 approaches of setting binding numbers:
  1469. // - m1: [[vk::binding(...)]]
  1470. // - m2: :register(xX, spaceY)
  1471. // - m3: None
  1472. // - m4: :register(spaceY)
  1473. //
  1474. // For associated counters, we support 2 approaches:
  1475. // - c1: [[vk::counter_binding(...)]
  1476. // - c2: None
  1477. //
  1478. // In combination, we need to handle 12 cases:
  1479. // - 4 cases for nomral resoures (m1, m2, m3, m4)
  1480. // - 8 cases for associated counters (mX * cY)
  1481. //
  1482. // In the following order:
  1483. // - m1, mX * c1
  1484. // - m2
  1485. // - m3, m4, mX * c2
  1486. // The "-auto-binding-space" command line option can be used to specify a
  1487. // certain space as default. UINT_MAX means the user has not provided this
  1488. // option. If not provided, the SPIR-V backend uses space "0" as default.
  1489. auto defaultSpaceOpt =
  1490. theEmitter.getCompilerInstance().getCodeGenOpts().HLSLDefaultSpace;
  1491. uint32_t defaultSpace = (defaultSpaceOpt == UINT_MAX) ? 0 : defaultSpaceOpt;
  1492. const bool bindGlobals = !spirvOptions.bindGlobals.empty();
  1493. int32_t globalsBindNo = -1, globalsSetNo = -1;
  1494. if (bindGlobals) {
  1495. assert(spirvOptions.bindGlobals.size() == 2);
  1496. if (StringRef(spirvOptions.bindGlobals[0])
  1497. .getAsInteger(10, globalsBindNo) ||
  1498. globalsBindNo < 0) {
  1499. emitError("invalid -fvk-bind-globals binding number: %0", {})
  1500. << spirvOptions.bindGlobals[0];
  1501. return false;
  1502. }
  1503. if (StringRef(spirvOptions.bindGlobals[1]).getAsInteger(10, globalsSetNo) ||
  1504. globalsSetNo < 0) {
  1505. emitError("invalid -fvk-bind-globals set number: %0", {})
  1506. << spirvOptions.bindGlobals[1];
  1507. return false;
  1508. }
  1509. }
  1510. // Special handling of -fvk-bind-register, which requires
  1511. // * All resources are annoated with :register() in the source code
  1512. // * -fvk-bind-register is specified for every resource
  1513. if (!spirvOptions.bindRegister.empty()) {
  1514. RegisterBindingMapper bindingMapper;
  1515. std::string error;
  1516. if (!bindingMapper.takeInRelation(spirvOptions.bindRegister, &error)) {
  1517. emitError("invalid -fvk-bind-register %0", {}) << error;
  1518. return false;
  1519. }
  1520. for (const auto &var : resourceVars)
  1521. if (const auto *regAttr = var.getRegister()) {
  1522. if (var.isCounter()) {
  1523. emitError("-fvk-bind-register for RW/Append/Consume StructuredBuffer "
  1524. "unimplemented",
  1525. var.getSourceLocation());
  1526. } else {
  1527. int setNo = 0, bindNo = 0;
  1528. if (!bindingMapper.getSetBinding(regAttr, defaultSpace, &setNo,
  1529. &bindNo)) {
  1530. emitError("missing -fvk-bind-register for resource",
  1531. var.getSourceLocation());
  1532. return false;
  1533. }
  1534. spvBuilder.decorateDSetBinding(var.getSpirvInstr(), setNo, bindNo);
  1535. }
  1536. } else if (bindGlobals && var.isGlobalsBuffer()) {
  1537. spvBuilder.decorateDSetBinding(var.getSpirvInstr(), globalsSetNo,
  1538. globalsBindNo);
  1539. } else {
  1540. emitError(
  1541. "-fvk-bind-register requires register annotations on all resources",
  1542. var.getSourceLocation());
  1543. return false;
  1544. }
  1545. return true;
  1546. }
  1547. BindingSet bindingSet;
  1548. // Decorates the given varId of the given category with set number
  1549. // setNo, binding number bindingNo. Ignores overlaps.
  1550. const auto tryToDecorate = [this, &bindingSet](const ResourceVar &var,
  1551. const uint32_t setNo,
  1552. const uint32_t bindingNo) {
  1553. // By default we use one binding number per resource, and an array of
  1554. // resources also gets only one binding number. However, for array of
  1555. // resources (e.g. array of textures), DX uses one binding number per array
  1556. // element. We can match this behavior via a command line option.
  1557. uint32_t numBindingsToUse = 1;
  1558. if (spirvOptions.flattenResourceArrays || needsFlatteningCompositeResources)
  1559. numBindingsToUse = getNumBindingsUsedByResourceType(
  1560. var.getSpirvInstr()->getAstResultType());
  1561. for (uint32_t i = 0; i < numBindingsToUse; ++i) {
  1562. bool success = bindingSet.useBinding(bindingNo + i, setNo);
  1563. // We will not emit an error if we find a set/binding overlap because it
  1564. // is possible that the optimizer optimizes away a resource which resolves
  1565. // the overlap.
  1566. (void)success;
  1567. }
  1568. // No need to decorate multiple binding numbers for arrays. It will be done
  1569. // by legalization/optimization.
  1570. spvBuilder.decorateDSetBinding(var.getSpirvInstr(), setNo, bindingNo);
  1571. };
  1572. for (const auto &var : resourceVars) {
  1573. if (var.isCounter()) {
  1574. if (const auto *vkCBinding = var.getCounterBinding()) {
  1575. // Process mX * c1
  1576. uint32_t set = defaultSpace;
  1577. if (const auto *vkBinding = var.getBinding())
  1578. set = getVkBindingAttrSet(vkBinding, defaultSpace);
  1579. else if (const auto *reg = var.getRegister())
  1580. set = reg->RegisterSpace.getValueOr(defaultSpace);
  1581. tryToDecorate(var, set, vkCBinding->getBinding());
  1582. }
  1583. } else {
  1584. if (const auto *vkBinding = var.getBinding()) {
  1585. // Process m1
  1586. tryToDecorate(var, getVkBindingAttrSet(vkBinding, defaultSpace),
  1587. vkBinding->getBinding());
  1588. }
  1589. }
  1590. }
  1591. BindingShiftMapper bShiftMapper(spirvOptions.bShift);
  1592. BindingShiftMapper tShiftMapper(spirvOptions.tShift);
  1593. BindingShiftMapper sShiftMapper(spirvOptions.sShift);
  1594. BindingShiftMapper uShiftMapper(spirvOptions.uShift);
  1595. // Process m2
  1596. for (const auto &var : resourceVars)
  1597. if (!var.isCounter() && !var.getBinding())
  1598. if (const auto *reg = var.getRegister()) {
  1599. // Skip space-only register() annotations
  1600. if (reg->isSpaceOnly())
  1601. continue;
  1602. const uint32_t set = reg->RegisterSpace.getValueOr(defaultSpace);
  1603. uint32_t binding = reg->RegisterNumber;
  1604. switch (reg->RegisterType) {
  1605. case 'b':
  1606. binding += bShiftMapper.getShiftForSet(set);
  1607. break;
  1608. case 't':
  1609. binding += tShiftMapper.getShiftForSet(set);
  1610. break;
  1611. case 's':
  1612. binding += sShiftMapper.getShiftForSet(set);
  1613. break;
  1614. case 'u':
  1615. binding += uShiftMapper.getShiftForSet(set);
  1616. break;
  1617. case 'c':
  1618. // For setting packing offset. Does not affect binding.
  1619. break;
  1620. default:
  1621. llvm_unreachable("unknown register type found");
  1622. }
  1623. tryToDecorate(var, set, binding);
  1624. }
  1625. for (const auto &var : resourceVars) {
  1626. // By default we use one binding number per resource, and an array of
  1627. // resources also gets only one binding number. However, for array of
  1628. // resources (e.g. array of textures), DX uses one binding number per array
  1629. // element. We can match this behavior via a command line option.
  1630. uint32_t numBindingsToUse = 1;
  1631. if (spirvOptions.flattenResourceArrays || needsFlatteningCompositeResources)
  1632. numBindingsToUse = getNumBindingsUsedByResourceType(
  1633. var.getSpirvInstr()->getAstResultType());
  1634. BindingShiftMapper *bindingShiftMapper = nullptr;
  1635. if (spirvOptions.autoShiftBindings) {
  1636. char registerType = '\0';
  1637. if (getImplicitRegisterType(var, &registerType)) {
  1638. switch (registerType) {
  1639. case 'b':
  1640. bindingShiftMapper = &bShiftMapper;
  1641. break;
  1642. case 't':
  1643. bindingShiftMapper = &tShiftMapper;
  1644. break;
  1645. case 's':
  1646. bindingShiftMapper = &sShiftMapper;
  1647. break;
  1648. case 'u':
  1649. bindingShiftMapper = &uShiftMapper;
  1650. break;
  1651. default:
  1652. llvm_unreachable("unknown register type found");
  1653. }
  1654. }
  1655. }
  1656. if (var.isCounter()) {
  1657. if (!var.getCounterBinding()) {
  1658. // Process mX * c2
  1659. uint32_t set = defaultSpace;
  1660. if (const auto *vkBinding = var.getBinding())
  1661. set = getVkBindingAttrSet(vkBinding, defaultSpace);
  1662. else if (const auto *reg = var.getRegister())
  1663. set = reg->RegisterSpace.getValueOr(defaultSpace);
  1664. uint32_t bindingShift = 0;
  1665. if (bindingShiftMapper)
  1666. bindingShift = bindingShiftMapper->getShiftForSet(set);
  1667. spvBuilder.decorateDSetBinding(
  1668. var.getSpirvInstr(), set,
  1669. bindingSet.useNextBinding(set, numBindingsToUse, bindingShift));
  1670. }
  1671. } else if (!var.getBinding()) {
  1672. const auto *reg = var.getRegister();
  1673. if (reg && reg->isSpaceOnly()) {
  1674. const uint32_t set = reg->RegisterSpace.getValueOr(defaultSpace);
  1675. uint32_t bindingShift = 0;
  1676. if (bindingShiftMapper)
  1677. bindingShift = bindingShiftMapper->getShiftForSet(set);
  1678. spvBuilder.decorateDSetBinding(
  1679. var.getSpirvInstr(), set,
  1680. bindingSet.useNextBinding(set, numBindingsToUse, bindingShift));
  1681. } else if (!reg) {
  1682. // Process m3 (no 'vk::binding' and no ':register' assignment)
  1683. // There is a special case for the $Globals cbuffer. The $Globals buffer
  1684. // doesn't have either 'vk::binding' or ':register', but the user may
  1685. // ask for a specific binding for it via command line options.
  1686. if (bindGlobals && var.isGlobalsBuffer()) {
  1687. uint32_t bindingShift = 0;
  1688. if (bindingShiftMapper)
  1689. bindingShift = bindingShiftMapper->getShiftForSet(globalsSetNo);
  1690. spvBuilder.decorateDSetBinding(var.getSpirvInstr(), globalsSetNo,
  1691. globalsBindNo + bindingShift);
  1692. }
  1693. // The normal case
  1694. else {
  1695. uint32_t bindingShift = 0;
  1696. if (bindingShiftMapper)
  1697. bindingShift = bindingShiftMapper->getShiftForSet(defaultSpace);
  1698. spvBuilder.decorateDSetBinding(
  1699. var.getSpirvInstr(), defaultSpace,
  1700. bindingSet.useNextBinding(defaultSpace, numBindingsToUse,
  1701. bindingShift));
  1702. }
  1703. }
  1704. }
  1705. }
  1706. return true;
  1707. }
  1708. bool DeclResultIdMapper::decorateResourceCoherent() {
  1709. for (const auto &var : resourceVars) {
  1710. if (const auto *decl = var.getDeclaration()) {
  1711. if (decl->getAttr<HLSLGloballyCoherentAttr>()) {
  1712. spvBuilder.decorateCoherent(var.getSpirvInstr(),
  1713. var.getSourceLocation());
  1714. }
  1715. }
  1716. }
  1717. return true;
  1718. }
  1719. bool DeclResultIdMapper::createStageVars(
  1720. const hlsl::SigPoint *sigPoint, const NamedDecl *decl, bool asInput,
  1721. QualType type, uint32_t arraySize, const llvm::StringRef namePrefix,
  1722. llvm::Optional<SpirvInstruction *> invocationId, SpirvInstruction **value,
  1723. bool noWriteBack, SemanticInfo *inheritSemantic) {
  1724. assert(value);
  1725. // invocationId should only be used for handling HS per-vertex output.
  1726. if (invocationId.hasValue()) {
  1727. assert(spvContext.isHS() && arraySize != 0 && !asInput);
  1728. }
  1729. assert(inheritSemantic);
  1730. if (type->isVoidType()) {
  1731. // No stage variables will be created for void type.
  1732. return true;
  1733. }
  1734. // The type the variable is evaluated as for SPIR-V.
  1735. QualType evalType = type;
  1736. // We have several cases regarding HLSL semantics to handle here:
  1737. // * If the currrent decl inherits a semantic from some enclosing entity,
  1738. // use the inherited semantic no matter whether there is a semantic
  1739. // attached to the current decl.
  1740. // * If there is no semantic to inherit,
  1741. // * If the current decl is a struct,
  1742. // * If the current decl has a semantic, all its members inhert this
  1743. // decl's semantic, with the index sequentially increasing;
  1744. // * If the current decl does not have a semantic, all its members
  1745. // should have semantics attached;
  1746. // * If the current decl is not a struct, it should have semantic attached.
  1747. auto thisSemantic = getStageVarSemantic(decl);
  1748. // Which semantic we should use for this decl
  1749. auto *semanticToUse = &thisSemantic;
  1750. // Enclosing semantics override internal ones
  1751. if (inheritSemantic->isValid()) {
  1752. if (thisSemantic.isValid()) {
  1753. emitWarning(
  1754. "internal semantic '%0' overridden by enclosing semantic '%1'",
  1755. thisSemantic.loc)
  1756. << thisSemantic.str << inheritSemantic->str;
  1757. }
  1758. semanticToUse = inheritSemantic;
  1759. }
  1760. const auto loc = decl->getLocation();
  1761. if (semanticToUse->isValid() &&
  1762. // Structs with attached semantics will be handled later.
  1763. !type->isStructureType()) {
  1764. // Found semantic attached directly to this Decl. This means we need to
  1765. // map this decl to a single stage variable.
  1766. if (!validateVKAttributes(decl))
  1767. return false;
  1768. const auto semanticKind = semanticToUse->getKind();
  1769. const auto sigPointKind = sigPoint->GetKind();
  1770. // Error out when the given semantic is invalid in this shader model
  1771. if (hlsl::SigPoint::GetInterpretation(semanticKind, sigPointKind,
  1772. spvContext.getMajorVersion(),
  1773. spvContext.getMinorVersion()) ==
  1774. hlsl::DXIL::SemanticInterpretationKind::NA) {
  1775. // Special handle MSIn/ASIn allowing VK-only builtin "DrawIndex".
  1776. switch (sigPointKind) {
  1777. case hlsl::SigPoint::Kind::MSIn:
  1778. case hlsl::SigPoint::Kind::ASIn:
  1779. if (const auto *builtinAttr = decl->getAttr<VKBuiltInAttr>()) {
  1780. const llvm::StringRef builtin = builtinAttr->getBuiltIn();
  1781. if (builtin == "DrawIndex") {
  1782. break;
  1783. }
  1784. }
  1785. // fall through
  1786. default:
  1787. emitError("invalid usage of semantic '%0' in shader profile %1", loc)
  1788. << semanticToUse->str
  1789. << hlsl::ShaderModel::GetKindName(
  1790. spvContext.getCurrentShaderModelKind());
  1791. return false;
  1792. }
  1793. }
  1794. if (!validateVKBuiltins(decl, sigPoint))
  1795. return false;
  1796. const auto *builtinAttr = decl->getAttr<VKBuiltInAttr>();
  1797. // Special handling of certain mappings between HLSL semantics and
  1798. // SPIR-V builtins:
  1799. // * SV_CullDistance/SV_ClipDistance are outsourced to GlPerVertex.
  1800. // * SV_DomainLocation can refer to a float2, whereas TessCoord is a float3.
  1801. // To ensure SPIR-V validity, we must create a float3 and extract a
  1802. // float2 from it before passing it to the main function.
  1803. // * SV_TessFactor is an array of size 2 for isoline patch, array of size 3
  1804. // for tri patch, and array of size 4 for quad patch, but it must always
  1805. // be an array of size 4 in SPIR-V for Vulkan.
  1806. // * SV_InsideTessFactor is a single float for tri patch, and an array of
  1807. // size 2 for a quad patch, but it must always be an array of size 2 in
  1808. // SPIR-V for Vulkan.
  1809. // * SV_Coverage is an uint value, but the builtin it corresponds to,
  1810. // SampleMask, must be an array of integers.
  1811. // * SV_InnerCoverage is an uint value, but the corresponding builtin,
  1812. // FullyCoveredEXT, must be an boolean value.
  1813. // * SV_DispatchThreadID, SV_GroupThreadID, and SV_GroupID are allowed to be
  1814. // uint, uint2, or uint3, but the corresponding builtins
  1815. // (GlobalInvocationId, LocalInvocationId, WorkgroupId) must be a uint3.
  1816. // * SV_ShadingRate is a uint value, but the builtin it corresponds to is a
  1817. // int2.
  1818. if (glPerVertex.tryToAccess(sigPointKind, semanticKind,
  1819. semanticToUse->index, invocationId, value,
  1820. noWriteBack, /*vecComponent=*/nullptr, loc))
  1821. return true;
  1822. switch (semanticKind) {
  1823. case hlsl::Semantic::Kind::DomainLocation:
  1824. evalType = astContext.getExtVectorType(astContext.FloatTy, 3);
  1825. break;
  1826. case hlsl::Semantic::Kind::TessFactor:
  1827. evalType = astContext.getConstantArrayType(
  1828. astContext.FloatTy, llvm::APInt(32, 4), clang::ArrayType::Normal, 0);
  1829. break;
  1830. case hlsl::Semantic::Kind::InsideTessFactor:
  1831. evalType = astContext.getConstantArrayType(
  1832. astContext.FloatTy, llvm::APInt(32, 2), clang::ArrayType::Normal, 0);
  1833. break;
  1834. case hlsl::Semantic::Kind::Coverage:
  1835. evalType = astContext.getConstantArrayType(astContext.UnsignedIntTy,
  1836. llvm::APInt(32, 1),
  1837. clang::ArrayType::Normal, 0);
  1838. break;
  1839. case hlsl::Semantic::Kind::InnerCoverage:
  1840. if (!type->isSpecificBuiltinType(BuiltinType::UInt)) {
  1841. emitError("SV_InnerCoverage must be of uint type.", loc);
  1842. return false;
  1843. }
  1844. evalType = astContext.BoolTy;
  1845. break;
  1846. case hlsl::Semantic::Kind::Barycentrics:
  1847. evalType = astContext.getExtVectorType(astContext.FloatTy, 2);
  1848. break;
  1849. case hlsl::Semantic::Kind::DispatchThreadID:
  1850. case hlsl::Semantic::Kind::GroupThreadID:
  1851. case hlsl::Semantic::Kind::GroupID:
  1852. // Keep the original integer signedness
  1853. evalType = astContext.getExtVectorType(
  1854. hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecElementType(type) : type,
  1855. 3);
  1856. break;
  1857. case hlsl::Semantic::Kind::ShadingRate:
  1858. evalType = astContext.getExtVectorType(astContext.IntTy, 2);
  1859. break;
  1860. default:
  1861. // Only the semantic kinds mentioned above are handled.
  1862. break;
  1863. }
  1864. // Boolean stage I/O variables must be represented as unsigned integers.
  1865. // Boolean built-in variables are represented as bool.
  1866. if (isBooleanStageIOVar(decl, type, semanticKind, sigPointKind)) {
  1867. evalType = getUintTypeWithSourceComponents(astContext, type);
  1868. }
  1869. // Handle the extra arrayness
  1870. if (arraySize != 0) {
  1871. evalType = astContext.getConstantArrayType(
  1872. evalType, llvm::APInt(32, arraySize), clang::ArrayType::Normal, 0);
  1873. }
  1874. StageVar stageVar(
  1875. sigPoint, *semanticToUse, builtinAttr, evalType,
  1876. // For HS/DS/GS, we have already stripped the outmost arrayness on type.
  1877. getLocationCount(astContext, type));
  1878. const auto name = namePrefix.str() + "." + stageVar.getSemanticStr();
  1879. SpirvVariable *varInstr =
  1880. createSpirvStageVar(&stageVar, decl, name, semanticToUse->loc);
  1881. if (!varInstr)
  1882. return false;
  1883. stageVar.setSpirvInstr(varInstr);
  1884. stageVar.setLocationAttr(decl->getAttr<VKLocationAttr>());
  1885. stageVar.setIndexAttr(decl->getAttr<VKIndexAttr>());
  1886. stageVars.push_back(stageVar);
  1887. // Emit OpDecorate* instructions to link this stage variable with the HLSL
  1888. // semantic it is created for
  1889. spvBuilder.decorateHlslSemantic(varInstr, stageVar.getSemanticStr());
  1890. // We have semantics attached to this decl, which means it must be a
  1891. // function/parameter/variable. All are DeclaratorDecls.
  1892. stageVarInstructions[cast<DeclaratorDecl>(decl)] = varInstr;
  1893. // Special case: The DX12 SV_InstanceID always counts from 0, even if the
  1894. // StartInstanceLocation parameter is non-zero. gl_InstanceIndex, however,
  1895. // starts from firstInstance. Thus it doesn't emulate actual DX12 shader
  1896. // behavior. To make it equivalent, SPIR-V codegen should emit:
  1897. // SV_InstanceID = gl_InstanceIndex - gl_BaseInstance
  1898. // Unfortunately, this means that there is no 1-to-1 mapping of the HLSL
  1899. // semantic to the SPIR-V builtin. As a result, we have to manually create
  1900. // a second stage variable for this specific case.
  1901. //
  1902. // According to the Vulkan spec on builtin variables:
  1903. // www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#interfaces-builtin-variables
  1904. //
  1905. // InstanceIndex:
  1906. // Decorating a variable in a vertex shader with the InstanceIndex
  1907. // built-in decoration will make that variable contain the index of the
  1908. // instance that is being processed by the current vertex shader
  1909. // invocation. InstanceIndex begins at the firstInstance.
  1910. // BaseInstance
  1911. // Decorating a variable with the BaseInstance built-in will make that
  1912. // variable contain the integer value corresponding to the first instance
  1913. // that was passed to the command that invoked the current vertex shader
  1914. // invocation. BaseInstance is the firstInstance parameter to a direct
  1915. // drawing command or the firstInstance member of a structure consumed by
  1916. // an indirect drawing command.
  1917. if (spirvOptions.supportNonzeroBaseInstance && asInput &&
  1918. semanticKind == hlsl::Semantic::Kind::InstanceID &&
  1919. sigPointKind == hlsl::SigPoint::Kind::VSIn) {
  1920. // The above call to createSpirvStageVar creates the gl_InstanceIndex.
  1921. // We should now manually create the gl_BaseInstance variable and do the
  1922. // subtraction.
  1923. auto *instanceIndexVar = varInstr;
  1924. auto *baseInstanceVar = spvBuilder.addStageBuiltinVar(
  1925. type, spv::StorageClass::Input, spv::BuiltIn::BaseInstance,
  1926. decl->hasAttr<HLSLPreciseAttr>(), semanticToUse->loc);
  1927. StageVar stageVar2(sigPoint, *semanticToUse, builtinAttr, evalType,
  1928. getLocationCount(astContext, type));
  1929. stageVar2.setSpirvInstr(baseInstanceVar);
  1930. stageVar2.setLocationAttr(decl->getAttr<VKLocationAttr>());
  1931. stageVar2.setIndexAttr(decl->getAttr<VKIndexAttr>());
  1932. stageVar2.setIsSpirvBuiltin();
  1933. stageVars.push_back(stageVar2);
  1934. // SPIR-V code fore 'SV_InstanceID = gl_InstanceIndex - gl_BaseInstance'
  1935. auto *instanceIdVar =
  1936. spvBuilder.addFnVar(type, semanticToUse->loc, "SV_InstanceID");
  1937. auto *instanceIndexValue =
  1938. spvBuilder.createLoad(type, instanceIndexVar, semanticToUse->loc);
  1939. auto *baseInstanceValue =
  1940. spvBuilder.createLoad(type, baseInstanceVar, semanticToUse->loc);
  1941. auto *instanceIdValue =
  1942. spvBuilder.createBinaryOp(spv::Op::OpISub, type, instanceIndexValue,
  1943. baseInstanceValue, semanticToUse->loc);
  1944. spvBuilder.createStore(instanceIdVar, instanceIdValue,
  1945. semanticToUse->loc);
  1946. stageVarInstructions[cast<DeclaratorDecl>(decl)] = instanceIdVar;
  1947. varInstr = instanceIdVar;
  1948. }
  1949. // Mark that we have used one index for this semantic
  1950. ++semanticToUse->index;
  1951. // TODO: the following may not be correct?
  1952. if (sigPoint->GetSignatureKind() ==
  1953. hlsl::DXIL::SignatureKind::PatchConstOrPrim) {
  1954. if (sigPointKind == hlsl::SigPoint::Kind::MSPOut) {
  1955. // Decorate with PerPrimitiveNV for per-primitive out variables.
  1956. spvBuilder.decoratePerPrimitiveNV(varInstr,
  1957. varInstr->getSourceLocation());
  1958. } else {
  1959. spvBuilder.decoratePatch(varInstr, varInstr->getSourceLocation());
  1960. }
  1961. }
  1962. // Decorate with interpolation modes for pixel shader input variables
  1963. // or vertex shader output variables.
  1964. if (((spvContext.isPS() && sigPoint->IsInput()) ||
  1965. (spvContext.isVS() && sigPoint->IsOutput())) &&
  1966. // BaryCoord*AMD buitins already encode the interpolation mode.
  1967. semanticKind != hlsl::Semantic::Kind::Barycentrics)
  1968. decorateInterpolationMode(decl, type, varInstr);
  1969. if (asInput) {
  1970. *value = spvBuilder.createLoad(evalType, varInstr, loc);
  1971. // Fix ups for corner cases
  1972. // Special handling of SV_TessFactor DS patch constant input.
  1973. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  1974. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  1975. // relevant indexes must be loaded.
  1976. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  1977. hlsl::GetArraySize(type) != 4) {
  1978. llvm::SmallVector<SpirvInstruction *, 4> components;
  1979. const auto tessFactorSize = hlsl::GetArraySize(type);
  1980. const auto arrType = astContext.getConstantArrayType(
  1981. astContext.FloatTy, llvm::APInt(32, tessFactorSize),
  1982. clang::ArrayType::Normal, 0);
  1983. for (uint32_t i = 0; i < tessFactorSize; ++i)
  1984. components.push_back(spvBuilder.createCompositeExtract(
  1985. astContext.FloatTy, *value, {i}, thisSemantic.loc));
  1986. *value = spvBuilder.createCompositeConstruct(arrType, components,
  1987. thisSemantic.loc);
  1988. }
  1989. // Special handling of SV_InsideTessFactor DS patch constant input.
  1990. // TessLevelInner is always an array of size 2 in SPIR-V, but
  1991. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  1992. // HLSL. If SV_InsideTessFactor is a scalar, only extract index 0 of
  1993. // TessLevelInner.
  1994. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  1995. // Some developers use float[1] instead of a scalar float.
  1996. (!type->isArrayType() || hlsl::GetArraySize(type) == 1)) {
  1997. *value = spvBuilder.createCompositeExtract(astContext.FloatTy, *value,
  1998. {0}, thisSemantic.loc);
  1999. if (type->isArrayType()) { // float[1]
  2000. const auto arrType = astContext.getConstantArrayType(
  2001. astContext.FloatTy, llvm::APInt(32, 1), clang::ArrayType::Normal,
  2002. 0);
  2003. *value = spvBuilder.createCompositeConstruct(arrType, {*value},
  2004. thisSemantic.loc);
  2005. }
  2006. }
  2007. // SV_DomainLocation can refer to a float2 or a float3, whereas TessCoord
  2008. // is always a float3. To ensure SPIR-V validity, a float3 stage variable
  2009. // is created, and we must extract a float2 from it before passing it to
  2010. // the main function.
  2011. else if (semanticKind == hlsl::Semantic::Kind::DomainLocation &&
  2012. hlsl::GetHLSLVecSize(type) != 3) {
  2013. const auto domainLocSize = hlsl::GetHLSLVecSize(type);
  2014. *value = spvBuilder.createVectorShuffle(
  2015. astContext.getExtVectorType(astContext.FloatTy, domainLocSize),
  2016. *value, *value, {0, 1}, thisSemantic.loc);
  2017. }
  2018. // Special handling of SV_Coverage, which is an uint value. We need to
  2019. // read SampleMask and extract its first element.
  2020. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  2021. *value = spvBuilder.createCompositeExtract(type, *value, {0},
  2022. thisSemantic.loc);
  2023. }
  2024. // Special handling of SV_InnerCoverage, which is an uint value. We need
  2025. // to read FullyCoveredEXT, which is a boolean value, and convert it to an
  2026. // uint value. According to D3D12 "Conservative Rasterization" doc: "The
  2027. // Pixel Shader has a 32-bit scalar integer System Generate Value
  2028. // available: InnerCoverage. This is a bit-field that has bit 0 from the
  2029. // LSB set to 1 for a given conservatively rasterized pixel, only when
  2030. // that pixel is guaranteed to be entirely inside the current primitive.
  2031. // All other input register bits must be set to 0 when bit 0 is not set,
  2032. // but are undefined when bit 0 is set to 1 (essentially, this bit-field
  2033. // represents a Boolean value where false must be exactly 0, but true can
  2034. // be any odd (i.e. bit 0 set) non-zero value)."
  2035. else if (semanticKind == hlsl::Semantic::Kind::InnerCoverage) {
  2036. const auto constOne = spvBuilder.getConstantInt(
  2037. astContext.UnsignedIntTy, llvm::APInt(32, 1));
  2038. const auto constZero = spvBuilder.getConstantInt(
  2039. astContext.UnsignedIntTy, llvm::APInt(32, 0));
  2040. *value = spvBuilder.createSelect(astContext.UnsignedIntTy, *value,
  2041. constOne, constZero, thisSemantic.loc);
  2042. }
  2043. // Special handling of SV_Barycentrics, which is a float3, but the
  2044. // underlying stage input variable is a float2 (only provides the first
  2045. // two components). Calculate the third element.
  2046. else if (semanticKind == hlsl::Semantic::Kind::Barycentrics) {
  2047. const auto x = spvBuilder.createCompositeExtract(
  2048. astContext.FloatTy, *value, {0}, thisSemantic.loc);
  2049. const auto y = spvBuilder.createCompositeExtract(
  2050. astContext.FloatTy, *value, {1}, thisSemantic.loc);
  2051. const auto xy = spvBuilder.createBinaryOp(
  2052. spv::Op::OpFAdd, astContext.FloatTy, x, y, thisSemantic.loc);
  2053. const auto z = spvBuilder.createBinaryOp(
  2054. spv::Op::OpFSub, astContext.FloatTy,
  2055. spvBuilder.getConstantFloat(astContext.FloatTy,
  2056. llvm::APFloat(1.0f)),
  2057. xy, thisSemantic.loc);
  2058. *value = spvBuilder.createCompositeConstruct(
  2059. astContext.getExtVectorType(astContext.FloatTy, 3), {x, y, z},
  2060. thisSemantic.loc);
  2061. }
  2062. // Special handling of SV_DispatchThreadID and SV_GroupThreadID, which may
  2063. // be a uint or uint2, but the underlying stage input variable is a uint3.
  2064. // The last component(s) should be discarded in needed.
  2065. else if ((semanticKind == hlsl::Semantic::Kind::DispatchThreadID ||
  2066. semanticKind == hlsl::Semantic::Kind::GroupThreadID ||
  2067. semanticKind == hlsl::Semantic::Kind::GroupID) &&
  2068. (!hlsl::IsHLSLVecType(type) ||
  2069. hlsl::GetHLSLVecSize(type) != 3)) {
  2070. const auto srcVecElemType = hlsl::IsHLSLVecType(type)
  2071. ? hlsl::GetHLSLVecElementType(type)
  2072. : type;
  2073. const auto vecSize =
  2074. hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecSize(type) : 1;
  2075. if (vecSize == 1)
  2076. *value = spvBuilder.createCompositeExtract(srcVecElemType, *value,
  2077. {0}, thisSemantic.loc);
  2078. else if (vecSize == 2)
  2079. *value = spvBuilder.createVectorShuffle(
  2080. astContext.getExtVectorType(srcVecElemType, 2), *value, *value,
  2081. {0, 1}, thisSemantic.loc);
  2082. }
  2083. // Special handling of SV_ShadingRate, which is a bitpacked enum value,
  2084. // but SPIR-V's FragSizeEXT uses an int2. We build the enum value from
  2085. // the separate axis values.
  2086. else if (semanticKind == hlsl::Semantic::Kind::ShadingRate) {
  2087. // From the D3D12 functional spec for Variable-Rate Shading.
  2088. // #define D3D12_MAKE_COARSE_SHADING_RATE(x,y) ((x) << 2 | (y))
  2089. const auto x = spvBuilder.createCompositeExtract(
  2090. astContext.IntTy, *value, {0}, thisSemantic.loc);
  2091. const auto y = spvBuilder.createCompositeExtract(
  2092. astContext.IntTy, *value, {1}, thisSemantic.loc);
  2093. const auto constTwo =
  2094. spvBuilder.getConstantInt(astContext.IntTy, llvm::APInt(32, 2));
  2095. *value = spvBuilder.createBinaryOp(
  2096. spv::Op::OpBitwiseOr, astContext.UnsignedIntTy,
  2097. spvBuilder.createBinaryOp(spv::Op::OpShiftLeftLogical,
  2098. astContext.IntTy, x, constTwo,
  2099. thisSemantic.loc),
  2100. y, thisSemantic.loc);
  2101. }
  2102. // Reciprocate SV_Position.w if requested
  2103. if (semanticKind == hlsl::Semantic::Kind::Position)
  2104. *value = invertWIfRequested(*value, thisSemantic.loc);
  2105. // Since boolean stage input variables are represented as unsigned
  2106. // integers, after loading them, we should cast them to boolean.
  2107. if (isBooleanStageIOVar(decl, type, semanticKind, sigPointKind)) {
  2108. *value =
  2109. theEmitter.castToType(*value, evalType, type, thisSemantic.loc);
  2110. }
  2111. } else {
  2112. if (noWriteBack)
  2113. return true;
  2114. // Negate SV_Position.y if requested
  2115. if (semanticKind == hlsl::Semantic::Kind::Position)
  2116. *value = invertYIfRequested(*value, thisSemantic.loc);
  2117. SpirvInstruction *ptr = varInstr;
  2118. // Special handling of SV_TessFactor HS patch constant output.
  2119. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  2120. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  2121. // relevant indexes must be written to.
  2122. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  2123. hlsl::GetArraySize(type) != 4) {
  2124. const auto tessFactorSize = hlsl::GetArraySize(type);
  2125. for (uint32_t i = 0; i < tessFactorSize; ++i) {
  2126. ptr = spvBuilder.createAccessChain(
  2127. astContext.FloatTy, varInstr,
  2128. {spvBuilder.getConstantInt(astContext.UnsignedIntTy,
  2129. llvm::APInt(32, i))},
  2130. thisSemantic.loc);
  2131. spvBuilder.createStore(
  2132. ptr,
  2133. spvBuilder.createCompositeExtract(astContext.FloatTy, *value, {i},
  2134. thisSemantic.loc),
  2135. thisSemantic.loc);
  2136. }
  2137. }
  2138. // Special handling of SV_InsideTessFactor HS patch constant output.
  2139. // TessLevelInner is always an array of size 2 in SPIR-V, but
  2140. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  2141. // HLSL. If SV_InsideTessFactor is a scalar, only write to index 0 of
  2142. // TessLevelInner.
  2143. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  2144. // Some developers use float[1] instead of a scalar float.
  2145. (!type->isArrayType() || hlsl::GetArraySize(type) == 1)) {
  2146. ptr = spvBuilder.createAccessChain(
  2147. astContext.FloatTy, varInstr,
  2148. spvBuilder.getConstantInt(astContext.UnsignedIntTy,
  2149. llvm::APInt(32, 0)),
  2150. thisSemantic.loc);
  2151. if (type->isArrayType()) // float[1]
  2152. *value = spvBuilder.createCompositeExtract(astContext.FloatTy, *value,
  2153. {0}, thisSemantic.loc);
  2154. spvBuilder.createStore(ptr, *value, thisSemantic.loc);
  2155. }
  2156. // Special handling of SV_Coverage, which is an unit value. We need to
  2157. // write it to the first element in the SampleMask builtin.
  2158. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  2159. ptr = spvBuilder.createAccessChain(
  2160. type, varInstr,
  2161. spvBuilder.getConstantInt(astContext.UnsignedIntTy,
  2162. llvm::APInt(32, 0)),
  2163. thisSemantic.loc);
  2164. ptr->setStorageClass(spv::StorageClass::Output);
  2165. spvBuilder.createStore(ptr, *value, thisSemantic.loc);
  2166. }
  2167. // Special handling of HS ouput, for which we write to only one
  2168. // element in the per-vertex data array: the one indexed by
  2169. // SV_ControlPointID.
  2170. else if (invocationId.hasValue() && invocationId.getValue() != nullptr) {
  2171. // Remove the arrayness to get the element type.
  2172. assert(isa<ConstantArrayType>(evalType));
  2173. const auto elementType =
  2174. astContext.getAsArrayType(evalType)->getElementType();
  2175. auto index = invocationId.getValue();
  2176. ptr = spvBuilder.createAccessChain(elementType, varInstr, index,
  2177. thisSemantic.loc);
  2178. ptr->setStorageClass(spv::StorageClass::Output);
  2179. spvBuilder.createStore(ptr, *value, thisSemantic.loc);
  2180. }
  2181. // Since boolean output stage variables are represented as unsigned
  2182. // integers, we must cast the value to uint before storing.
  2183. else if (isBooleanStageIOVar(decl, type, semanticKind, sigPointKind)) {
  2184. *value =
  2185. theEmitter.castToType(*value, type, evalType, thisSemantic.loc);
  2186. spvBuilder.createStore(ptr, *value, thisSemantic.loc);
  2187. }
  2188. // For all normal cases
  2189. else {
  2190. spvBuilder.createStore(ptr, *value, thisSemantic.loc);
  2191. }
  2192. }
  2193. return true;
  2194. }
  2195. // If the decl itself doesn't have semantic string attached and there is no
  2196. // one to inherit, it should be a struct having all its fields with semantic
  2197. // strings.
  2198. if (!semanticToUse->isValid() && !type->isStructureType()) {
  2199. emitError("semantic string missing for shader %select{output|input}0 "
  2200. "variable '%1'",
  2201. loc)
  2202. << asInput << decl->getName();
  2203. return false;
  2204. }
  2205. const auto *structDecl = type->getAs<RecordType>()->getDecl();
  2206. if (asInput) {
  2207. // If this decl translates into multiple stage input variables, we need to
  2208. // load their values into a composite.
  2209. llvm::SmallVector<SpirvInstruction *, 4> subValues;
  2210. // If we have base classes, we need to handle them first.
  2211. if (const auto *cxxDecl = type->getAsCXXRecordDecl()) {
  2212. for (auto base : cxxDecl->bases()) {
  2213. SpirvInstruction *subValue = nullptr;
  2214. if (!createStageVars(sigPoint, base.getType()->getAsCXXRecordDecl(),
  2215. asInput, base.getType(), arraySize, namePrefix,
  2216. invocationId, &subValue, noWriteBack,
  2217. semanticToUse))
  2218. return false;
  2219. subValues.push_back(subValue);
  2220. }
  2221. }
  2222. for (const auto *field : structDecl->fields()) {
  2223. SpirvInstruction *subValue = nullptr;
  2224. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  2225. arraySize, namePrefix, invocationId, &subValue,
  2226. noWriteBack, semanticToUse))
  2227. return false;
  2228. subValues.push_back(subValue);
  2229. }
  2230. if (arraySize == 0) {
  2231. *value = spvBuilder.createCompositeConstruct(evalType, subValues, loc);
  2232. return true;
  2233. }
  2234. // Handle the extra level of arrayness.
  2235. // We need to return an array of structs. But we get arrays of fields
  2236. // from visiting all fields. So now we need to extract all the elements
  2237. // at the same index of each field arrays and compose a new struct out
  2238. // of them.
  2239. const auto structType = type;
  2240. const auto arrayType = astContext.getConstantArrayType(
  2241. structType, llvm::APInt(32, arraySize), clang::ArrayType::Normal, 0);
  2242. llvm::SmallVector<SpirvInstruction *, 16> arrayElements;
  2243. for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) {
  2244. llvm::SmallVector<SpirvInstruction *, 8> fields;
  2245. // If we have base classes, we need to handle them first.
  2246. if (const auto *cxxDecl = type->getAsCXXRecordDecl()) {
  2247. uint32_t baseIndex = 0;
  2248. for (auto base : cxxDecl->bases()) {
  2249. const auto baseType = base.getType();
  2250. fields.push_back(spvBuilder.createCompositeExtract(
  2251. baseType, subValues[baseIndex++], {arrayIndex}, loc));
  2252. }
  2253. }
  2254. // Extract the element at index arrayIndex from each field
  2255. for (const auto *field : structDecl->fields()) {
  2256. const auto fieldType = field->getType();
  2257. fields.push_back(spvBuilder.createCompositeExtract(
  2258. fieldType,
  2259. subValues[getNumBaseClasses(type) + field->getFieldIndex()],
  2260. {arrayIndex}, loc));
  2261. }
  2262. // Compose a new struct out of them
  2263. arrayElements.push_back(
  2264. spvBuilder.createCompositeConstruct(structType, fields, loc));
  2265. }
  2266. *value = spvBuilder.createCompositeConstruct(arrayType, arrayElements, loc);
  2267. } else {
  2268. // If we have base classes, we need to handle them first.
  2269. if (const auto *cxxDecl = type->getAsCXXRecordDecl()) {
  2270. uint32_t baseIndex = 0;
  2271. for (auto base : cxxDecl->bases()) {
  2272. SpirvInstruction *subValue = nullptr;
  2273. if (!noWriteBack)
  2274. subValue = spvBuilder.createCompositeExtract(base.getType(), *value,
  2275. {baseIndex++}, loc);
  2276. if (!createStageVars(sigPoint, base.getType()->getAsCXXRecordDecl(),
  2277. asInput, base.getType(), arraySize, namePrefix,
  2278. invocationId, &subValue, noWriteBack,
  2279. semanticToUse))
  2280. return false;
  2281. }
  2282. }
  2283. // Unlike reading, which may require us to read stand-alone builtins and
  2284. // stage input variables and compose an array of structs out of them,
  2285. // it happens that we don't need to write an array of structs in a bunch
  2286. // for all shader stages:
  2287. //
  2288. // * VS: output is a single struct, without extra arrayness
  2289. // * HS: output is an array of structs, with extra arrayness,
  2290. // but we only write to the struct at the InvocationID index
  2291. // * DS: output is a single struct, without extra arrayness
  2292. // * GS: output is controlled by OpEmitVertex, one vertex per time
  2293. // * MS: output is an array of structs, with extra arrayness
  2294. //
  2295. // The interesting shader stage is HS. We need the InvocationID to write
  2296. // out the value to the correct array element.
  2297. for (const auto *field : structDecl->fields()) {
  2298. const auto fieldType = field->getType();
  2299. SpirvInstruction *subValue = nullptr;
  2300. if (!noWriteBack)
  2301. subValue = spvBuilder.createCompositeExtract(
  2302. fieldType, *value,
  2303. {getNumBaseClasses(type) + field->getFieldIndex()}, loc);
  2304. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  2305. arraySize, namePrefix, invocationId, &subValue,
  2306. noWriteBack, semanticToUse))
  2307. return false;
  2308. }
  2309. }
  2310. return true;
  2311. }
  2312. bool DeclResultIdMapper::createPayloadStageVars(
  2313. const hlsl::SigPoint *sigPoint, spv::StorageClass sc, const NamedDecl *decl,
  2314. bool asInput, QualType type, const llvm::StringRef namePrefix,
  2315. SpirvInstruction **value, uint32_t payloadMemOffset) {
  2316. assert(spvContext.isMS() || spvContext.isAS());
  2317. assert(value);
  2318. if (type->isVoidType()) {
  2319. // No stage variables will be created for void type.
  2320. return true;
  2321. }
  2322. const auto loc = decl->getLocation();
  2323. if (!type->isStructureType()) {
  2324. StageVar stageVar(sigPoint, /*semaInfo=*/{}, /*builtinAttr=*/nullptr, type,
  2325. getLocationCount(astContext, type));
  2326. const auto name = namePrefix.str() + "." + decl->getNameAsString();
  2327. SpirvVariable *varInstr =
  2328. spvBuilder.addStageIOVar(type, sc, name, /*isPrecise=*/false, loc);
  2329. if (!varInstr)
  2330. return false;
  2331. // Even though these as user defined IO stage variables, set them as SPIR-V
  2332. // builtins in order to bypass any semantic string checks and location
  2333. // assignment.
  2334. stageVar.setIsSpirvBuiltin();
  2335. stageVar.setSpirvInstr(varInstr);
  2336. stageVars.push_back(stageVar);
  2337. // Decorate with PerTaskNV for mesh/amplification shader payload variables.
  2338. spvBuilder.decoratePerTaskNV(varInstr, payloadMemOffset,
  2339. varInstr->getSourceLocation());
  2340. if (asInput) {
  2341. *value = spvBuilder.createLoad(type, varInstr, loc);
  2342. } else {
  2343. spvBuilder.createStore(varInstr, *value, loc);
  2344. }
  2345. return true;
  2346. }
  2347. // This decl translates into multiple stage input/output payload variables
  2348. // and we need to load/store these individual member variables.
  2349. const auto *structDecl = type->getAs<RecordType>()->getDecl();
  2350. llvm::SmallVector<SpirvInstruction *, 4> subValues;
  2351. AlignmentSizeCalculator alignmentCalc(astContext, spirvOptions);
  2352. uint32_t nextMemberOffset = 0;
  2353. for (const auto *field : structDecl->fields()) {
  2354. const auto fieldType = field->getType();
  2355. SpirvInstruction *subValue = nullptr;
  2356. uint32_t memberAlignment = 0, memberSize = 0, stride = 0;
  2357. // The next avaiable offset after laying out the previous members.
  2358. std::tie(memberAlignment, memberSize) = alignmentCalc.getAlignmentAndSize(
  2359. field->getType(), spirvOptions.ampPayloadLayoutRule,
  2360. /*isRowMajor*/ llvm::None, &stride);
  2361. alignmentCalc.alignUsingHLSLRelaxedLayout(
  2362. field->getType(), memberSize, memberAlignment, &nextMemberOffset);
  2363. // The vk::offset attribute takes precedence over all.
  2364. if (field->getAttr<VKOffsetAttr>()) {
  2365. nextMemberOffset = field->getAttr<VKOffsetAttr>()->getOffset();
  2366. }
  2367. // Each payload member must have an Offset Decoration.
  2368. payloadMemOffset = nextMemberOffset;
  2369. nextMemberOffset += memberSize;
  2370. if (!asInput) {
  2371. subValue = spvBuilder.createCompositeExtract(
  2372. fieldType, *value, {getNumBaseClasses(type) + field->getFieldIndex()},
  2373. loc);
  2374. }
  2375. if (!createPayloadStageVars(sigPoint, sc, field, asInput, field->getType(),
  2376. namePrefix, &subValue, payloadMemOffset))
  2377. return false;
  2378. if (asInput) {
  2379. subValues.push_back(subValue);
  2380. }
  2381. }
  2382. if (asInput) {
  2383. *value = spvBuilder.createCompositeConstruct(type, subValues, loc);
  2384. }
  2385. return true;
  2386. }
  2387. bool DeclResultIdMapper::writeBackOutputStream(const NamedDecl *decl,
  2388. QualType type,
  2389. SpirvInstruction *value) {
  2390. assert(spvContext.isGS()); // Only for GS use
  2391. if (hlsl::IsHLSLStreamOutputType(type))
  2392. type = hlsl::GetHLSLResourceResultType(type);
  2393. if (hasGSPrimitiveTypeQualifier(decl))
  2394. type = astContext.getAsConstantArrayType(type)->getElementType();
  2395. auto semanticInfo = getStageVarSemantic(decl);
  2396. const auto loc = decl->getLocation();
  2397. if (semanticInfo.isValid()) {
  2398. // Found semantic attached directly to this Decl. Write the value for this
  2399. // Decl to the corresponding stage output variable.
  2400. // Handle SV_ClipDistance, and SV_CullDistance
  2401. if (glPerVertex.tryToAccess(
  2402. hlsl::DXIL::SigPointKind::GSOut, semanticInfo.semantic->GetKind(),
  2403. semanticInfo.index, llvm::None, &value,
  2404. /*noWriteBack=*/false, /*vecComponent=*/nullptr, loc))
  2405. return true;
  2406. // Query the <result-id> for the stage output variable generated out
  2407. // of this decl.
  2408. // We have semantic string attached to this decl; therefore, it must be a
  2409. // DeclaratorDecl.
  2410. const auto found = stageVarInstructions.find(cast<DeclaratorDecl>(decl));
  2411. // We should have recorded its stage output variable previously.
  2412. assert(found != stageVarInstructions.end());
  2413. // Negate SV_Position.y if requested
  2414. if (semanticInfo.semantic->GetKind() == hlsl::Semantic::Kind::Position)
  2415. value = invertYIfRequested(value, loc);
  2416. // Boolean stage output variables are represented as unsigned integers.
  2417. if (isBooleanStageIOVar(decl, type, semanticInfo.semantic->GetKind(),
  2418. hlsl::SigPoint::Kind::GSOut)) {
  2419. QualType uintType = getUintTypeWithSourceComponents(astContext, type);
  2420. value = theEmitter.castToType(value, type, uintType, loc);
  2421. }
  2422. spvBuilder.createStore(found->second, value, loc);
  2423. return true;
  2424. }
  2425. // If the decl itself doesn't have semantic string attached, it should be
  2426. // a struct having all its fields with semantic strings.
  2427. if (!type->isStructureType()) {
  2428. emitError("semantic string missing for shader output variable '%0'", loc)
  2429. << decl->getName();
  2430. return false;
  2431. }
  2432. // If we have base classes, we need to handle them first.
  2433. if (const auto *cxxDecl = type->getAsCXXRecordDecl()) {
  2434. uint32_t baseIndex = 0;
  2435. for (auto base : cxxDecl->bases()) {
  2436. auto *subValue = spvBuilder.createCompositeExtract(base.getType(), value,
  2437. {baseIndex++}, loc);
  2438. if (!writeBackOutputStream(base.getType()->getAsCXXRecordDecl(),
  2439. base.getType(), subValue))
  2440. return false;
  2441. }
  2442. }
  2443. const auto *structDecl = type->getAs<RecordType>()->getDecl();
  2444. // Write out each field
  2445. for (const auto *field : structDecl->fields()) {
  2446. const auto fieldType = field->getType();
  2447. auto *subValue = spvBuilder.createCompositeExtract(
  2448. fieldType, value, {getNumBaseClasses(type) + field->getFieldIndex()},
  2449. loc);
  2450. if (!writeBackOutputStream(field, field->getType(), subValue))
  2451. return false;
  2452. }
  2453. return true;
  2454. }
  2455. SpirvInstruction *
  2456. DeclResultIdMapper::invertYIfRequested(SpirvInstruction *position,
  2457. SourceLocation loc) {
  2458. // Negate SV_Position.y if requested
  2459. if (spirvOptions.invertY) {
  2460. const auto oldY = spvBuilder.createCompositeExtract(astContext.FloatTy,
  2461. position, {1}, loc);
  2462. const auto newY = spvBuilder.createUnaryOp(spv::Op::OpFNegate,
  2463. astContext.FloatTy, oldY, loc);
  2464. position = spvBuilder.createCompositeInsert(
  2465. astContext.getExtVectorType(astContext.FloatTy, 4), position, {1}, newY,
  2466. loc);
  2467. }
  2468. return position;
  2469. }
  2470. SpirvInstruction *
  2471. DeclResultIdMapper::invertWIfRequested(SpirvInstruction *position,
  2472. SourceLocation loc) {
  2473. // Reciprocate SV_Position.w if requested
  2474. if (spirvOptions.invertW && spvContext.isPS()) {
  2475. const auto oldW = spvBuilder.createCompositeExtract(astContext.FloatTy,
  2476. position, {3}, loc);
  2477. const auto newW = spvBuilder.createBinaryOp(
  2478. spv::Op::OpFDiv, astContext.FloatTy,
  2479. spvBuilder.getConstantFloat(astContext.FloatTy, llvm::APFloat(1.0f)),
  2480. oldW, loc);
  2481. position = spvBuilder.createCompositeInsert(
  2482. astContext.getExtVectorType(astContext.FloatTy, 4), position, {3}, newW,
  2483. loc);
  2484. }
  2485. return position;
  2486. }
  2487. void DeclResultIdMapper::decorateInterpolationMode(const NamedDecl *decl,
  2488. QualType type,
  2489. SpirvVariable *varInstr) {
  2490. const auto loc = decl->getLocation();
  2491. if (isUintOrVecMatOfUintType(type) || isSintOrVecMatOfSintType(type) ||
  2492. isBoolOrVecMatOfBoolType(type)) {
  2493. // TODO: Probably we can call hlsl::ValidateSignatureElement() for the
  2494. // following check.
  2495. if (decl->getAttr<HLSLLinearAttr>() || decl->getAttr<HLSLCentroidAttr>() ||
  2496. decl->getAttr<HLSLNoPerspectiveAttr>() ||
  2497. decl->getAttr<HLSLSampleAttr>()) {
  2498. emitError("only nointerpolation mode allowed for integer input "
  2499. "parameters in pixel shader or integer output in vertex shader",
  2500. decl->getLocation());
  2501. } else {
  2502. spvBuilder.decorateFlat(varInstr, loc);
  2503. }
  2504. } else {
  2505. // Do nothing for HLSLLinearAttr since its the default
  2506. // Attributes can be used together. So cannot use else if.
  2507. if (decl->getAttr<HLSLCentroidAttr>())
  2508. spvBuilder.decorateCentroid(varInstr, loc);
  2509. if (decl->getAttr<HLSLNoInterpolationAttr>())
  2510. spvBuilder.decorateFlat(varInstr, loc);
  2511. if (decl->getAttr<HLSLNoPerspectiveAttr>())
  2512. spvBuilder.decorateNoPerspective(varInstr, loc);
  2513. if (decl->getAttr<HLSLSampleAttr>()) {
  2514. spvBuilder.decorateSample(varInstr, loc);
  2515. }
  2516. }
  2517. }
  2518. SpirvVariable *DeclResultIdMapper::getBuiltinVar(spv::BuiltIn builtIn,
  2519. QualType type,
  2520. SourceLocation loc) {
  2521. // Guarantee uniqueness
  2522. uint32_t spvBuiltinId = static_cast<uint32_t>(builtIn);
  2523. const auto builtInVar = builtinToVarMap.find(spvBuiltinId);
  2524. if (builtInVar != builtinToVarMap.end()) {
  2525. return builtInVar->second;
  2526. }
  2527. spv::StorageClass sc = spv::StorageClass::Max;
  2528. // Valid builtins supported
  2529. switch (builtIn) {
  2530. case spv::BuiltIn::SubgroupSize:
  2531. case spv::BuiltIn::SubgroupLocalInvocationId:
  2532. case spv::BuiltIn::HitTNV:
  2533. case spv::BuiltIn::RayTmaxNV:
  2534. case spv::BuiltIn::RayTminNV:
  2535. case spv::BuiltIn::HitKindNV:
  2536. case spv::BuiltIn::IncomingRayFlagsNV:
  2537. case spv::BuiltIn::InstanceCustomIndexNV:
  2538. case spv::BuiltIn::RayGeometryIndexKHR:
  2539. case spv::BuiltIn::PrimitiveId:
  2540. case spv::BuiltIn::InstanceId:
  2541. case spv::BuiltIn::WorldRayDirectionNV:
  2542. case spv::BuiltIn::WorldRayOriginNV:
  2543. case spv::BuiltIn::ObjectRayDirectionNV:
  2544. case spv::BuiltIn::ObjectRayOriginNV:
  2545. case spv::BuiltIn::ObjectToWorldNV:
  2546. case spv::BuiltIn::WorldToObjectNV:
  2547. case spv::BuiltIn::LaunchIdNV:
  2548. case spv::BuiltIn::LaunchSizeNV:
  2549. case spv::BuiltIn::GlobalInvocationId:
  2550. case spv::BuiltIn::WorkgroupId:
  2551. case spv::BuiltIn::LocalInvocationIndex:
  2552. sc = spv::StorageClass::Input;
  2553. break;
  2554. case spv::BuiltIn::PrimitiveCountNV:
  2555. case spv::BuiltIn::PrimitiveIndicesNV:
  2556. case spv::BuiltIn::TaskCountNV:
  2557. sc = spv::StorageClass::Output;
  2558. break;
  2559. default:
  2560. assert(false && "unsupported SPIR-V builtin");
  2561. return nullptr;
  2562. }
  2563. // Create a dummy StageVar for this builtin variable
  2564. auto var = spvBuilder.addStageBuiltinVar(type, sc, builtIn,
  2565. /*isPrecise*/ false, loc);
  2566. const hlsl::SigPoint *sigPoint =
  2567. hlsl::SigPoint::GetSigPoint(hlsl::SigPointFromInputQual(
  2568. hlsl::DxilParamInputQual::In, spvContext.getCurrentShaderModelKind(),
  2569. /*isPatchConstant=*/false));
  2570. StageVar stageVar(sigPoint, /*semaInfo=*/{}, /*builtinAttr=*/nullptr, type,
  2571. /*locCount=*/0);
  2572. stageVar.setIsSpirvBuiltin();
  2573. stageVar.setSpirvInstr(var);
  2574. stageVars.push_back(stageVar);
  2575. // Store in map for re-use
  2576. builtinToVarMap[spvBuiltinId] = var;
  2577. return var;
  2578. }
  2579. SpirvVariable *DeclResultIdMapper::createSpirvIntermediateOutputStageVar(
  2580. const NamedDecl *decl, const llvm::StringRef name, QualType type) {
  2581. const auto *semantic = hlsl::Semantic::GetByName(name);
  2582. SemanticInfo thisSemantic{name, semantic, name, 0, decl->getLocation()};
  2583. const auto *sigPoint =
  2584. deduceSigPoint(cast<DeclaratorDecl>(decl), /*asInput=*/false,
  2585. spvContext.getCurrentShaderModelKind(), /*forPCF=*/false);
  2586. StageVar stageVar(sigPoint, thisSemantic, decl->getAttr<VKBuiltInAttr>(),
  2587. type, /*locCount=*/1);
  2588. SpirvVariable *varInstr =
  2589. createSpirvStageVar(&stageVar, decl, name, thisSemantic.loc);
  2590. if (!varInstr)
  2591. return nullptr;
  2592. stageVar.setSpirvInstr(varInstr);
  2593. stageVar.setLocationAttr(decl->getAttr<VKLocationAttr>());
  2594. stageVar.setIndexAttr(decl->getAttr<VKIndexAttr>());
  2595. stageVars.push_back(stageVar);
  2596. // Emit OpDecorate* instructions to link this stage variable with the HLSL
  2597. // semantic it is created for.
  2598. spvBuilder.decorateHlslSemantic(varInstr, stageVar.getSemanticStr());
  2599. // We have semantics attached to this decl, which means it must be a
  2600. // function/parameter/variable. All are DeclaratorDecls.
  2601. stageVarInstructions[cast<DeclaratorDecl>(decl)] = varInstr;
  2602. return varInstr;
  2603. }
  2604. SpirvVariable *DeclResultIdMapper::createSpirvStageVar(
  2605. StageVar *stageVar, const NamedDecl *decl, const llvm::StringRef name,
  2606. SourceLocation srcLoc) {
  2607. using spv::BuiltIn;
  2608. const auto sigPoint = stageVar->getSigPoint();
  2609. const auto semanticKind = stageVar->getSemanticInfo().getKind();
  2610. const auto sigPointKind = sigPoint->GetKind();
  2611. const auto type = stageVar->getAstType();
  2612. const auto isPrecise = decl->hasAttr<HLSLPreciseAttr>();
  2613. spv::StorageClass sc = getStorageClassForSigPoint(sigPoint);
  2614. if (sc == spv::StorageClass::Max)
  2615. return 0;
  2616. stageVar->setStorageClass(sc);
  2617. // [[vk::builtin(...)]] takes precedence.
  2618. if (const auto *builtinAttr = stageVar->getBuiltInAttr()) {
  2619. const auto spvBuiltIn =
  2620. llvm::StringSwitch<BuiltIn>(builtinAttr->getBuiltIn())
  2621. .Case("PointSize", BuiltIn::PointSize)
  2622. .Case("HelperInvocation", BuiltIn::HelperInvocation)
  2623. .Case("BaseVertex", BuiltIn::BaseVertex)
  2624. .Case("BaseInstance", BuiltIn::BaseInstance)
  2625. .Case("DrawIndex", BuiltIn::DrawIndex)
  2626. .Case("DeviceIndex", BuiltIn::DeviceIndex)
  2627. .Case("ViewportMaskNV", BuiltIn::ViewportMaskNV)
  2628. .Default(BuiltIn::Max);
  2629. assert(spvBuiltIn != BuiltIn::Max); // The frontend should guarantee this.
  2630. return spvBuilder.addStageBuiltinVar(type, sc, spvBuiltIn, isPrecise,
  2631. srcLoc);
  2632. }
  2633. // The following translation assumes that semantic validity in the current
  2634. // shader model is already checked, so it only covers valid SigPoints for
  2635. // each semantic.
  2636. switch (semanticKind) {
  2637. // According to DXIL spec, the Position SV can be used by all SigPoints
  2638. // other than PCIn, HSIn, GSIn, PSOut, CSIn, MSIn, MSPOut, ASIn.
  2639. // According to Vulkan spec, the Position BuiltIn can only be used
  2640. // by VSOut, HS/DS/GS In/Out, MSOut.
  2641. case hlsl::Semantic::Kind::Position: {
  2642. switch (sigPointKind) {
  2643. case hlsl::SigPoint::Kind::VSIn:
  2644. case hlsl::SigPoint::Kind::PCOut:
  2645. case hlsl::SigPoint::Kind::DSIn:
  2646. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2647. case hlsl::SigPoint::Kind::VSOut:
  2648. case hlsl::SigPoint::Kind::HSCPIn:
  2649. case hlsl::SigPoint::Kind::HSCPOut:
  2650. case hlsl::SigPoint::Kind::DSCPIn:
  2651. case hlsl::SigPoint::Kind::DSOut:
  2652. case hlsl::SigPoint::Kind::GSVIn:
  2653. case hlsl::SigPoint::Kind::GSOut:
  2654. case hlsl::SigPoint::Kind::MSOut:
  2655. stageVar->setIsSpirvBuiltin();
  2656. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::Position,
  2657. isPrecise, srcLoc);
  2658. case hlsl::SigPoint::Kind::PSIn:
  2659. stageVar->setIsSpirvBuiltin();
  2660. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragCoord,
  2661. isPrecise, srcLoc);
  2662. default:
  2663. llvm_unreachable("invalid usage of SV_Position sneaked in");
  2664. }
  2665. }
  2666. // According to DXIL spec, the VertexID SV can only be used by VSIn.
  2667. // According to Vulkan spec, the VertexIndex BuiltIn can only be used by
  2668. // VSIn.
  2669. case hlsl::Semantic::Kind::VertexID: {
  2670. stageVar->setIsSpirvBuiltin();
  2671. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::VertexIndex,
  2672. isPrecise, srcLoc);
  2673. }
  2674. // According to DXIL spec, the InstanceID SV can be used by VSIn, VSOut,
  2675. // HSCPIn, HSCPOut, DSCPIn, DSOut, GSVIn, GSOut, PSIn.
  2676. // According to Vulkan spec, the InstanceIndex BuitIn can only be used by
  2677. // VSIn.
  2678. case hlsl::Semantic::Kind::InstanceID: {
  2679. switch (sigPointKind) {
  2680. case hlsl::SigPoint::Kind::VSIn:
  2681. stageVar->setIsSpirvBuiltin();
  2682. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::InstanceIndex,
  2683. isPrecise, srcLoc);
  2684. case hlsl::SigPoint::Kind::VSOut:
  2685. case hlsl::SigPoint::Kind::HSCPIn:
  2686. case hlsl::SigPoint::Kind::HSCPOut:
  2687. case hlsl::SigPoint::Kind::DSCPIn:
  2688. case hlsl::SigPoint::Kind::DSOut:
  2689. case hlsl::SigPoint::Kind::GSVIn:
  2690. case hlsl::SigPoint::Kind::GSOut:
  2691. case hlsl::SigPoint::Kind::PSIn:
  2692. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2693. default:
  2694. llvm_unreachable("invalid usage of SV_InstanceID sneaked in");
  2695. }
  2696. }
  2697. // According to DXIL spec, the Depth{|GreaterEqual|LessEqual} SV can only be
  2698. // used by PSOut.
  2699. // According to Vulkan spec, the FragDepth BuiltIn can only be used by PSOut.
  2700. case hlsl::Semantic::Kind::Depth:
  2701. case hlsl::Semantic::Kind::DepthGreaterEqual:
  2702. case hlsl::Semantic::Kind::DepthLessEqual: {
  2703. stageVar->setIsSpirvBuiltin();
  2704. // Vulkan requires the DepthReplacing execution mode to write to FragDepth.
  2705. spvBuilder.addExecutionMode(entryFunction,
  2706. spv::ExecutionMode::DepthReplacing, {}, srcLoc);
  2707. if (semanticKind == hlsl::Semantic::Kind::DepthGreaterEqual)
  2708. spvBuilder.addExecutionMode(entryFunction,
  2709. spv::ExecutionMode::DepthGreater, {}, srcLoc);
  2710. else if (semanticKind == hlsl::Semantic::Kind::DepthLessEqual)
  2711. spvBuilder.addExecutionMode(entryFunction, spv::ExecutionMode::DepthLess,
  2712. {}, srcLoc);
  2713. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragDepth,
  2714. isPrecise, srcLoc);
  2715. }
  2716. // According to DXIL spec, the ClipDistance/CullDistance SV can be used by all
  2717. // SigPoints other than PCIn, HSIn, GSIn, PSOut, CSIn, MSIn, MSPOut, ASIn.
  2718. // According to Vulkan spec, the ClipDistance/CullDistance
  2719. // BuiltIn can only be used by VSOut, HS/DS/GS In/Out, MSOut.
  2720. case hlsl::Semantic::Kind::ClipDistance:
  2721. case hlsl::Semantic::Kind::CullDistance: {
  2722. switch (sigPointKind) {
  2723. case hlsl::SigPoint::Kind::VSIn:
  2724. case hlsl::SigPoint::Kind::PCOut:
  2725. case hlsl::SigPoint::Kind::DSIn:
  2726. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2727. case hlsl::SigPoint::Kind::VSOut:
  2728. case hlsl::SigPoint::Kind::HSCPIn:
  2729. case hlsl::SigPoint::Kind::HSCPOut:
  2730. case hlsl::SigPoint::Kind::DSCPIn:
  2731. case hlsl::SigPoint::Kind::DSOut:
  2732. case hlsl::SigPoint::Kind::GSVIn:
  2733. case hlsl::SigPoint::Kind::GSOut:
  2734. case hlsl::SigPoint::Kind::PSIn:
  2735. case hlsl::SigPoint::Kind::MSOut:
  2736. llvm_unreachable("should be handled in gl_PerVertex struct");
  2737. default:
  2738. llvm_unreachable(
  2739. "invalid usage of SV_ClipDistance/SV_CullDistance sneaked in");
  2740. }
  2741. }
  2742. // According to DXIL spec, the IsFrontFace SV can only be used by GSOut and
  2743. // PSIn.
  2744. // According to Vulkan spec, the FrontFacing BuitIn can only be used in PSIn.
  2745. case hlsl::Semantic::Kind::IsFrontFace: {
  2746. switch (sigPointKind) {
  2747. case hlsl::SigPoint::Kind::GSOut:
  2748. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2749. case hlsl::SigPoint::Kind::PSIn:
  2750. stageVar->setIsSpirvBuiltin();
  2751. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FrontFacing,
  2752. isPrecise, srcLoc);
  2753. default:
  2754. llvm_unreachable("invalid usage of SV_IsFrontFace sneaked in");
  2755. }
  2756. }
  2757. // According to DXIL spec, the Target SV can only be used by PSOut.
  2758. // There is no corresponding builtin decoration in SPIR-V. So generate normal
  2759. // Vulkan stage input/output variables.
  2760. case hlsl::Semantic::Kind::Target:
  2761. // An arbitrary semantic is defined by users. Generate normal Vulkan stage
  2762. // input/output variables.
  2763. case hlsl::Semantic::Kind::Arbitrary: {
  2764. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2765. // TODO: patch constant function in hull shader
  2766. }
  2767. // According to DXIL spec, the DispatchThreadID SV can only be used by CSIn.
  2768. // According to Vulkan spec, the GlobalInvocationId can only be used in CSIn.
  2769. case hlsl::Semantic::Kind::DispatchThreadID: {
  2770. stageVar->setIsSpirvBuiltin();
  2771. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::GlobalInvocationId,
  2772. isPrecise, srcLoc);
  2773. }
  2774. // According to DXIL spec, the GroupID SV can only be used by CSIn.
  2775. // According to Vulkan spec, the WorkgroupId can only be used in CSIn.
  2776. case hlsl::Semantic::Kind::GroupID: {
  2777. stageVar->setIsSpirvBuiltin();
  2778. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::WorkgroupId,
  2779. isPrecise, srcLoc);
  2780. }
  2781. // According to DXIL spec, the GroupThreadID SV can only be used by CSIn.
  2782. // According to Vulkan spec, the LocalInvocationId can only be used in CSIn.
  2783. case hlsl::Semantic::Kind::GroupThreadID: {
  2784. stageVar->setIsSpirvBuiltin();
  2785. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::LocalInvocationId,
  2786. isPrecise, srcLoc);
  2787. }
  2788. // According to DXIL spec, the GroupIndex SV can only be used by CSIn.
  2789. // According to Vulkan spec, the LocalInvocationIndex can only be used in
  2790. // CSIn.
  2791. case hlsl::Semantic::Kind::GroupIndex: {
  2792. stageVar->setIsSpirvBuiltin();
  2793. return spvBuilder.addStageBuiltinVar(
  2794. type, sc, BuiltIn::LocalInvocationIndex, isPrecise, srcLoc);
  2795. }
  2796. // According to DXIL spec, the OutputControlID SV can only be used by HSIn.
  2797. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  2798. // HS/GS In.
  2799. case hlsl::Semantic::Kind::OutputControlPointID: {
  2800. stageVar->setIsSpirvBuiltin();
  2801. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId,
  2802. isPrecise, srcLoc);
  2803. }
  2804. // According to DXIL spec, the PrimitiveID SV can only be used by PCIn, HSIn,
  2805. // DSIn, GSIn, GSOut, PSIn, and MSPOut.
  2806. // According to Vulkan spec, the PrimitiveId BuiltIn can only be used in
  2807. // HS/DS/PS In, GS In/Out, MSPOut.
  2808. case hlsl::Semantic::Kind::PrimitiveID: {
  2809. // Translate to PrimitiveId BuiltIn for all valid SigPoints.
  2810. stageVar->setIsSpirvBuiltin();
  2811. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::PrimitiveId,
  2812. isPrecise, srcLoc);
  2813. }
  2814. // According to DXIL spec, the TessFactor SV can only be used by PCOut and
  2815. // DSIn.
  2816. // According to Vulkan spec, the TessLevelOuter BuiltIn can only be used in
  2817. // PCOut and DSIn.
  2818. case hlsl::Semantic::Kind::TessFactor: {
  2819. stageVar->setIsSpirvBuiltin();
  2820. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelOuter,
  2821. isPrecise, srcLoc);
  2822. }
  2823. // According to DXIL spec, the InsideTessFactor SV can only be used by PCOut
  2824. // and DSIn.
  2825. // According to Vulkan spec, the TessLevelInner BuiltIn can only be used in
  2826. // PCOut and DSIn.
  2827. case hlsl::Semantic::Kind::InsideTessFactor: {
  2828. stageVar->setIsSpirvBuiltin();
  2829. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelInner,
  2830. isPrecise, srcLoc);
  2831. }
  2832. // According to DXIL spec, the DomainLocation SV can only be used by DSIn.
  2833. // According to Vulkan spec, the TessCoord BuiltIn can only be used in DSIn.
  2834. case hlsl::Semantic::Kind::DomainLocation: {
  2835. stageVar->setIsSpirvBuiltin();
  2836. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessCoord,
  2837. isPrecise, srcLoc);
  2838. }
  2839. // According to DXIL spec, the GSInstanceID SV can only be used by GSIn.
  2840. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  2841. // HS/GS In.
  2842. case hlsl::Semantic::Kind::GSInstanceID: {
  2843. stageVar->setIsSpirvBuiltin();
  2844. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId,
  2845. isPrecise, srcLoc);
  2846. }
  2847. // According to DXIL spec, the SampleIndex SV can only be used by PSIn.
  2848. // According to Vulkan spec, the SampleId BuiltIn can only be used in PSIn.
  2849. case hlsl::Semantic::Kind::SampleIndex: {
  2850. stageVar->setIsSpirvBuiltin();
  2851. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleId, isPrecise,
  2852. srcLoc);
  2853. }
  2854. // According to DXIL spec, the StencilRef SV can only be used by PSOut.
  2855. case hlsl::Semantic::Kind::StencilRef: {
  2856. stageVar->setIsSpirvBuiltin();
  2857. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragStencilRefEXT,
  2858. isPrecise, srcLoc);
  2859. }
  2860. // According to DXIL spec, the Barycentrics SV can only be used by PSIn.
  2861. case hlsl::Semantic::Kind::Barycentrics: {
  2862. stageVar->setIsSpirvBuiltin();
  2863. // Selecting the correct builtin according to interpolation mode
  2864. auto bi = BuiltIn::Max;
  2865. if (decl->hasAttr<HLSLNoPerspectiveAttr>()) {
  2866. if (decl->hasAttr<HLSLCentroidAttr>()) {
  2867. bi = BuiltIn::BaryCoordNoPerspCentroidAMD;
  2868. } else if (decl->hasAttr<HLSLSampleAttr>()) {
  2869. bi = BuiltIn::BaryCoordNoPerspSampleAMD;
  2870. } else {
  2871. bi = BuiltIn::BaryCoordNoPerspAMD;
  2872. }
  2873. } else {
  2874. if (decl->hasAttr<HLSLCentroidAttr>()) {
  2875. bi = BuiltIn::BaryCoordSmoothCentroidAMD;
  2876. } else if (decl->hasAttr<HLSLSampleAttr>()) {
  2877. bi = BuiltIn::BaryCoordSmoothSampleAMD;
  2878. } else {
  2879. bi = BuiltIn::BaryCoordSmoothAMD;
  2880. }
  2881. }
  2882. return spvBuilder.addStageBuiltinVar(type, sc, bi, isPrecise, srcLoc);
  2883. }
  2884. // According to DXIL spec, the RenderTargetArrayIndex SV can only be used by
  2885. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn, MSPOut.
  2886. // According to Vulkan spec, the Layer BuiltIn can only be used in GSOut
  2887. // PSIn, and MSPOut.
  2888. case hlsl::Semantic::Kind::RenderTargetArrayIndex: {
  2889. switch (sigPointKind) {
  2890. case hlsl::SigPoint::Kind::VSIn:
  2891. case hlsl::SigPoint::Kind::HSCPIn:
  2892. case hlsl::SigPoint::Kind::HSCPOut:
  2893. case hlsl::SigPoint::Kind::PCOut:
  2894. case hlsl::SigPoint::Kind::DSIn:
  2895. case hlsl::SigPoint::Kind::DSCPIn:
  2896. case hlsl::SigPoint::Kind::GSVIn:
  2897. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2898. case hlsl::SigPoint::Kind::VSOut:
  2899. case hlsl::SigPoint::Kind::DSOut:
  2900. stageVar->setIsSpirvBuiltin();
  2901. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::Layer, isPrecise,
  2902. srcLoc);
  2903. case hlsl::SigPoint::Kind::GSOut:
  2904. case hlsl::SigPoint::Kind::PSIn:
  2905. case hlsl::SigPoint::Kind::MSPOut:
  2906. stageVar->setIsSpirvBuiltin();
  2907. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::Layer, isPrecise,
  2908. srcLoc);
  2909. default:
  2910. llvm_unreachable("invalid usage of SV_RenderTargetArrayIndex sneaked in");
  2911. }
  2912. }
  2913. // According to DXIL spec, the ViewportArrayIndex SV can only be used by
  2914. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn, MSPOut.
  2915. // According to Vulkan spec, the ViewportIndex BuiltIn can only be used in
  2916. // GSOut, PSIn, and MSPOut.
  2917. case hlsl::Semantic::Kind::ViewPortArrayIndex: {
  2918. switch (sigPointKind) {
  2919. case hlsl::SigPoint::Kind::VSIn:
  2920. case hlsl::SigPoint::Kind::HSCPIn:
  2921. case hlsl::SigPoint::Kind::HSCPOut:
  2922. case hlsl::SigPoint::Kind::PCOut:
  2923. case hlsl::SigPoint::Kind::DSIn:
  2924. case hlsl::SigPoint::Kind::DSCPIn:
  2925. case hlsl::SigPoint::Kind::GSVIn:
  2926. return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc);
  2927. case hlsl::SigPoint::Kind::VSOut:
  2928. case hlsl::SigPoint::Kind::DSOut:
  2929. stageVar->setIsSpirvBuiltin();
  2930. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::ViewportIndex,
  2931. isPrecise, srcLoc);
  2932. case hlsl::SigPoint::Kind::GSOut:
  2933. case hlsl::SigPoint::Kind::PSIn:
  2934. case hlsl::SigPoint::Kind::MSPOut:
  2935. stageVar->setIsSpirvBuiltin();
  2936. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::ViewportIndex,
  2937. isPrecise, srcLoc);
  2938. default:
  2939. llvm_unreachable("invalid usage of SV_ViewportArrayIndex sneaked in");
  2940. }
  2941. }
  2942. // According to DXIL spec, the Coverage SV can only be used by PSIn and PSOut.
  2943. // According to Vulkan spec, the SampleMask BuiltIn can only be used in
  2944. // PSIn and PSOut.
  2945. case hlsl::Semantic::Kind::Coverage: {
  2946. stageVar->setIsSpirvBuiltin();
  2947. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleMask,
  2948. isPrecise, srcLoc);
  2949. }
  2950. // According to DXIL spec, the ViewID SV can only be used by VSIn, PCIn,
  2951. // HSIn, DSIn, GSIn, PSIn.
  2952. // According to Vulkan spec, the ViewIndex BuiltIn can only be used in
  2953. // VS/HS/DS/GS/PS input.
  2954. case hlsl::Semantic::Kind::ViewID: {
  2955. stageVar->setIsSpirvBuiltin();
  2956. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::ViewIndex,
  2957. isPrecise, srcLoc);
  2958. }
  2959. // According to DXIL spec, the InnerCoverage SV can only be used as PSIn.
  2960. // According to Vulkan spec, the FullyCoveredEXT BuiltIn can only be used as
  2961. // PSIn.
  2962. case hlsl::Semantic::Kind::InnerCoverage: {
  2963. stageVar->setIsSpirvBuiltin();
  2964. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FullyCoveredEXT,
  2965. isPrecise, srcLoc);
  2966. }
  2967. // According to DXIL spec, the ShadingRate SV can only be used by GSOut,
  2968. // VSOut, or PSIn. According to Vulkan spec, the FragSizeEXT BuiltIn can only
  2969. // be used as PSIn.
  2970. case hlsl::Semantic::Kind::ShadingRate: {
  2971. switch (sigPointKind) {
  2972. case hlsl::SigPoint::Kind::PSIn:
  2973. stageVar->setIsSpirvBuiltin();
  2974. return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragSizeEXT,
  2975. isPrecise, srcLoc);
  2976. default:
  2977. emitError("semantic ShadingRate currently unsupported in non-PS shader"
  2978. " stages",
  2979. srcLoc);
  2980. break;
  2981. }
  2982. break;
  2983. }
  2984. default:
  2985. emitError("semantic %0 unimplemented", srcLoc)
  2986. << stageVar->getSemanticStr();
  2987. break;
  2988. }
  2989. return 0;
  2990. }
  2991. bool DeclResultIdMapper::validateVKAttributes(const NamedDecl *decl) {
  2992. bool success = true;
  2993. if (const auto *idxAttr = decl->getAttr<VKIndexAttr>()) {
  2994. if (!spvContext.isPS()) {
  2995. emitError("vk::index only allowed in pixel shader",
  2996. idxAttr->getLocation());
  2997. success = false;
  2998. }
  2999. const auto *locAttr = decl->getAttr<VKLocationAttr>();
  3000. if (!locAttr) {
  3001. emitError("vk::index should be used together with vk::location for "
  3002. "dual-source blending",
  3003. idxAttr->getLocation());
  3004. success = false;
  3005. } else {
  3006. const auto locNumber = locAttr->getNumber();
  3007. if (locNumber != 0) {
  3008. emitError("dual-source blending should use vk::location 0",
  3009. locAttr->getLocation());
  3010. success = false;
  3011. }
  3012. }
  3013. const auto idxNumber = idxAttr->getNumber();
  3014. if (idxNumber != 0 && idxNumber != 1) {
  3015. emitError("dual-source blending only accepts 0 or 1 as vk::index",
  3016. idxAttr->getLocation());
  3017. success = false;
  3018. }
  3019. }
  3020. return success;
  3021. }
  3022. bool DeclResultIdMapper::validateVKBuiltins(const NamedDecl *decl,
  3023. const hlsl::SigPoint *sigPoint) {
  3024. bool success = true;
  3025. if (const auto *builtinAttr = decl->getAttr<VKBuiltInAttr>()) {
  3026. // The front end parsing only allows vk::builtin to be attached to a
  3027. // function/parameter/variable; all of them are DeclaratorDecls.
  3028. const auto declType = getTypeOrFnRetType(cast<DeclaratorDecl>(decl));
  3029. const auto loc = builtinAttr->getLocation();
  3030. if (decl->hasAttr<VKLocationAttr>()) {
  3031. emitError("cannot use vk::builtin and vk::location together", loc);
  3032. success = false;
  3033. }
  3034. const llvm::StringRef builtin = builtinAttr->getBuiltIn();
  3035. if (builtin == "HelperInvocation") {
  3036. if (!declType->isBooleanType()) {
  3037. emitError("HelperInvocation builtin must be of boolean type", loc);
  3038. success = false;
  3039. }
  3040. if (sigPoint->GetKind() != hlsl::SigPoint::Kind::PSIn) {
  3041. emitError(
  3042. "HelperInvocation builtin can only be used as pixel shader input",
  3043. loc);
  3044. success = false;
  3045. }
  3046. } else if (builtin == "PointSize") {
  3047. if (!declType->isFloatingType()) {
  3048. emitError("PointSize builtin must be of float type", loc);
  3049. success = false;
  3050. }
  3051. switch (sigPoint->GetKind()) {
  3052. case hlsl::SigPoint::Kind::VSOut:
  3053. case hlsl::SigPoint::Kind::HSCPIn:
  3054. case hlsl::SigPoint::Kind::HSCPOut:
  3055. case hlsl::SigPoint::Kind::DSCPIn:
  3056. case hlsl::SigPoint::Kind::DSOut:
  3057. case hlsl::SigPoint::Kind::GSVIn:
  3058. case hlsl::SigPoint::Kind::GSOut:
  3059. case hlsl::SigPoint::Kind::PSIn:
  3060. case hlsl::SigPoint::Kind::MSOut:
  3061. break;
  3062. default:
  3063. emitError("PointSize builtin cannot be used as %0", loc)
  3064. << sigPoint->GetName();
  3065. success = false;
  3066. }
  3067. } else if (builtin == "BaseVertex" || builtin == "BaseInstance" ||
  3068. builtin == "DrawIndex") {
  3069. if (!declType->isSpecificBuiltinType(BuiltinType::Kind::Int) &&
  3070. !declType->isSpecificBuiltinType(BuiltinType::Kind::UInt)) {
  3071. emitError("%0 builtin must be of 32-bit scalar integer type", loc)
  3072. << builtin;
  3073. success = false;
  3074. }
  3075. switch (sigPoint->GetKind()) {
  3076. case hlsl::SigPoint::Kind::VSIn:
  3077. break;
  3078. case hlsl::SigPoint::Kind::MSIn:
  3079. case hlsl::SigPoint::Kind::ASIn:
  3080. if (builtin != "DrawIndex") {
  3081. emitError("%0 builtin cannot be used as %1", loc)
  3082. << builtin << sigPoint->GetName();
  3083. success = false;
  3084. }
  3085. break;
  3086. default:
  3087. emitError("%0 builtin cannot be used as %1", loc)
  3088. << builtin << sigPoint->GetName();
  3089. success = false;
  3090. }
  3091. } else if (builtin == "DeviceIndex") {
  3092. if (getStorageClassForSigPoint(sigPoint) != spv::StorageClass::Input) {
  3093. emitError("%0 builtin can only be used as shader input", loc)
  3094. << builtin;
  3095. success = false;
  3096. }
  3097. if (!declType->isSpecificBuiltinType(BuiltinType::Kind::Int) &&
  3098. !declType->isSpecificBuiltinType(BuiltinType::Kind::UInt)) {
  3099. emitError("%0 builtin must be of 32-bit scalar integer type", loc)
  3100. << builtin;
  3101. success = false;
  3102. }
  3103. } else if (builtin == "ViewportMaskNV") {
  3104. if (sigPoint->GetKind() != hlsl::SigPoint::Kind::MSPOut) {
  3105. emitError("%0 builtin can only be used as 'primitives' output in MS",
  3106. loc)
  3107. << builtin;
  3108. success = false;
  3109. }
  3110. if (!declType->isArrayType() ||
  3111. !declType->getArrayElementTypeNoTypeQual()->isSpecificBuiltinType(
  3112. BuiltinType::Kind::Int)) {
  3113. emitError("%0 builtin must be of type array of integers", loc)
  3114. << builtin;
  3115. success = false;
  3116. }
  3117. }
  3118. }
  3119. return success;
  3120. }
  3121. spv::StorageClass
  3122. DeclResultIdMapper::getStorageClassForSigPoint(const hlsl::SigPoint *sigPoint) {
  3123. // This translation is done based on the HLSL reference (see docs/dxil.rst).
  3124. const auto sigPointKind = sigPoint->GetKind();
  3125. const auto signatureKind = sigPoint->GetSignatureKind();
  3126. spv::StorageClass sc = spv::StorageClass::Max;
  3127. switch (signatureKind) {
  3128. case hlsl::DXIL::SignatureKind::Input:
  3129. sc = spv::StorageClass::Input;
  3130. break;
  3131. case hlsl::DXIL::SignatureKind::Output:
  3132. sc = spv::StorageClass::Output;
  3133. break;
  3134. case hlsl::DXIL::SignatureKind::Invalid: {
  3135. // There are some special cases in HLSL (See docs/dxil.rst):
  3136. // SignatureKind is "invalid" for PCIn, HSIn, GSIn, and CSIn.
  3137. switch (sigPointKind) {
  3138. case hlsl::DXIL::SigPointKind::PCIn:
  3139. case hlsl::DXIL::SigPointKind::HSIn:
  3140. case hlsl::DXIL::SigPointKind::GSIn:
  3141. case hlsl::DXIL::SigPointKind::CSIn:
  3142. case hlsl::DXIL::SigPointKind::MSIn:
  3143. case hlsl::DXIL::SigPointKind::ASIn:
  3144. sc = spv::StorageClass::Input;
  3145. break;
  3146. default:
  3147. llvm_unreachable("Found invalid SigPoint kind for semantic");
  3148. }
  3149. break;
  3150. }
  3151. case hlsl::DXIL::SignatureKind::PatchConstOrPrim: {
  3152. // There are some special cases in HLSL (See docs/dxil.rst):
  3153. // SignatureKind is "PatchConstOrPrim" for PCOut, MSPOut and DSIn.
  3154. switch (sigPointKind) {
  3155. case hlsl::DXIL::SigPointKind::PCOut:
  3156. case hlsl::DXIL::SigPointKind::MSPOut:
  3157. // Patch Constant Output (Output of Hull which is passed to Domain).
  3158. // Mesh Shader per-primitive output attributes.
  3159. sc = spv::StorageClass::Output;
  3160. break;
  3161. case hlsl::DXIL::SigPointKind::DSIn:
  3162. // Domain Shader regular input - Patch Constant data plus system values.
  3163. sc = spv::StorageClass::Input;
  3164. break;
  3165. default:
  3166. llvm_unreachable("Found invalid SigPoint kind for semantic");
  3167. }
  3168. break;
  3169. }
  3170. default:
  3171. llvm_unreachable("Found invalid SigPoint kind for semantic");
  3172. }
  3173. return sc;
  3174. }
  3175. QualType DeclResultIdMapper::getTypeAndCreateCounterForPotentialAliasVar(
  3176. const DeclaratorDecl *decl, bool *shouldBeAlias) {
  3177. if (const auto *varDecl = dyn_cast<VarDecl>(decl)) {
  3178. // This method is only intended to be used to create SPIR-V variables in the
  3179. // Function or Private storage class.
  3180. assert(!varDecl->isExternallyVisible() || varDecl->isStaticDataMember());
  3181. }
  3182. const QualType type = getTypeOrFnRetType(decl);
  3183. // Whether we should generate this decl as an alias variable.
  3184. bool genAlias = false;
  3185. // For ConstantBuffers, TextureBuffers, StructuredBuffers, ByteAddressBuffers
  3186. if (isConstantTextureBuffer(type) ||
  3187. isOrContainsAKindOfStructuredOrByteBuffer(type)) {
  3188. genAlias = true;
  3189. }
  3190. // Return via parameter whether alias was generated.
  3191. if (shouldBeAlias)
  3192. *shouldBeAlias = genAlias;
  3193. if (genAlias) {
  3194. needsLegalization = true;
  3195. createCounterVarForDecl(decl);
  3196. }
  3197. return type;
  3198. }
  3199. bool DeclResultIdMapper::getImplicitRegisterType(const ResourceVar &var,
  3200. char *registerTypeOut) const {
  3201. assert(registerTypeOut);
  3202. if (var.getSpirvInstr()) {
  3203. if (var.getSpirvInstr()->hasAstResultType()) {
  3204. QualType type = var.getSpirvInstr()->getAstResultType();
  3205. // Strip outer arrayness first
  3206. while (type->isArrayType())
  3207. type = type->getAsArrayTypeUnsafe()->getElementType();
  3208. // t - for shader resource views (SRV)
  3209. if (isTexture(type) || isNonWritableStructuredBuffer(type) ||
  3210. isByteAddressBuffer(type) || isBuffer(type)) {
  3211. *registerTypeOut = 't';
  3212. return true;
  3213. }
  3214. // s - for samplers
  3215. else if (isSampler(type)) {
  3216. *registerTypeOut = 's';
  3217. return true;
  3218. }
  3219. // u - for unordered access views (UAV)
  3220. else if (isRWByteAddressBuffer(type) || isRWAppendConsumeSBuffer(type) ||
  3221. isRWBuffer(type) || isRWTexture(type)) {
  3222. *registerTypeOut = 'u';
  3223. return true;
  3224. }
  3225. } else {
  3226. llvm::StringRef hlslUserType = var.getSpirvInstr()->getHlslUserType();
  3227. // b - for constant buffer views (CBV)
  3228. if (var.isGlobalsBuffer() || hlslUserType == "cbuffer" ||
  3229. hlslUserType == "ConstantBuffer") {
  3230. *registerTypeOut = 'b';
  3231. return true;
  3232. }
  3233. if (hlslUserType == "tbuffer") {
  3234. *registerTypeOut = 't';
  3235. return true;
  3236. }
  3237. }
  3238. }
  3239. *registerTypeOut = '\0';
  3240. return false;
  3241. }
  3242. SpirvVariable *
  3243. DeclResultIdMapper::createRayTracingNVStageVar(spv::StorageClass sc,
  3244. const VarDecl *decl) {
  3245. QualType type = decl->getType();
  3246. SpirvVariable *retVal = nullptr;
  3247. // Raytracing interface variables are special since they do not participate
  3248. // in any interface matching and hence do not create StageVar and
  3249. // track them under StageVars vector
  3250. const auto name = decl->getName();
  3251. switch (sc) {
  3252. case spv::StorageClass::IncomingRayPayloadNV:
  3253. case spv::StorageClass::IncomingCallableDataNV:
  3254. case spv::StorageClass::HitAttributeNV:
  3255. case spv::StorageClass::RayPayloadNV:
  3256. case spv::StorageClass::CallableDataNV:
  3257. retVal = spvBuilder.addModuleVar(type, sc, decl->hasAttr<HLSLPreciseAttr>(),
  3258. name.str());
  3259. break;
  3260. default:
  3261. assert(false && "Unsupported SPIR-V storage class for raytracing");
  3262. }
  3263. return retVal;
  3264. }
  3265. void DeclResultIdMapper::tryToCreateImplicitConstVar(const ValueDecl *decl) {
  3266. const VarDecl *varDecl = dyn_cast<VarDecl>(decl);
  3267. if (!varDecl || !varDecl->isImplicit())
  3268. return;
  3269. APValue *val = varDecl->evaluateValue();
  3270. if (!val)
  3271. return;
  3272. SpirvInstruction *constVal =
  3273. spvBuilder.getConstantInt(astContext.UnsignedIntTy, val->getInt());
  3274. constVal->setRValue(true);
  3275. astDecls[varDecl].instr = constVal;
  3276. }
  3277. SpirvInstruction *
  3278. DeclResultIdMapper::createHullMainOutputPatch(const ParmVarDecl *param,
  3279. const QualType retType,
  3280. uint32_t numOutputControlPoints) {
  3281. const QualType hullMainRetType = astContext.getConstantArrayType(
  3282. retType, llvm::APInt(32, numOutputControlPoints),
  3283. clang::ArrayType::Normal, 0);
  3284. SpirvInstruction *hullMainOutputPatch = createSpirvIntermediateOutputStageVar(
  3285. param, "temp.var.hullMainRetVal", hullMainRetType);
  3286. assert(astDecls[param].instr == nullptr);
  3287. astDecls[param].instr = hullMainOutputPatch;
  3288. return hullMainOutputPatch;
  3289. }
  3290. } // end namespace spirv
  3291. } // end namespace clang