DeclResultIdMapper.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  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 <algorithm>
  11. #include <cstring>
  12. #include <unordered_map>
  13. #include "dxc/HLSL/DxilConstants.h"
  14. #include "dxc/HLSL/DxilTypeSystem.h"
  15. #include "clang/AST/Expr.h"
  16. #include "clang/AST/HlslTypes.h"
  17. #include "clang/AST/RecursiveASTVisitor.h"
  18. #include "llvm/ADT/SmallBitVector.h"
  19. #include "llvm/ADT/StringSet.h"
  20. namespace clang {
  21. namespace spirv {
  22. namespace {
  23. /// \brief Returns true if the given decl has a semantic string attached and
  24. /// writes the info to *semanticStr, *semantic, *semanticIndex, and
  25. /// *semanticLoc.
  26. bool getStageVarSemantic(const NamedDecl *decl, llvm::StringRef *semanticStr,
  27. const hlsl::Semantic **semantic,
  28. uint32_t *semanticIndex, SourceLocation *semanticLoc) {
  29. for (auto *annotation : decl->getUnusualAnnotations()) {
  30. if (auto *sema = dyn_cast<hlsl::SemanticDecl>(annotation)) {
  31. *semanticStr = sema->SemanticName;
  32. llvm::StringRef semanticName;
  33. hlsl::Semantic::DecomposeNameAndIndex(*semanticStr, &semanticName,
  34. semanticIndex);
  35. *semantic = hlsl::Semantic::GetByName(semanticName);
  36. *semanticLoc = sema->Loc;
  37. return true;
  38. }
  39. }
  40. return false;
  41. }
  42. /// \brief Returns the stage variable's register assignment for the given Decl.
  43. const hlsl::RegisterAssignment *getResourceBinding(const NamedDecl *decl) {
  44. for (auto *annotation : decl->getUnusualAnnotations()) {
  45. if (auto *reg = dyn_cast<hlsl::RegisterAssignment>(annotation)) {
  46. return reg;
  47. }
  48. }
  49. return nullptr;
  50. }
  51. /// \brief Returns the resource category for the given type.
  52. ResourceVar::Category getResourceCategory(QualType type) {
  53. if (TypeTranslator::isTexture(type) || TypeTranslator::isRWTexture(type))
  54. return ResourceVar::Category::Image;
  55. if (TypeTranslator::isSampler(type))
  56. return ResourceVar::Category::Sampler;
  57. return ResourceVar::Category::Other;
  58. }
  59. /// \brief Returns true if the given declaration has a primitive type qualifier.
  60. /// Returns false otherwise.
  61. inline bool hasGSPrimitiveTypeQualifier(const Decl *decl) {
  62. return decl->hasAttr<HLSLTriangleAttr>() ||
  63. decl->hasAttr<HLSLTriangleAdjAttr>() ||
  64. decl->hasAttr<HLSLPointAttr>() || decl->hasAttr<HLSLLineAttr>() ||
  65. decl->hasAttr<HLSLLineAdjAttr>();
  66. }
  67. /// \brief Deduces the parameter qualifier for the given decl.
  68. hlsl::DxilParamInputQual deduceParamQual(const DeclaratorDecl *decl,
  69. bool asInput) {
  70. const auto type = decl->getType();
  71. if (hlsl::IsHLSLInputPatchType(type))
  72. return hlsl::DxilParamInputQual::InputPatch;
  73. if (hlsl::IsHLSLOutputPatchType(type))
  74. return hlsl::DxilParamInputQual::OutputPatch;
  75. // TODO: Add support for multiple output streams.
  76. if (hlsl::IsHLSLStreamOutputType(type))
  77. return hlsl::DxilParamInputQual::OutStream0;
  78. // The inputs to the geometry shader that have a primitive type qualifier
  79. // must use 'InputPrimitive'.
  80. if (hasGSPrimitiveTypeQualifier(decl))
  81. return hlsl::DxilParamInputQual::InputPrimitive;
  82. return asInput ? hlsl::DxilParamInputQual::In : hlsl::DxilParamInputQual::Out;
  83. }
  84. /// \brief Deduces the HLSL SigPoint for the given decl appearing in the given
  85. /// shader model.
  86. const hlsl::SigPoint *deduceSigPoint(const DeclaratorDecl *decl, bool asInput,
  87. const hlsl::ShaderModel::Kind kind,
  88. bool forPCF) {
  89. return hlsl::SigPoint::GetSigPoint(hlsl::SigPointFromInputQual(
  90. deduceParamQual(decl, asInput), kind, forPCF));
  91. }
  92. /// Returns the type of the given decl. If the given decl is a FunctionDecl,
  93. /// returns its result type.
  94. inline QualType getTypeOrFnRetType(const DeclaratorDecl *decl) {
  95. if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
  96. return funcDecl->getReturnType();
  97. }
  98. return decl->getType();
  99. }
  100. } // anonymous namespace
  101. bool DeclResultIdMapper::createStageOutputVar(const DeclaratorDecl *decl,
  102. uint32_t storedValue,
  103. bool forPCF) {
  104. QualType type = getTypeOrFnRetType(decl);
  105. // Output stream types (PointStream, LineStream, TriangleStream) are
  106. // translated as their underlying struct types.
  107. if (hlsl::IsHLSLStreamOutputType(type))
  108. type = hlsl::GetHLSLResourceResultType(type);
  109. const auto *sigPoint =
  110. deduceSigPoint(decl, /*asInput=*/false, shaderModel.GetKind(), forPCF);
  111. // HS output variables are created using the other overload. For the rest,
  112. // none of them should be created as arrays.
  113. assert(sigPoint->GetKind() != hlsl::DXIL::SigPointKind::HSCPOut);
  114. return createStageVars(
  115. sigPoint, decl, /*asInput=*/false, type,
  116. /*arraySize=*/0, "out.var", llvm::None, &storedValue,
  117. // Write back of stage output variables in GS is manually controlled by
  118. // .Append() intrinsic method, implemented in writeBackOutputStream().
  119. // So noWriteBack should be set to true for GS.
  120. shaderModel.IsGS());
  121. }
  122. bool DeclResultIdMapper::createStageOutputVar(const DeclaratorDecl *decl,
  123. uint32_t arraySize,
  124. uint32_t invocationId,
  125. uint32_t storedValue) {
  126. assert(shaderModel.IsHS());
  127. QualType type = getTypeOrFnRetType(decl);
  128. const auto *sigPoint =
  129. hlsl::SigPoint::GetSigPoint(hlsl::DXIL::SigPointKind::HSCPOut);
  130. return createStageVars(sigPoint, decl, /*asInput=*/false, type, arraySize,
  131. "out.var", invocationId, &storedValue,
  132. /*noWriteBack=*/false);
  133. }
  134. bool DeclResultIdMapper::createStageInputVar(const ParmVarDecl *paramDecl,
  135. uint32_t *loadedValue,
  136. bool forPCF) {
  137. uint32_t arraySize = 0;
  138. QualType type = paramDecl->getType();
  139. // Deprive the outermost arrayness for HS/DS/GS and use arraySize
  140. // to convey that information
  141. if (hlsl::IsHLSLInputPatchType(type)) {
  142. arraySize = hlsl::GetHLSLInputPatchCount(type);
  143. type = hlsl::GetHLSLInputPatchElementType(type);
  144. } else if (hlsl::IsHLSLOutputPatchType(type)) {
  145. arraySize = hlsl::GetHLSLOutputPatchCount(type);
  146. type = hlsl::GetHLSLOutputPatchElementType(type);
  147. }
  148. if (hasGSPrimitiveTypeQualifier(paramDecl)) {
  149. const auto *typeDecl = astContext.getAsConstantArrayType(type);
  150. arraySize = static_cast<uint32_t>(typeDecl->getSize().getZExtValue());
  151. type = typeDecl->getElementType();
  152. }
  153. const auto *sigPoint = deduceSigPoint(paramDecl, /*asInput=*/true,
  154. shaderModel.GetKind(), forPCF);
  155. return createStageVars(sigPoint, paramDecl, /*asInput=*/true, type, arraySize,
  156. "in.var", llvm::None, loadedValue,
  157. /*noWriteBack=*/false);
  158. }
  159. const DeclResultIdMapper::DeclSpirvInfo *
  160. DeclResultIdMapper::getDeclSpirvInfo(const NamedDecl *decl) const {
  161. auto it = astDecls.find(decl);
  162. if (it != astDecls.end())
  163. return &it->second;
  164. return nullptr;
  165. }
  166. SpirvEvalInfo DeclResultIdMapper::getDeclResultId(const NamedDecl *decl) {
  167. if (const auto *info = getDeclSpirvInfo(decl))
  168. if (info->indexInCTBuffer >= 0) {
  169. // If this is a VarDecl inside a HLSLBufferDecl, we need to do an extra
  170. // OpAccessChain to get the pointer to the variable since we created
  171. // a single variable for the whole buffer object.
  172. const uint32_t varType = typeTranslator.translateType(
  173. // Should only have VarDecls in a HLSLBufferDecl.
  174. cast<VarDecl>(decl)->getType(),
  175. // We need to set decorateLayout here to avoid creating SPIR-V
  176. // instructions for the current type without decorations.
  177. info->layoutRule);
  178. const uint32_t elemId = theBuilder.createAccessChain(
  179. theBuilder.getPointerType(varType, info->storageClass),
  180. info->resultId, {theBuilder.getConstantInt32(info->indexInCTBuffer)});
  181. return {elemId, info->storageClass, info->layoutRule};
  182. } else {
  183. return *info;
  184. }
  185. assert(false && "found unregistered decl");
  186. return 0;
  187. }
  188. uint32_t DeclResultIdMapper::createFnParam(uint32_t paramType,
  189. const ParmVarDecl *param) {
  190. const uint32_t id = theBuilder.addFnParam(paramType, param->getName());
  191. astDecls[param] = {id, spv::StorageClass::Function};
  192. return id;
  193. }
  194. uint32_t DeclResultIdMapper::createFnVar(uint32_t varType, const VarDecl *var,
  195. llvm::Optional<uint32_t> init) {
  196. const uint32_t id = theBuilder.addFnVar(varType, var->getName(), init);
  197. astDecls[var] = {id, spv::StorageClass::Function};
  198. return id;
  199. }
  200. uint32_t DeclResultIdMapper::createFileVar(uint32_t varType, const VarDecl *var,
  201. llvm::Optional<uint32_t> init) {
  202. const uint32_t id = theBuilder.addModuleVar(
  203. varType, spv::StorageClass::Private, var->getName(), init);
  204. astDecls[var] = {id, spv::StorageClass::Private};
  205. return id;
  206. }
  207. uint32_t DeclResultIdMapper::createExternVar(const VarDecl *var) {
  208. auto storageClass = spv::StorageClass::UniformConstant;
  209. auto rule = LayoutRule::Void;
  210. bool isACSBuffer = false; // Whether its {Append|Consume}StructuredBuffer
  211. if (var->getAttr<HLSLGroupSharedAttr>()) {
  212. // For CS groupshared variables
  213. storageClass = spv::StorageClass::Workgroup;
  214. } else if (auto *t = var->getType()->getAs<RecordType>()) {
  215. const llvm::StringRef typeName = t->getDecl()->getName();
  216. if (typeName == "StructuredBuffer" || typeName == "RWStructuredBuffer" ||
  217. typeName == "ByteAddressBuffer" || typeName == "RWByteAddressBuffer" ||
  218. typeName == "AppendStructuredBuffer" ||
  219. typeName == "ConsumeStructuredBuffer") {
  220. // These types are all translated into OpTypeStruct with BufferBlock
  221. // decoration. They should follow standard storage buffer layout,
  222. // which GLSL std430 rules statisfies.
  223. storageClass = spv::StorageClass::Uniform;
  224. rule = LayoutRule::GLSLStd430;
  225. isACSBuffer =
  226. typeName.startswith("Append") || typeName.startswith("Consume");
  227. }
  228. }
  229. const auto varType = typeTranslator.translateType(var->getType(), rule);
  230. const uint32_t id = theBuilder.addModuleVar(varType, storageClass,
  231. var->getName(), llvm::None);
  232. astDecls[var] = {id, storageClass, rule};
  233. const auto *regAttr = getResourceBinding(var);
  234. const auto *bindingAttr = var->getAttr<VKBindingAttr>();
  235. const auto *counterBindingAttr = var->getAttr<VKCounterBindingAttr>();
  236. resourceVars.emplace_back(id, getResourceCategory(var->getType()), regAttr,
  237. bindingAttr, counterBindingAttr);
  238. if (isACSBuffer) {
  239. // For {Append|Consume}StructuredBuffer, we need to always create another
  240. // variable for its associated counter.
  241. createCounterVar(var);
  242. }
  243. return id;
  244. }
  245. uint32_t DeclResultIdMapper::createVarOfExplicitLayoutStruct(
  246. const DeclContext *decl, const ContextUsageKind usageKind,
  247. llvm::StringRef typeName, llvm::StringRef varName) {
  248. // cbuffers are translated into OpTypeStruct with Block decoration.
  249. // tbuffers are translated into OpTypeStruct with BufferBlock decoration.
  250. // PushConstants are translated into OpTypeStruct with Block decoration.
  251. //
  252. // Both cbuffers and tbuffers have the SPIR-V Uniform storage class. cbuffers
  253. // follow GLSL std140 layout rules, and tbuffers follow GLSL std430 layout
  254. // rules. PushConstants follow GLSL std430 layout rules.
  255. auto &context = *theBuilder.getSPIRVContext();
  256. const LayoutRule layoutRule = usageKind == ContextUsageKind::CBuffer
  257. ? LayoutRule::GLSLStd140
  258. : LayoutRule::GLSLStd430;
  259. const auto *blockDec = usageKind == ContextUsageKind::TBuffer
  260. ? Decoration::getBufferBlock(context)
  261. : Decoration::getBlock(context);
  262. auto decorations = typeTranslator.getLayoutDecorations(decl, layoutRule);
  263. decorations.push_back(blockDec);
  264. // Collect the type and name for each field
  265. llvm::SmallVector<uint32_t, 4> fieldTypes;
  266. llvm::SmallVector<llvm::StringRef, 4> fieldNames;
  267. uint32_t fieldIndex = 0;
  268. for (const auto *subDecl : decl->decls()) {
  269. // Ignore implicit generated struct declarations/constructors/destructors.
  270. if (subDecl->isImplicit())
  271. continue;
  272. // The field can only be FieldDecl (for normal structs) or VarDecl (for
  273. // HLSLBufferDecls).
  274. assert(isa<VarDecl>(subDecl) || isa<FieldDecl>(subDecl));
  275. const auto *declDecl = cast<DeclaratorDecl>(subDecl);
  276. // All fields are qualified with const. It will affect the debug name.
  277. // We don't need it here.
  278. auto varType = declDecl->getType();
  279. varType.removeLocalConst();
  280. fieldTypes.push_back(typeTranslator.translateType(
  281. varType, layoutRule, declDecl->hasAttr<HLSLRowMajorAttr>()));
  282. fieldNames.push_back(declDecl->getName());
  283. // tbuffer/TextureBuffers are non-writable SSBOs. OpMemberDecorate
  284. // NonWritable must be applied to all fields.
  285. if (usageKind == ContextUsageKind::TBuffer) {
  286. decorations.push_back(Decoration::getNonWritable(
  287. *theBuilder.getSPIRVContext(), fieldIndex));
  288. }
  289. ++fieldIndex;
  290. }
  291. // Get the type for the whole struct
  292. const uint32_t structType =
  293. theBuilder.getStructType(fieldTypes, typeName, fieldNames, decorations);
  294. const auto sc = usageKind == ContextUsageKind::PushConstant
  295. ? spv::StorageClass::PushConstant
  296. : spv::StorageClass::Uniform;
  297. // Create the variable for the whole struct
  298. return theBuilder.addModuleVar(structType, sc, varName);
  299. }
  300. uint32_t DeclResultIdMapper::createCTBuffer(const HLSLBufferDecl *decl) {
  301. const auto usageKind =
  302. decl->isCBuffer() ? ContextUsageKind::CBuffer : ContextUsageKind::TBuffer;
  303. const std::string structName = "type." + decl->getName().str();
  304. const std::string varName = "var." + decl->getName().str();
  305. const uint32_t bufferVar =
  306. createVarOfExplicitLayoutStruct(decl, usageKind, structName, varName);
  307. // We still register all VarDecls seperately here. All the VarDecls are
  308. // mapped to the <result-id> of the buffer object, which means when querying
  309. // querying the <result-id> for a certain VarDecl, we need to do an extra
  310. // OpAccessChain.
  311. int index = 0;
  312. for (const auto *subDecl : decl->decls()) {
  313. const auto *varDecl = cast<VarDecl>(subDecl);
  314. astDecls[varDecl] = {bufferVar, spv::StorageClass::Uniform,
  315. decl->isCBuffer() ? LayoutRule::GLSLStd140
  316. : LayoutRule::GLSLStd430,
  317. index++};
  318. }
  319. resourceVars.emplace_back(
  320. bufferVar, ResourceVar::Category::Other, getResourceBinding(decl),
  321. decl->getAttr<VKBindingAttr>(), decl->getAttr<VKCounterBindingAttr>());
  322. return bufferVar;
  323. }
  324. uint32_t DeclResultIdMapper::createCTBuffer(const VarDecl *decl) {
  325. const auto *recordType = decl->getType()->getAs<RecordType>();
  326. assert(recordType);
  327. const auto *context = cast<HLSLBufferDecl>(decl->getDeclContext());
  328. const auto usageKind = context->isCBuffer() ? ContextUsageKind::CBuffer
  329. : ContextUsageKind::TBuffer;
  330. const std::string structName =
  331. "type." +
  332. std::string(context->isCBuffer() ? "ConstantBuffer." : "TextureBuffer.") +
  333. recordType->getDecl()->getName().str();
  334. const uint32_t bufferVar = createVarOfExplicitLayoutStruct(
  335. recordType->getDecl(), usageKind, structName, decl->getName());
  336. // We register the VarDecl here.
  337. astDecls[decl] = {bufferVar, spv::StorageClass::Uniform,
  338. context->isCBuffer() ? LayoutRule::GLSLStd140
  339. : LayoutRule::GLSLStd430};
  340. resourceVars.emplace_back(
  341. bufferVar, ResourceVar::Category::Other, getResourceBinding(context),
  342. decl->getAttr<VKBindingAttr>(), decl->getAttr<VKCounterBindingAttr>());
  343. return bufferVar;
  344. }
  345. uint32_t DeclResultIdMapper::createPushConstant(const VarDecl *decl) {
  346. const auto *recordType = decl->getType()->getAs<RecordType>();
  347. assert(recordType);
  348. const std::string structName =
  349. "type.PushConstant." + recordType->getDecl()->getName().str();
  350. const uint32_t var = createVarOfExplicitLayoutStruct(
  351. recordType->getDecl(), ContextUsageKind::PushConstant, structName,
  352. decl->getName());
  353. // Register the VarDecl
  354. astDecls[decl] = {var, spv::StorageClass::PushConstant,
  355. LayoutRule::GLSLStd430};
  356. // Do not push this variable into resourceVars since it does not need
  357. // descriptor set.
  358. return var;
  359. }
  360. uint32_t DeclResultIdMapper::getOrRegisterFnResultId(const FunctionDecl *fn) {
  361. if (const auto *info = getDeclSpirvInfo(fn))
  362. return info->resultId;
  363. const uint32_t id = theBuilder.getSPIRVContext()->takeNextId();
  364. astDecls[fn] = {id, spv::StorageClass::Function};
  365. return id;
  366. }
  367. uint32_t DeclResultIdMapper::getOrCreateCounterId(const ValueDecl *decl) {
  368. const auto counter = counterVars.find(decl);
  369. if (counter != counterVars.end())
  370. return counter->second;
  371. return createCounterVar(decl);
  372. }
  373. uint32_t DeclResultIdMapper::createCounterVar(const ValueDecl *decl) {
  374. const auto *info = getDeclSpirvInfo(decl);
  375. const uint32_t counterType = typeTranslator.getACSBufferCounter();
  376. const std::string counterName = "counter.var." + decl->getName().str();
  377. const uint32_t counterId =
  378. theBuilder.addModuleVar(counterType, info->storageClass, counterName);
  379. resourceVars.emplace_back(counterId, ResourceVar::Category::Other,
  380. getResourceBinding(decl),
  381. decl->getAttr<VKBindingAttr>(),
  382. decl->getAttr<VKCounterBindingAttr>(), true);
  383. return counterVars[decl] = counterId;
  384. }
  385. std::vector<uint32_t> DeclResultIdMapper::collectStageVars() const {
  386. std::vector<uint32_t> vars;
  387. for (auto var : glPerVertex.getStageInVars())
  388. vars.push_back(var);
  389. for (auto var : glPerVertex.getStageOutVars())
  390. vars.push_back(var);
  391. for (const auto &var : stageVars)
  392. vars.push_back(var.getSpirvId());
  393. return vars;
  394. }
  395. namespace {
  396. /// A class for managing stage input/output locations to avoid duplicate uses of
  397. /// the same location.
  398. class LocationSet {
  399. public:
  400. /// Maximum number of locations supported
  401. // Typically we won't have that many stage input or output variables.
  402. // Using 64 should be fine here.
  403. const static uint32_t kMaxLoc = 64;
  404. LocationSet() : usedLocs(kMaxLoc, false), nextLoc(0) {}
  405. /// Uses the given location.
  406. void useLoc(uint32_t loc) { usedLocs.set(loc); }
  407. /// Uses the next available location.
  408. uint32_t useNextLoc() {
  409. while (usedLocs[nextLoc])
  410. nextLoc++;
  411. usedLocs.set(nextLoc);
  412. return nextLoc++;
  413. }
  414. /// Returns true if the given location number is already used.
  415. bool isLocUsed(uint32_t loc) { return usedLocs[loc]; }
  416. private:
  417. llvm::SmallBitVector usedLocs; ///< All previously used locations
  418. uint32_t nextLoc; ///< Next available location
  419. };
  420. /// A class for managing resource bindings to avoid duplicate uses of the same
  421. /// set and binding number.
  422. class BindingSet {
  423. public:
  424. /// Tries to use the given set and binding number. Returns true if possible,
  425. /// false otherwise.
  426. bool tryToUseBinding(uint32_t binding, uint32_t set,
  427. ResourceVar::Category category) {
  428. const auto cat = static_cast<uint32_t>(category);
  429. // Note that we will create the entry for binding in bindings[set] here.
  430. // But that should not have bad effects since it defaults to zero.
  431. if ((usedBindings[set][binding] & cat) == 0) {
  432. usedBindings[set][binding] |= cat;
  433. return true;
  434. }
  435. return false;
  436. }
  437. /// Uses the next avaiable binding number in set 0.
  438. uint32_t useNextBinding(uint32_t set, ResourceVar::Category category) {
  439. auto &binding = usedBindings[set];
  440. auto &next = nextBindings[set];
  441. while (binding.count(next))
  442. ++next;
  443. binding[next] = static_cast<uint32_t>(category);
  444. return next++;
  445. }
  446. private:
  447. ///< set number -> (binding number -> resource category)
  448. llvm::DenseMap<uint32_t, llvm::DenseMap<uint32_t, uint32_t>> usedBindings;
  449. ///< set number -> next available binding number
  450. llvm::DenseMap<uint32_t, uint32_t> nextBindings;
  451. };
  452. } // namespace
  453. bool DeclResultIdMapper::checkSemanticDuplication(bool forInput) {
  454. llvm::StringSet<> seenSemantics;
  455. bool success = true;
  456. for (const auto &var : stageVars) {
  457. auto s = var.getSemanticStr();
  458. if (forInput && var.getSigPoint()->IsInput()) {
  459. if (seenSemantics.count(s)) {
  460. emitError("input semantic '%0' used more than once", {}) << s;
  461. success = false;
  462. }
  463. seenSemantics.insert(s);
  464. } else if (!forInput && var.getSigPoint()->IsOutput()) {
  465. if (seenSemantics.count(s)) {
  466. emitError("output semantic '%0' used more than once", {}) << s;
  467. success = false;
  468. }
  469. seenSemantics.insert(s);
  470. }
  471. }
  472. return success;
  473. }
  474. bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) {
  475. if (!checkSemanticDuplication(forInput))
  476. return false;
  477. // Returns false if the given StageVar is an input/output variable without
  478. // explicit location assignment. Otherwise, returns true.
  479. const auto locAssigned = [forInput, this](const StageVar &v) {
  480. if (forInput == isInputStorageClass(v))
  481. // No need to assign location for builtins. Treat as assigned.
  482. return v.isSpirvBuitin() || v.getLocationAttr() != nullptr;
  483. // For the ones we don't care, treat as assigned.
  484. return true;
  485. };
  486. // If we have explicit location specified for all input/output variables,
  487. // use them instead assign by ourselves.
  488. if (std::all_of(stageVars.begin(), stageVars.end(), locAssigned)) {
  489. LocationSet locSet;
  490. bool noError = true;
  491. for (const auto &var : stageVars) {
  492. // Skip those stage variables we are not handling for this call
  493. if (forInput != isInputStorageClass(var))
  494. continue;
  495. // Skip builtins
  496. if (var.isSpirvBuitin())
  497. continue;
  498. const auto *attr = var.getLocationAttr();
  499. const auto loc = attr->getNumber();
  500. const auto attrLoc = attr->getLocation(); // Attr source code location
  501. if (loc >= LocationSet::kMaxLoc) {
  502. emitError("stage %select{output|input}0 location #%1 too large",
  503. attrLoc)
  504. << forInput << loc;
  505. return false;
  506. }
  507. // Make sure the same location is not assigned more than once
  508. if (locSet.isLocUsed(loc)) {
  509. emitError("stage %select{output|input}0 location #%1 already assigned",
  510. attrLoc)
  511. << forInput << loc;
  512. noError = false;
  513. }
  514. locSet.useLoc(loc);
  515. theBuilder.decorateLocation(var.getSpirvId(), loc);
  516. }
  517. return noError;
  518. }
  519. std::vector<const StageVar *> vars;
  520. LocationSet locSet;
  521. for (const auto &var : stageVars) {
  522. if (forInput != isInputStorageClass(var))
  523. continue;
  524. if (!var.isSpirvBuitin()) {
  525. if (var.getLocationAttr() != nullptr) {
  526. // We have checked that not all of the stage variables have explicit
  527. // location assignment.
  528. emitError("partial explicit stage %select{output|input}0 location "
  529. "assignment via [[vk::location(X)]] unsupported",
  530. {})
  531. << forInput;
  532. return false;
  533. }
  534. // Only SV_Target, SV_Depth, SV_DepthLessEqual, SV_DepthGreaterEqual,
  535. // SV_StencilRef, SV_Coverage are allowed in the pixel shader.
  536. // Arbitrary semantics are disallowed in pixel shader.
  537. if (var.getSemantic() &&
  538. var.getSemantic()->GetKind() == hlsl::Semantic::Kind::Target) {
  539. theBuilder.decorateLocation(var.getSpirvId(), var.getSemanticIndex());
  540. locSet.useLoc(var.getSemanticIndex());
  541. } else {
  542. vars.push_back(&var);
  543. }
  544. }
  545. }
  546. if (spirvOptions.stageIoOrder == "alpha") {
  547. // Sort stage input/output variables alphabetically
  548. std::sort(vars.begin(), vars.end(),
  549. [](const StageVar *a, const StageVar *b) {
  550. return a->getSemanticStr() < b->getSemanticStr();
  551. });
  552. }
  553. for (const auto *var : vars)
  554. theBuilder.decorateLocation(var->getSpirvId(), locSet.useNextLoc());
  555. return true;
  556. }
  557. namespace {
  558. /// A class for maintaining the binding number shift requested for descriptor
  559. /// sets.
  560. class BindingShiftMapper {
  561. public:
  562. explicit BindingShiftMapper(const llvm::SmallVectorImpl<uint32_t> &shifts)
  563. : masterShift(0) {
  564. assert(shifts.size() % 2 == 0);
  565. for (uint32_t i = 0; i < shifts.size(); i += 2)
  566. perSetShift[shifts[i + 1]] = shifts[i];
  567. }
  568. /// Returns the shift amount for the given set.
  569. uint32_t getShiftForSet(uint32_t set) const {
  570. const auto found = perSetShift.find(set);
  571. if (found != perSetShift.end())
  572. return found->second;
  573. return masterShift;
  574. }
  575. private:
  576. uint32_t masterShift; /// Shift amount applies to all sets.
  577. llvm::DenseMap<uint32_t, uint32_t> perSetShift;
  578. };
  579. }
  580. bool DeclResultIdMapper::decorateResourceBindings() {
  581. // For normal resource, we support 3 approaches of setting binding numbers:
  582. // - m1: [[vk::binding(...)]]
  583. // - m2: :register(...)
  584. // - m3: None
  585. //
  586. // For associated counters, we support 2 approaches:
  587. // - c1: [[vk::counter_binding(...)]
  588. // - c2: None
  589. //
  590. // In combination, we need to handle 9 cases:
  591. // - 3 cases for nomral resoures (m1, m2, m3)
  592. // - 6 cases for associated counters (mX * cY)
  593. //
  594. // In the following order:
  595. // - m1, mX * c1
  596. // - m2
  597. // - m3, mX * c2
  598. BindingSet bindingSet;
  599. bool noError = true;
  600. // Tries to decorate the given varId of the given category with set number
  601. // setNo, binding number bindingNo. Emits error on failure.
  602. const auto tryToDecorate = [this, &bindingSet, &noError](
  603. const uint32_t varId, const uint32_t setNo, const uint32_t bindingNo,
  604. const ResourceVar::Category cat, SourceLocation loc) {
  605. if (bindingSet.tryToUseBinding(bindingNo, setNo, cat)) {
  606. theBuilder.decorateDSetBinding(varId, setNo, bindingNo);
  607. } else {
  608. emitError("resource binding #%0 in descriptor set #%1 already assigned",
  609. loc)
  610. << bindingNo << setNo;
  611. noError = false;
  612. }
  613. };
  614. for (const auto &var : resourceVars) {
  615. if (var.isCounter()) {
  616. if (const auto *vkCBinding = var.getCounterBinding()) {
  617. // Process mX * c1
  618. uint32_t set = 0;
  619. if (const auto *vkBinding = var.getBinding())
  620. set = vkBinding->getSet();
  621. if (const auto *reg = var.getRegister())
  622. set = reg->RegisterSpace;
  623. tryToDecorate(var.getSpirvId(), set, vkCBinding->getBinding(),
  624. var.getCategory(), vkCBinding->getLocation());
  625. }
  626. } else {
  627. if (const auto *vkBinding = var.getBinding()) {
  628. // Process m1
  629. tryToDecorate(var.getSpirvId(), vkBinding->getSet(),
  630. vkBinding->getBinding(), var.getCategory(),
  631. vkBinding->getLocation());
  632. }
  633. }
  634. }
  635. BindingShiftMapper bShiftMapper(spirvOptions.bShift);
  636. BindingShiftMapper tShiftMapper(spirvOptions.tShift);
  637. BindingShiftMapper sShiftMapper(spirvOptions.sShift);
  638. BindingShiftMapper uShiftMapper(spirvOptions.uShift);
  639. // Process m2
  640. for (const auto &var : resourceVars)
  641. if (!var.isCounter() && !var.getBinding())
  642. if (const auto *reg = var.getRegister()) {
  643. const uint32_t set = reg->RegisterSpace;
  644. uint32_t binding = reg->RegisterNumber;
  645. switch (reg->RegisterType) {
  646. case 'b':
  647. binding += bShiftMapper.getShiftForSet(set);
  648. break;
  649. case 't':
  650. binding += tShiftMapper.getShiftForSet(set);
  651. break;
  652. case 's':
  653. binding += sShiftMapper.getShiftForSet(set);
  654. break;
  655. case 'u':
  656. binding += uShiftMapper.getShiftForSet(set);
  657. break;
  658. case 'c':
  659. // For setting packing offset. Does not affect binding.
  660. break;
  661. default:
  662. llvm_unreachable("unknown register type found");
  663. }
  664. tryToDecorate(var.getSpirvId(), set, binding, var.getCategory(),
  665. reg->Loc);
  666. }
  667. for (const auto &var : resourceVars) {
  668. const auto cat = var.getCategory();
  669. if (var.isCounter()) {
  670. if (!var.getCounterBinding()) {
  671. // Process mX * c2
  672. uint32_t set = 0;
  673. if (const auto *vkBinding = var.getBinding())
  674. set = vkBinding->getSet();
  675. else if (const auto *reg = var.getRegister())
  676. set = reg->RegisterSpace;
  677. theBuilder.decorateDSetBinding(var.getSpirvId(), set,
  678. bindingSet.useNextBinding(set, cat));
  679. }
  680. } else if (!var.getBinding() && !var.getRegister()) {
  681. // Process m3
  682. theBuilder.decorateDSetBinding(var.getSpirvId(), 0,
  683. bindingSet.useNextBinding(0, cat));
  684. }
  685. }
  686. return noError;
  687. }
  688. bool DeclResultIdMapper::createStageVars(
  689. const hlsl::SigPoint *sigPoint, const DeclaratorDecl *decl, bool asInput,
  690. QualType type, uint32_t arraySize, const llvm::Twine &namePrefix,
  691. llvm::Optional<uint32_t> invocationId, uint32_t *value, bool noWriteBack) {
  692. // invocationId should only be used for handling HS per-vertex output.
  693. if (invocationId.hasValue()) {
  694. assert(shaderModel.IsHS() && arraySize != 0 && !asInput);
  695. }
  696. if (type->isVoidType()) {
  697. // No stage variables will be created for void type.
  698. return true;
  699. }
  700. uint32_t typeId = typeTranslator.translateType(type);
  701. llvm::StringRef semanticStr;
  702. const hlsl::Semantic *semantic = {};
  703. uint32_t semanticIndex = {};
  704. SourceLocation semanticLoc = {};
  705. if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
  706. &semanticLoc)) {
  707. const auto semanticKind = semantic->GetKind();
  708. // Found semantic attached directly to this Decl. This means we need to
  709. // map this decl to a single stage variable.
  710. // Error out when the given semantic is invalid in this shader model
  711. if (hlsl::SigPoint::GetInterpretation(semanticKind, sigPoint->GetKind(),
  712. shaderModel.GetMajor(),
  713. shaderModel.GetMinor()) ==
  714. hlsl::DXIL::SemanticInterpretationKind::NA) {
  715. emitError("invalid usage of semantic '%0' in shader profile %1",
  716. decl->getLocation())
  717. << semanticStr << shaderModel.GetName();
  718. return false;
  719. }
  720. // Special handling of certain mappings between HLSL semantics and
  721. // SPIR-V builtins:
  722. // * SV_Position/SV_CullDistance/SV_ClipDistance should be grouped into the
  723. // gl_PerVertex struct in vertex processing stages.
  724. // * SV_DomainLocation can refer to a float2, whereas TessCoord is a float3.
  725. // To ensure SPIR-V validity, we must create a float3 and extract a
  726. // float2 from it before passing it to the main function.
  727. // * SV_TessFactor is an array of size 2 for isoline patch, array of size 3
  728. // for tri patch, and array of size 4 for quad patch, but it must always
  729. // be an array of size 4 in SPIR-V for Vulkan.
  730. // * SV_InsideTessFactor is a single float for tri patch, and an array of
  731. // size 2 for a quad patch, but it must always be an array of size 2 in
  732. // SPIR-V for Vulkan.
  733. // * SV_Coverage is an uint value, but the builtin it corresponds to,
  734. // SampleMask, must be an array of integers.
  735. if (glPerVertex.tryToAccess(sigPoint->GetKind(), semanticKind,
  736. semanticIndex, invocationId, value,
  737. noWriteBack))
  738. return true;
  739. const uint32_t srcTypeId = typeId; // Variable type in source code
  740. switch (semanticKind) {
  741. case hlsl::Semantic::Kind::DomainLocation:
  742. typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 3);
  743. break;
  744. case hlsl::Semantic::Kind::TessFactor:
  745. typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
  746. theBuilder.getConstantUint32(4));
  747. break;
  748. case hlsl::Semantic::Kind::InsideTessFactor:
  749. typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
  750. theBuilder.getConstantUint32(2));
  751. break;
  752. case hlsl::Semantic::Kind::Coverage:
  753. typeId = theBuilder.getArrayType(typeId, theBuilder.getConstantUint32(1));
  754. break;
  755. }
  756. // Handle the extra arrayness
  757. const uint32_t elementTypeId = typeId; // Array element's type
  758. if (arraySize != 0)
  759. typeId = theBuilder.getArrayType(typeId,
  760. theBuilder.getConstantUint32(arraySize));
  761. StageVar stageVar(sigPoint, semanticStr, semantic, semanticIndex, typeId);
  762. llvm::Twine name = namePrefix + "." + semanticStr;
  763. const uint32_t varId = createSpirvStageVar(&stageVar, name, semanticLoc);
  764. if (varId == 0)
  765. return false;
  766. stageVar.setSpirvId(varId);
  767. stageVar.setLocationAttr(decl->getAttr<VKLocationAttr>());
  768. stageVars.push_back(stageVar);
  769. stageVarIds[decl] = varId;
  770. // TODO: the following may not be correct?
  771. if (sigPoint->GetSignatureKind() ==
  772. hlsl::DXIL::SignatureKind::PatchConstant)
  773. theBuilder.decorate(varId, spv::Decoration::Patch);
  774. // Decorate with interpolation modes for pixel shader input variables
  775. if (shaderModel.IsPS() && sigPoint->IsInput())
  776. decoratePSInterpolationMode(decl, type, varId);
  777. if (asInput) {
  778. *value = theBuilder.createLoad(typeId, varId);
  779. // Fix ups for corner cases
  780. // Special handling of SV_TessFactor DS patch constant input.
  781. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  782. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  783. // relevant indexes must be loaded.
  784. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  785. hlsl::GetArraySize(type) != 4) {
  786. llvm::SmallVector<uint32_t, 4> components;
  787. const auto f32TypeId = theBuilder.getFloat32Type();
  788. const auto tessFactorSize = hlsl::GetArraySize(type);
  789. const auto arrType = theBuilder.getArrayType(
  790. f32TypeId, theBuilder.getConstantUint32(tessFactorSize));
  791. for (uint32_t i = 0; i < tessFactorSize; ++i)
  792. components.push_back(
  793. theBuilder.createCompositeExtract(f32TypeId, *value, {i}));
  794. *value = theBuilder.createCompositeConstruct(arrType, components);
  795. }
  796. // Special handling of SV_InsideTessFactor DS patch constant input.
  797. // TessLevelInner is always an array of size 2 in SPIR-V, but
  798. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  799. // HLSL. If SV_InsideTessFactor is a scalar, only extract index 0 of
  800. // TessLevelInner.
  801. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  802. !type->isArrayType()) {
  803. *value = theBuilder.createCompositeExtract(theBuilder.getFloat32Type(),
  804. *value, {0});
  805. }
  806. // SV_DomainLocation can refer to a float2 or a float3, whereas TessCoord
  807. // is always a float3. To ensure SPIR-V validity, a float3 stage variable
  808. // is created, and we must extract a float2 from it before passing it to
  809. // the main function.
  810. else if (semanticKind == hlsl::Semantic::Kind::DomainLocation &&
  811. hlsl::GetHLSLVecSize(type) != 3) {
  812. const auto domainLocSize = hlsl::GetHLSLVecSize(type);
  813. *value = theBuilder.createVectorShuffle(
  814. theBuilder.getVecType(theBuilder.getFloat32Type(), domainLocSize),
  815. *value, *value, {0, 1});
  816. }
  817. // Special handling of SV_Coverage, which is an uint value. We need to
  818. // read SampleMask and extract its first element.
  819. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  820. *value = theBuilder.createCompositeExtract(srcTypeId, *value, {0});
  821. }
  822. } else {
  823. if (noWriteBack)
  824. return true;
  825. uint32_t ptr = varId;
  826. // Special handling of SV_TessFactor HS patch constant output.
  827. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  828. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  829. // relevant indexes must be written to.
  830. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  831. hlsl::GetArraySize(type) != 4) {
  832. const auto f32TypeId = theBuilder.getFloat32Type();
  833. const auto tessFactorSize = hlsl::GetArraySize(type);
  834. for (uint32_t i = 0; i < tessFactorSize; ++i) {
  835. const uint32_t ptrType =
  836. theBuilder.getPointerType(f32TypeId, spv::StorageClass::Output);
  837. ptr = theBuilder.createAccessChain(ptrType, varId,
  838. theBuilder.getConstantUint32(i));
  839. theBuilder.createStore(
  840. ptr, theBuilder.createCompositeExtract(f32TypeId, *value, i));
  841. }
  842. }
  843. // Special handling of SV_InsideTessFactor HS patch constant output.
  844. // TessLevelInner is always an array of size 2 in SPIR-V, but
  845. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  846. // HLSL. If SV_InsideTessFactor is a scalar, only write to index 0 of
  847. // TessLevelInner.
  848. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  849. !type->isArrayType()) {
  850. ptr = theBuilder.createAccessChain(
  851. theBuilder.getPointerType(theBuilder.getFloat32Type(),
  852. spv::StorageClass::Output),
  853. varId, theBuilder.getConstantUint32(0));
  854. theBuilder.createStore(ptr, *value);
  855. }
  856. // Special handling of SV_Coverage, which is an unit value. We need to
  857. // write it to the first element in the SampleMask builtin.
  858. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  859. ptr = theBuilder.createAccessChain(
  860. theBuilder.getPointerType(srcTypeId, spv::StorageClass::Output),
  861. varId, theBuilder.getConstantUint32(0));
  862. theBuilder.createStore(ptr, *value);
  863. }
  864. // Special handling of HS ouput, for which we write to only one
  865. // element in the per-vertex data array: the one indexed by
  866. // SV_ControlPointID.
  867. else if (invocationId.hasValue()) {
  868. const uint32_t ptrType =
  869. theBuilder.getPointerType(elementTypeId, spv::StorageClass::Output);
  870. const uint32_t index = invocationId.getValue();
  871. ptr = theBuilder.createAccessChain(ptrType, varId, index);
  872. theBuilder.createStore(ptr, *value);
  873. }
  874. // For all normal cases
  875. else {
  876. theBuilder.createStore(ptr, *value);
  877. }
  878. }
  879. return true;
  880. }
  881. // If the decl itself doesn't have semantic string attached, it should be
  882. // a struct having all its fields with semantic strings.
  883. if (!type->isStructureType()) {
  884. emitError("semantic string missing for shader %select{output|input}0 "
  885. "variable '%1'",
  886. decl->getLocation())
  887. << asInput << decl->getName();
  888. return false;
  889. }
  890. const auto *structDecl = cast<RecordType>(type.getTypePtr())->getDecl();
  891. if (asInput) {
  892. // If this decl translates into multiple stage input variables, we need to
  893. // load their values into a composite.
  894. llvm::SmallVector<uint32_t, 4> subValues;
  895. for (const auto *field : structDecl->fields()) {
  896. uint32_t subValue = 0;
  897. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  898. arraySize, namePrefix, invocationId, &subValue,
  899. noWriteBack))
  900. return false;
  901. subValues.push_back(subValue);
  902. }
  903. if (arraySize == 0) {
  904. *value = theBuilder.createCompositeConstruct(typeId, subValues);
  905. return true;
  906. }
  907. // Handle the extra level of arrayness.
  908. // We need to return an array of structs. But we get arrays of fields
  909. // from visiting all fields. So now we need to extract all the elements
  910. // at the same index of each field arrays and compose a new struct out
  911. // of them.
  912. const uint32_t structType = typeTranslator.translateType(type);
  913. const uint32_t arrayType = theBuilder.getArrayType(
  914. structType, theBuilder.getConstantUint32(arraySize));
  915. llvm::SmallVector<uint32_t, 16> arrayElements;
  916. for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) {
  917. llvm::SmallVector<uint32_t, 8> fields;
  918. // Extract the element at index arrayIndex from each field
  919. for (const auto *field : structDecl->fields()) {
  920. const uint32_t fieldType =
  921. typeTranslator.translateType(field->getType());
  922. fields.push_back(theBuilder.createCompositeExtract(
  923. fieldType, subValues[field->getFieldIndex()], {arrayIndex}));
  924. }
  925. // Compose a new struct out of them
  926. arrayElements.push_back(
  927. theBuilder.createCompositeConstruct(structType, fields));
  928. }
  929. *value = theBuilder.createCompositeConstruct(arrayType, arrayElements);
  930. } else {
  931. // Unlike reading, which may require us to read stand-alone builtins and
  932. // stage input variables and compose an array of structs out of them,
  933. // it happens that we don't need to write an array of structs in a bunch
  934. // for all shader stages:
  935. //
  936. // * VS: output is a single struct, without extra arrayness
  937. // * HS: output is an array of structs, with extra arrayness,
  938. // but we only write to the struct at the InvocationID index
  939. // * DS: output is a single struct, without extra arrayness
  940. // * GS: output is controlled by OpEmitVertex, one vertex per time
  941. //
  942. // The interesting shader stage is HS. We need the InvocationID to write
  943. // out the value to the correct array element.
  944. for (const auto *field : structDecl->fields()) {
  945. const uint32_t fieldType = typeTranslator.translateType(field->getType());
  946. uint32_t subValue = 0;
  947. if (!noWriteBack)
  948. subValue = theBuilder.createCompositeExtract(fieldType, *value,
  949. {field->getFieldIndex()});
  950. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  951. arraySize, namePrefix, invocationId, &subValue,
  952. noWriteBack))
  953. return false;
  954. }
  955. }
  956. return true;
  957. }
  958. bool DeclResultIdMapper::writeBackOutputStream(const ValueDecl *decl,
  959. uint32_t value) {
  960. assert(shaderModel.IsGS()); // Only for GS use
  961. QualType type = decl->getType();
  962. if (hlsl::IsHLSLStreamOutputType(type))
  963. type = hlsl::GetHLSLResourceResultType(type);
  964. if (hasGSPrimitiveTypeQualifier(decl))
  965. type = astContext.getAsConstantArrayType(type)->getElementType();
  966. llvm::StringRef semanticStr;
  967. const hlsl::Semantic *semantic = {};
  968. uint32_t semanticIndex = {};
  969. SourceLocation semanticLoc = {};
  970. if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
  971. &semanticLoc)) {
  972. // Found semantic attached directly to this Decl. Write the value for this
  973. // Decl to the corresponding stage output variable.
  974. const uint32_t srcTypeId = typeTranslator.translateType(type);
  975. // Handle SV_Position, SV_ClipDistance, and SV_CullDistance
  976. if (glPerVertex.tryToAccess(hlsl::DXIL::SigPointKind::GSOut,
  977. semantic->GetKind(), semanticIndex, llvm::None,
  978. &value, /*noWriteBack=*/false))
  979. return true;
  980. // Query the <result-id> for the stage output variable generated out
  981. // of this decl.
  982. const auto found = stageVarIds.find(decl);
  983. // We should have recorded its stage output variable previously.
  984. assert(found != stageVarIds.end());
  985. theBuilder.createStore(found->second, value);
  986. return true;
  987. }
  988. // If the decl itself doesn't have semantic string attached, it should be
  989. // a struct having all its fields with semantic strings.
  990. if (!type->isStructureType()) {
  991. emitError("semantic string missing for shader output variable '%0'",
  992. decl->getLocation())
  993. << decl->getName();
  994. return false;
  995. }
  996. const auto *structDecl = cast<RecordType>(type.getTypePtr())->getDecl();
  997. // Write out each field
  998. for (const auto *field : structDecl->fields()) {
  999. const uint32_t fieldType = typeTranslator.translateType(field->getType());
  1000. const uint32_t subValue = theBuilder.createCompositeExtract(
  1001. fieldType, value, {field->getFieldIndex()});
  1002. if (!writeBackOutputStream(field, subValue))
  1003. return false;
  1004. }
  1005. return true;
  1006. }
  1007. void DeclResultIdMapper::decoratePSInterpolationMode(const DeclaratorDecl *decl,
  1008. QualType type,
  1009. uint32_t varId) {
  1010. const QualType elemType = typeTranslator.getElementType(type);
  1011. if (elemType->isBooleanType() || elemType->isIntegerType()) {
  1012. // TODO: Probably we can call hlsl::ValidateSignatureElement() for the
  1013. // following check.
  1014. if (decl->getAttr<HLSLLinearAttr>() || decl->getAttr<HLSLCentroidAttr>() ||
  1015. decl->getAttr<HLSLNoPerspectiveAttr>() ||
  1016. decl->getAttr<HLSLSampleAttr>()) {
  1017. emitError("only nointerpolation mode allowed for integer input "
  1018. "parameters in pixel shader",
  1019. decl->getLocation());
  1020. } else {
  1021. theBuilder.decorate(varId, spv::Decoration::Flat);
  1022. }
  1023. } else {
  1024. // Do nothing for HLSLLinearAttr since its the default
  1025. // Attributes can be used together. So cannot use else if.
  1026. if (decl->getAttr<HLSLCentroidAttr>())
  1027. theBuilder.decorate(varId, spv::Decoration::Centroid);
  1028. if (decl->getAttr<HLSLNoInterpolationAttr>())
  1029. theBuilder.decorate(varId, spv::Decoration::Flat);
  1030. if (decl->getAttr<HLSLNoPerspectiveAttr>())
  1031. theBuilder.decorate(varId, spv::Decoration::NoPerspective);
  1032. if (decl->getAttr<HLSLSampleAttr>()) {
  1033. theBuilder.requireCapability(spv::Capability::SampleRateShading);
  1034. theBuilder.decorate(varId, spv::Decoration::Sample);
  1035. }
  1036. }
  1037. }
  1038. uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
  1039. const llvm::Twine &name,
  1040. SourceLocation srcLoc) {
  1041. using spv::BuiltIn;
  1042. const auto sigPoint = stageVar->getSigPoint();
  1043. const auto semanticKind = stageVar->getSemantic()->GetKind();
  1044. const auto sigPointKind = sigPoint->GetKind();
  1045. const uint32_t type = stageVar->getSpirvTypeId();
  1046. spv::StorageClass sc = getStorageClassForSigPoint(sigPoint);
  1047. if (sc == spv::StorageClass::Max)
  1048. return 0;
  1049. stageVar->setStorageClass(sc);
  1050. // The following translation assumes that semantic validity in the current
  1051. // shader model is already checked, so it only covers valid SigPoints for
  1052. // each semantic.
  1053. switch (semanticKind) {
  1054. // According to DXIL spec, the Position SV can be used by all SigPoints
  1055. // other than PCIn, HSIn, GSIn, PSOut, CSIn.
  1056. // According to Vulkan spec, the Position BuiltIn can only be used
  1057. // by VSOut, HS/DS/GS In/Out.
  1058. case hlsl::Semantic::Kind::Position: {
  1059. switch (sigPointKind) {
  1060. case hlsl::SigPoint::Kind::VSIn:
  1061. case hlsl::SigPoint::Kind::PCOut:
  1062. case hlsl::SigPoint::Kind::DSIn:
  1063. return theBuilder.addStageIOVar(type, sc, name.str());
  1064. case hlsl::SigPoint::Kind::VSOut:
  1065. case hlsl::SigPoint::Kind::HSCPIn:
  1066. case hlsl::SigPoint::Kind::HSCPOut:
  1067. case hlsl::SigPoint::Kind::DSCPIn:
  1068. case hlsl::SigPoint::Kind::DSOut:
  1069. case hlsl::SigPoint::Kind::GSVIn:
  1070. llvm_unreachable("should be handled in gl_PerVertex struct");
  1071. case hlsl::SigPoint::Kind::GSOut:
  1072. stageVar->setIsSpirvBuiltin();
  1073. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::Position);
  1074. case hlsl::SigPoint::Kind::PSIn:
  1075. stageVar->setIsSpirvBuiltin();
  1076. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragCoord);
  1077. default:
  1078. llvm_unreachable("invalid usage of SV_Position sneaked in");
  1079. }
  1080. }
  1081. // According to DXIL spec, the VertexID SV can only be used by VSIn.
  1082. // According to Vulkan spec, the VertexIndex BuiltIn can only be used by
  1083. // VSIn.
  1084. case hlsl::Semantic::Kind::VertexID: {
  1085. stageVar->setIsSpirvBuiltin();
  1086. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::VertexIndex);
  1087. }
  1088. // According to DXIL spec, the InstanceID SV can be used by VSIn, VSOut,
  1089. // HSCPIn, HSCPOut, DSCPIn, DSOut, GSVIn, GSOut, PSIn.
  1090. // According to Vulkan spec, the InstanceIndex BuitIn can only be used by
  1091. // VSIn.
  1092. case hlsl::Semantic::Kind::InstanceID: {
  1093. switch (sigPointKind) {
  1094. case hlsl::SigPoint::Kind::VSIn:
  1095. stageVar->setIsSpirvBuiltin();
  1096. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InstanceIndex);
  1097. case hlsl::SigPoint::Kind::VSOut:
  1098. case hlsl::SigPoint::Kind::HSCPIn:
  1099. case hlsl::SigPoint::Kind::HSCPOut:
  1100. case hlsl::SigPoint::Kind::DSCPIn:
  1101. case hlsl::SigPoint::Kind::DSOut:
  1102. case hlsl::SigPoint::Kind::GSVIn:
  1103. case hlsl::SigPoint::Kind::GSOut:
  1104. case hlsl::SigPoint::Kind::PSIn:
  1105. return theBuilder.addStageIOVar(type, sc, name.str());
  1106. default:
  1107. llvm_unreachable("invalid usage of SV_InstanceID sneaked in");
  1108. }
  1109. }
  1110. // According to DXIL spec, the Depth{|GreaterEqual|LessEqual} SV can only be
  1111. // used by PSOut.
  1112. // According to Vulkan spec, the FragDepth BuiltIn can only be used by PSOut.
  1113. case hlsl::Semantic::Kind::Depth:
  1114. case hlsl::Semantic::Kind::DepthGreaterEqual:
  1115. case hlsl::Semantic::Kind::DepthLessEqual: {
  1116. stageVar->setIsSpirvBuiltin();
  1117. if (semanticKind == hlsl::Semantic::Kind::DepthGreaterEqual)
  1118. theBuilder.addExecutionMode(entryFunctionId,
  1119. spv::ExecutionMode::DepthGreater, {});
  1120. else if (semanticKind == hlsl::Semantic::Kind::DepthLessEqual)
  1121. theBuilder.addExecutionMode(entryFunctionId,
  1122. spv::ExecutionMode::DepthLess, {});
  1123. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragDepth);
  1124. }
  1125. // According to DXIL spec, the ClipDistance/CullDistance SV can be used by all
  1126. // SigPoints other than PCIn, HSIn, GSIn, PSOut, CSIn.
  1127. // According to Vulkan spec, the ClipDistance/CullDistance BuiltIn can only
  1128. // be
  1129. // used by VSOut, HS/DS/GS In/Out.
  1130. case hlsl::Semantic::Kind::ClipDistance:
  1131. case hlsl::Semantic::Kind::CullDistance: {
  1132. switch (sigPointKind) {
  1133. case hlsl::SigPoint::Kind::VSIn:
  1134. case hlsl::SigPoint::Kind::PCOut:
  1135. case hlsl::SigPoint::Kind::DSIn:
  1136. return theBuilder.addStageIOVar(type, sc, name.str());
  1137. case hlsl::SigPoint::Kind::VSOut:
  1138. case hlsl::SigPoint::Kind::HSCPIn:
  1139. case hlsl::SigPoint::Kind::HSCPOut:
  1140. case hlsl::SigPoint::Kind::DSCPIn:
  1141. case hlsl::SigPoint::Kind::DSOut:
  1142. case hlsl::SigPoint::Kind::GSVIn:
  1143. case hlsl::SigPoint::Kind::GSOut:
  1144. case hlsl::SigPoint::Kind::PSIn:
  1145. llvm_unreachable("should be handled in gl_PerVertex struct");
  1146. default:
  1147. llvm_unreachable(
  1148. "invalid usage of SV_ClipDistance/SV_CullDistance sneaked in");
  1149. }
  1150. }
  1151. // According to DXIL spec, the IsFrontFace SV can only be used by GSOut and
  1152. // PSIn.
  1153. // According to Vulkan spec, the FrontFacing BuitIn can only be used in PSIn.
  1154. case hlsl::Semantic::Kind::IsFrontFace: {
  1155. switch (sigPointKind) {
  1156. case hlsl::SigPoint::Kind::GSOut:
  1157. return theBuilder.addStageIOVar(type, sc, name.str());
  1158. case hlsl::SigPoint::Kind::PSIn:
  1159. stageVar->setIsSpirvBuiltin();
  1160. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FrontFacing);
  1161. default:
  1162. llvm_unreachable("invalid usage of SV_IsFrontFace sneaked in");
  1163. }
  1164. }
  1165. // According to DXIL spec, the Target SV can only be used by PSOut.
  1166. // There is no corresponding builtin decoration in SPIR-V. So generate normal
  1167. // Vulkan stage input/output variables.
  1168. case hlsl::Semantic::Kind::Target:
  1169. // An arbitrary semantic is defined by users. Generate normal Vulkan stage
  1170. // input/output variables.
  1171. case hlsl::Semantic::Kind::Arbitrary: {
  1172. return theBuilder.addStageIOVar(type, sc, name.str());
  1173. // TODO: patch constant function in hull shader
  1174. }
  1175. // According to DXIL spec, the DispatchThreadID SV can only be used by CSIn.
  1176. // According to Vulkan spec, the GlobalInvocationId can only be used in CSIn.
  1177. case hlsl::Semantic::Kind::DispatchThreadID: {
  1178. stageVar->setIsSpirvBuiltin();
  1179. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::GlobalInvocationId);
  1180. }
  1181. // According to DXIL spec, the GroupID SV can only be used by CSIn.
  1182. // According to Vulkan spec, the WorkgroupId can only be used in CSIn.
  1183. case hlsl::Semantic::Kind::GroupID: {
  1184. stageVar->setIsSpirvBuiltin();
  1185. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::WorkgroupId);
  1186. }
  1187. // According to DXIL spec, the GroupThreadID SV can only be used by CSIn.
  1188. // According to Vulkan spec, the LocalInvocationId can only be used in CSIn.
  1189. case hlsl::Semantic::Kind::GroupThreadID: {
  1190. stageVar->setIsSpirvBuiltin();
  1191. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::LocalInvocationId);
  1192. }
  1193. // According to DXIL spec, the GroupIndex SV can only be used by CSIn.
  1194. // According to Vulkan spec, the LocalInvocationIndex can only be used in
  1195. // CSIn.
  1196. case hlsl::Semantic::Kind::GroupIndex: {
  1197. stageVar->setIsSpirvBuiltin();
  1198. return theBuilder.addStageBuiltinVar(type, sc,
  1199. BuiltIn::LocalInvocationIndex);
  1200. }
  1201. // According to DXIL spec, the OutputControlID SV can only be used by HSIn.
  1202. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  1203. // HS/GS In.
  1204. case hlsl::Semantic::Kind::OutputControlPointID: {
  1205. stageVar->setIsSpirvBuiltin();
  1206. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
  1207. }
  1208. // According to DXIL spec, the PrimitiveID SV can only be used by PCIn, HSIn,
  1209. // DSIn, GSIn, GSOut, and PSIn.
  1210. // According to Vulkan spec, the PrimitiveId BuiltIn can only be used in
  1211. // HS/DS/PS In, GS In/Out.
  1212. case hlsl::Semantic::Kind::PrimitiveID: {
  1213. // PrimitiveId requires either Tessellation or Geometry capability.
  1214. // Need to require one for PSIn.
  1215. if (sigPointKind == hlsl::SigPoint::Kind::PSIn)
  1216. theBuilder.requireCapability(spv::Capability::Geometry);
  1217. // Translate to PrimitiveId BuiltIn for all valid SigPoints.
  1218. stageVar->setIsSpirvBuiltin();
  1219. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::PrimitiveId);
  1220. }
  1221. // According to DXIL spec, the TessFactor SV can only be used by PCOut and
  1222. // DSIn.
  1223. // According to Vulkan spec, the TessLevelOuter BuiltIn can only be used in
  1224. // PCOut and DSIn.
  1225. case hlsl::Semantic::Kind::TessFactor: {
  1226. stageVar->setIsSpirvBuiltin();
  1227. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelOuter);
  1228. }
  1229. // According to DXIL spec, the InsideTessFactor SV can only be used by PCOut
  1230. // and DSIn.
  1231. // According to Vulkan spec, the TessLevelInner BuiltIn can only be used in
  1232. // PCOut and DSIn.
  1233. case hlsl::Semantic::Kind::InsideTessFactor: {
  1234. stageVar->setIsSpirvBuiltin();
  1235. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelInner);
  1236. }
  1237. // According to DXIL spec, the DomainLocation SV can only be used by DSIn.
  1238. // According to Vulkan spec, the TessCoord BuiltIn can only be used in DSIn.
  1239. case hlsl::Semantic::Kind::DomainLocation: {
  1240. stageVar->setIsSpirvBuiltin();
  1241. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessCoord);
  1242. }
  1243. // According to DXIL spec, the GSInstanceID SV can only be used by GSIn.
  1244. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  1245. // HS/GS In.
  1246. case hlsl::Semantic::Kind::GSInstanceID: {
  1247. stageVar->setIsSpirvBuiltin();
  1248. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
  1249. }
  1250. // According to DXIL spec, the SampleIndex SV can only be used by PSIn.
  1251. // According to Vulkan spec, the SampleId BuiltIn can only be used in PSIn.
  1252. case hlsl::Semantic::Kind::SampleIndex: {
  1253. theBuilder.requireCapability(spv::Capability::SampleRateShading);
  1254. stageVar->setIsSpirvBuiltin();
  1255. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleId);
  1256. }
  1257. // According to DXIL spec, the StencilRef SV can only be used by PSOut.
  1258. case hlsl::Semantic::Kind::StencilRef: {
  1259. theBuilder.addExtension("SPV_EXT_shader_stencil_export");
  1260. theBuilder.requireCapability(spv::Capability::StencilExportEXT);
  1261. stageVar->setIsSpirvBuiltin();
  1262. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragStencilRefEXT);
  1263. }
  1264. // According to DXIL spec, the RenderTargetArrayIndex SV can only be used by
  1265. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn.
  1266. // According to Vulkan spec, the Layer BuiltIn can only be used in GSOut and
  1267. // PSIn.
  1268. case hlsl::Semantic::Kind::RenderTargetArrayIndex: {
  1269. switch (sigPointKind) {
  1270. case hlsl::SigPoint::Kind::VSIn:
  1271. case hlsl::SigPoint::Kind::VSOut:
  1272. case hlsl::SigPoint::Kind::HSCPIn:
  1273. case hlsl::SigPoint::Kind::HSCPOut:
  1274. case hlsl::SigPoint::Kind::PCOut:
  1275. case hlsl::SigPoint::Kind::DSIn:
  1276. case hlsl::SigPoint::Kind::DSCPIn:
  1277. case hlsl::SigPoint::Kind::DSOut:
  1278. case hlsl::SigPoint::Kind::GSVIn:
  1279. return theBuilder.addStageIOVar(type, sc, name.str());
  1280. case hlsl::SigPoint::Kind::GSOut:
  1281. case hlsl::SigPoint::Kind::PSIn:
  1282. theBuilder.requireCapability(spv::Capability::Geometry);
  1283. stageVar->setIsSpirvBuiltin();
  1284. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::Layer);
  1285. default:
  1286. llvm_unreachable("invalid usage of SV_RenderTargetArrayIndex sneaked in");
  1287. }
  1288. }
  1289. // According to DXIL spec, the ViewportArrayIndex SV can only be used by
  1290. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn.
  1291. // According to Vulkan spec, the ViewportIndex BuiltIn can only be used in
  1292. // GSOut and PSIn.
  1293. case hlsl::Semantic::Kind::ViewPortArrayIndex: {
  1294. switch (sigPointKind) {
  1295. case hlsl::SigPoint::Kind::VSIn:
  1296. case hlsl::SigPoint::Kind::VSOut:
  1297. case hlsl::SigPoint::Kind::HSCPIn:
  1298. case hlsl::SigPoint::Kind::HSCPOut:
  1299. case hlsl::SigPoint::Kind::PCOut:
  1300. case hlsl::SigPoint::Kind::DSIn:
  1301. case hlsl::SigPoint::Kind::DSCPIn:
  1302. case hlsl::SigPoint::Kind::DSOut:
  1303. case hlsl::SigPoint::Kind::GSVIn:
  1304. return theBuilder.addStageIOVar(type, sc, name.str());
  1305. case hlsl::SigPoint::Kind::GSOut:
  1306. case hlsl::SigPoint::Kind::PSIn:
  1307. theBuilder.requireCapability(spv::Capability::MultiViewport);
  1308. stageVar->setIsSpirvBuiltin();
  1309. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::ViewportIndex);
  1310. default:
  1311. llvm_unreachable("invalid usage of SV_ViewportArrayIndex sneaked in");
  1312. }
  1313. }
  1314. // According to DXIL spec, the Coverage SV can only be used by PSIn and PSOut.
  1315. // According to Vulkan spec, the SampleMask BuiltIn can only be used in
  1316. // PSIn and PSOut.
  1317. case hlsl::Semantic::Kind::Coverage: {
  1318. stageVar->setIsSpirvBuiltin();
  1319. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleMask);
  1320. }
  1321. case hlsl::Semantic::Kind::InnerCoverage: {
  1322. emitError("no equivalent for semantic SV_InnerCoverage in Vulkan", srcLoc);
  1323. return 0;
  1324. }
  1325. default:
  1326. emitError("semantic %0 unimplemented", srcLoc)
  1327. << stageVar->getSemantic()->GetName();
  1328. break;
  1329. }
  1330. return 0;
  1331. }
  1332. spv::StorageClass
  1333. DeclResultIdMapper::getStorageClassForSigPoint(const hlsl::SigPoint *sigPoint) {
  1334. // This translation is done based on the HLSL reference (see docs/dxil.rst).
  1335. const auto sigPointKind = sigPoint->GetKind();
  1336. const auto signatureKind = sigPoint->GetSignatureKind();
  1337. spv::StorageClass sc = spv::StorageClass::Max;
  1338. switch (signatureKind) {
  1339. case hlsl::DXIL::SignatureKind::Input:
  1340. sc = spv::StorageClass::Input;
  1341. break;
  1342. case hlsl::DXIL::SignatureKind::Output:
  1343. sc = spv::StorageClass::Output;
  1344. break;
  1345. case hlsl::DXIL::SignatureKind::Invalid: {
  1346. // There are some special cases in HLSL (See docs/dxil.rst):
  1347. // SignatureKind is "invalid" for PCIn, HSIn, GSIn, and CSIn.
  1348. switch (sigPointKind) {
  1349. case hlsl::DXIL::SigPointKind::PCIn:
  1350. case hlsl::DXIL::SigPointKind::HSIn:
  1351. case hlsl::DXIL::SigPointKind::GSIn:
  1352. case hlsl::DXIL::SigPointKind::CSIn:
  1353. sc = spv::StorageClass::Input;
  1354. break;
  1355. default:
  1356. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1357. }
  1358. break;
  1359. }
  1360. case hlsl::DXIL::SignatureKind::PatchConstant: {
  1361. // There are some special cases in HLSL (See docs/dxil.rst):
  1362. // SignatureKind is "PatchConstant" for PCOut and DSIn.
  1363. switch (sigPointKind) {
  1364. case hlsl::DXIL::SigPointKind::PCOut:
  1365. // Patch Constant Output (Output of Hull which is passed to Domain).
  1366. sc = spv::StorageClass::Output;
  1367. break;
  1368. case hlsl::DXIL::SigPointKind::DSIn:
  1369. // Domain Shader regular input - Patch Constant data plus system values.
  1370. sc = spv::StorageClass::Input;
  1371. break;
  1372. default:
  1373. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1374. }
  1375. break;
  1376. }
  1377. default:
  1378. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1379. }
  1380. return sc;
  1381. }
  1382. } // end namespace spirv
  1383. } // end namespace clang