DeclResultIdMapper.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  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 and writes the source location of where the binding number
  426. /// is used to *usedLoc.
  427. bool tryToUseBinding(uint32_t binding, uint32_t set,
  428. ResourceVar::Category category, SourceLocation tryLoc,
  429. SourceLocation *usedLoc) {
  430. const auto cat = static_cast<uint32_t>(category);
  431. // Note that we will create the entry for binding in bindings[set] here.
  432. // But that should not have bad effects since it defaults to zero.
  433. if ((usedBindings[set][binding] & cat) == 0) {
  434. usedBindings[set][binding] |= cat;
  435. whereUsed[set][binding] = tryLoc;
  436. return true;
  437. }
  438. *usedLoc = whereUsed[set][binding];
  439. return false;
  440. }
  441. /// Uses the next avaiable binding number in set 0.
  442. uint32_t useNextBinding(uint32_t set, ResourceVar::Category category) {
  443. auto &binding = usedBindings[set];
  444. auto &next = nextBindings[set];
  445. while (binding.count(next))
  446. ++next;
  447. binding[next] = static_cast<uint32_t>(category);
  448. return next++;
  449. }
  450. private:
  451. ///< set number -> (binding number -> resource category)
  452. llvm::DenseMap<uint32_t, llvm::DenseMap<uint32_t, uint32_t>> usedBindings;
  453. ///< set number -> (binding number -> source location)
  454. llvm::DenseMap<uint32_t, llvm::DenseMap<uint32_t, SourceLocation>> whereUsed;
  455. ///< set number -> next available binding number
  456. llvm::DenseMap<uint32_t, uint32_t> nextBindings;
  457. };
  458. } // namespace
  459. bool DeclResultIdMapper::checkSemanticDuplication(bool forInput) {
  460. llvm::StringSet<> seenSemantics;
  461. bool success = true;
  462. for (const auto &var : stageVars) {
  463. auto s = var.getSemanticStr();
  464. if (forInput && var.getSigPoint()->IsInput()) {
  465. if (seenSemantics.count(s)) {
  466. emitError("input semantic '%0' used more than once", {}) << s;
  467. success = false;
  468. }
  469. seenSemantics.insert(s);
  470. } else if (!forInput && var.getSigPoint()->IsOutput()) {
  471. if (seenSemantics.count(s)) {
  472. emitError("output semantic '%0' used more than once", {}) << s;
  473. success = false;
  474. }
  475. seenSemantics.insert(s);
  476. }
  477. }
  478. return success;
  479. }
  480. bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) {
  481. if (!checkSemanticDuplication(forInput))
  482. return false;
  483. // Returns false if the given StageVar is an input/output variable without
  484. // explicit location assignment. Otherwise, returns true.
  485. const auto locAssigned = [forInput, this](const StageVar &v) {
  486. if (forInput == isInputStorageClass(v))
  487. // No need to assign location for builtins. Treat as assigned.
  488. return v.isSpirvBuitin() || v.getLocationAttr() != nullptr;
  489. // For the ones we don't care, treat as assigned.
  490. return true;
  491. };
  492. // If we have explicit location specified for all input/output variables,
  493. // use them instead assign by ourselves.
  494. if (std::all_of(stageVars.begin(), stageVars.end(), locAssigned)) {
  495. LocationSet locSet;
  496. bool noError = true;
  497. for (const auto &var : stageVars) {
  498. // Skip those stage variables we are not handling for this call
  499. if (forInput != isInputStorageClass(var))
  500. continue;
  501. // Skip builtins
  502. if (var.isSpirvBuitin())
  503. continue;
  504. const auto *attr = var.getLocationAttr();
  505. const auto loc = attr->getNumber();
  506. const auto attrLoc = attr->getLocation(); // Attr source code location
  507. if (loc >= LocationSet::kMaxLoc) {
  508. emitError("stage %select{output|input}0 location #%1 too large",
  509. attrLoc)
  510. << forInput << loc;
  511. return false;
  512. }
  513. // Make sure the same location is not assigned more than once
  514. if (locSet.isLocUsed(loc)) {
  515. emitError("stage %select{output|input}0 location #%1 already assigned",
  516. attrLoc)
  517. << forInput << loc;
  518. noError = false;
  519. }
  520. locSet.useLoc(loc);
  521. theBuilder.decorateLocation(var.getSpirvId(), loc);
  522. }
  523. return noError;
  524. }
  525. std::vector<const StageVar *> vars;
  526. LocationSet locSet;
  527. for (const auto &var : stageVars) {
  528. if (forInput != isInputStorageClass(var))
  529. continue;
  530. if (!var.isSpirvBuitin()) {
  531. if (var.getLocationAttr() != nullptr) {
  532. // We have checked that not all of the stage variables have explicit
  533. // location assignment.
  534. emitError("partial explicit stage %select{output|input}0 location "
  535. "assignment via [[vk::location(X)]] unsupported",
  536. {})
  537. << forInput;
  538. return false;
  539. }
  540. // Only SV_Target, SV_Depth, SV_DepthLessEqual, SV_DepthGreaterEqual,
  541. // SV_StencilRef, SV_Coverage are allowed in the pixel shader.
  542. // Arbitrary semantics are disallowed in pixel shader.
  543. if (var.getSemantic() &&
  544. var.getSemantic()->GetKind() == hlsl::Semantic::Kind::Target) {
  545. theBuilder.decorateLocation(var.getSpirvId(), var.getSemanticIndex());
  546. locSet.useLoc(var.getSemanticIndex());
  547. } else {
  548. vars.push_back(&var);
  549. }
  550. }
  551. }
  552. if (spirvOptions.stageIoOrder == "alpha") {
  553. // Sort stage input/output variables alphabetically
  554. std::sort(vars.begin(), vars.end(),
  555. [](const StageVar *a, const StageVar *b) {
  556. return a->getSemanticStr() < b->getSemanticStr();
  557. });
  558. }
  559. for (const auto *var : vars)
  560. theBuilder.decorateLocation(var->getSpirvId(), locSet.useNextLoc());
  561. return true;
  562. }
  563. namespace {
  564. /// A class for maintaining the binding number shift requested for descriptor
  565. /// sets.
  566. class BindingShiftMapper {
  567. public:
  568. explicit BindingShiftMapper(const llvm::SmallVectorImpl<uint32_t> &shifts)
  569. : masterShift(0) {
  570. assert(shifts.size() % 2 == 0);
  571. for (uint32_t i = 0; i < shifts.size(); i += 2)
  572. perSetShift[shifts[i + 1]] = shifts[i];
  573. }
  574. /// Returns the shift amount for the given set.
  575. uint32_t getShiftForSet(uint32_t set) const {
  576. const auto found = perSetShift.find(set);
  577. if (found != perSetShift.end())
  578. return found->second;
  579. return masterShift;
  580. }
  581. private:
  582. uint32_t masterShift; /// Shift amount applies to all sets.
  583. llvm::DenseMap<uint32_t, uint32_t> perSetShift;
  584. };
  585. } // namespace
  586. bool DeclResultIdMapper::decorateResourceBindings() {
  587. // For normal resource, we support 3 approaches of setting binding numbers:
  588. // - m1: [[vk::binding(...)]]
  589. // - m2: :register(...)
  590. // - m3: None
  591. //
  592. // For associated counters, we support 2 approaches:
  593. // - c1: [[vk::counter_binding(...)]
  594. // - c2: None
  595. //
  596. // In combination, we need to handle 9 cases:
  597. // - 3 cases for nomral resoures (m1, m2, m3)
  598. // - 6 cases for associated counters (mX * cY)
  599. //
  600. // In the following order:
  601. // - m1, mX * c1
  602. // - m2
  603. // - m3, mX * c2
  604. BindingSet bindingSet;
  605. bool noError = true;
  606. // Decorates the given varId of the given category with set number
  607. // setNo, binding number bindingNo. Emits warning if overlap.
  608. const auto tryToDecorate = [this, &bindingSet, &noError](
  609. const uint32_t varId, const uint32_t setNo,
  610. const uint32_t bindingNo,
  611. const ResourceVar::Category cat,
  612. SourceLocation loc) {
  613. SourceLocation prevUseLoc;
  614. if (!bindingSet.tryToUseBinding(bindingNo, setNo, cat, loc, &prevUseLoc)) {
  615. emitWarning("resource binding #%0 in descriptor set #%1 already assigned",
  616. loc)
  617. << bindingNo << setNo;
  618. emitNote("binding number previously assigned here", prevUseLoc);
  619. // noError = false;
  620. }
  621. theBuilder.decorateDSetBinding(varId, setNo, bindingNo);
  622. };
  623. for (const auto &var : resourceVars) {
  624. if (var.isCounter()) {
  625. if (const auto *vkCBinding = var.getCounterBinding()) {
  626. // Process mX * c1
  627. uint32_t set = 0;
  628. if (const auto *vkBinding = var.getBinding())
  629. set = vkBinding->getSet();
  630. if (const auto *reg = var.getRegister())
  631. set = reg->RegisterSpace;
  632. tryToDecorate(var.getSpirvId(), set, vkCBinding->getBinding(),
  633. var.getCategory(), vkCBinding->getLocation());
  634. }
  635. } else {
  636. if (const auto *vkBinding = var.getBinding()) {
  637. // Process m1
  638. tryToDecorate(var.getSpirvId(), vkBinding->getSet(),
  639. vkBinding->getBinding(), var.getCategory(),
  640. vkBinding->getLocation());
  641. }
  642. }
  643. }
  644. BindingShiftMapper bShiftMapper(spirvOptions.bShift);
  645. BindingShiftMapper tShiftMapper(spirvOptions.tShift);
  646. BindingShiftMapper sShiftMapper(spirvOptions.sShift);
  647. BindingShiftMapper uShiftMapper(spirvOptions.uShift);
  648. // Process m2
  649. for (const auto &var : resourceVars)
  650. if (!var.isCounter() && !var.getBinding())
  651. if (const auto *reg = var.getRegister()) {
  652. const uint32_t set = reg->RegisterSpace;
  653. uint32_t binding = reg->RegisterNumber;
  654. switch (reg->RegisterType) {
  655. case 'b':
  656. binding += bShiftMapper.getShiftForSet(set);
  657. break;
  658. case 't':
  659. binding += tShiftMapper.getShiftForSet(set);
  660. break;
  661. case 's':
  662. binding += sShiftMapper.getShiftForSet(set);
  663. break;
  664. case 'u':
  665. binding += uShiftMapper.getShiftForSet(set);
  666. break;
  667. case 'c':
  668. // For setting packing offset. Does not affect binding.
  669. break;
  670. default:
  671. llvm_unreachable("unknown register type found");
  672. }
  673. tryToDecorate(var.getSpirvId(), set, binding, var.getCategory(),
  674. reg->Loc);
  675. }
  676. for (const auto &var : resourceVars) {
  677. const auto cat = var.getCategory();
  678. if (var.isCounter()) {
  679. if (!var.getCounterBinding()) {
  680. // Process mX * c2
  681. uint32_t set = 0;
  682. if (const auto *vkBinding = var.getBinding())
  683. set = vkBinding->getSet();
  684. else if (const auto *reg = var.getRegister())
  685. set = reg->RegisterSpace;
  686. theBuilder.decorateDSetBinding(var.getSpirvId(), set,
  687. bindingSet.useNextBinding(set, cat));
  688. }
  689. } else if (!var.getBinding() && !var.getRegister()) {
  690. // Process m3
  691. theBuilder.decorateDSetBinding(var.getSpirvId(), 0,
  692. bindingSet.useNextBinding(0, cat));
  693. }
  694. }
  695. return noError;
  696. }
  697. bool DeclResultIdMapper::createStageVars(
  698. const hlsl::SigPoint *sigPoint, const DeclaratorDecl *decl, bool asInput,
  699. QualType type, uint32_t arraySize, const llvm::Twine &namePrefix,
  700. llvm::Optional<uint32_t> invocationId, uint32_t *value, bool noWriteBack) {
  701. // invocationId should only be used for handling HS per-vertex output.
  702. if (invocationId.hasValue()) {
  703. assert(shaderModel.IsHS() && arraySize != 0 && !asInput);
  704. }
  705. if (type->isVoidType()) {
  706. // No stage variables will be created for void type.
  707. return true;
  708. }
  709. uint32_t typeId = typeTranslator.translateType(type);
  710. llvm::StringRef semanticStr;
  711. const hlsl::Semantic *semantic = {};
  712. uint32_t semanticIndex = {};
  713. SourceLocation semanticLoc = {};
  714. if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
  715. &semanticLoc)) {
  716. const auto semanticKind = semantic->GetKind();
  717. // Found semantic attached directly to this Decl. This means we need to
  718. // map this decl to a single stage variable.
  719. // Error out when the given semantic is invalid in this shader model
  720. if (hlsl::SigPoint::GetInterpretation(semanticKind, sigPoint->GetKind(),
  721. shaderModel.GetMajor(),
  722. shaderModel.GetMinor()) ==
  723. hlsl::DXIL::SemanticInterpretationKind::NA) {
  724. emitError("invalid usage of semantic '%0' in shader profile %1",
  725. decl->getLocation())
  726. << semanticStr << shaderModel.GetName();
  727. return false;
  728. }
  729. // Special handling of certain mappings between HLSL semantics and
  730. // SPIR-V builtins:
  731. // * SV_Position/SV_CullDistance/SV_ClipDistance should be grouped into the
  732. // gl_PerVertex struct in vertex processing stages.
  733. // * SV_DomainLocation can refer to a float2, whereas TessCoord is a float3.
  734. // To ensure SPIR-V validity, we must create a float3 and extract a
  735. // float2 from it before passing it to the main function.
  736. // * SV_TessFactor is an array of size 2 for isoline patch, array of size 3
  737. // for tri patch, and array of size 4 for quad patch, but it must always
  738. // be an array of size 4 in SPIR-V for Vulkan.
  739. // * SV_InsideTessFactor is a single float for tri patch, and an array of
  740. // size 2 for a quad patch, but it must always be an array of size 2 in
  741. // SPIR-V for Vulkan.
  742. // * SV_Coverage is an uint value, but the builtin it corresponds to,
  743. // SampleMask, must be an array of integers.
  744. if (glPerVertex.tryToAccess(sigPoint->GetKind(), semanticKind,
  745. semanticIndex, invocationId, value,
  746. noWriteBack))
  747. return true;
  748. const uint32_t srcTypeId = typeId; // Variable type in source code
  749. switch (semanticKind) {
  750. case hlsl::Semantic::Kind::DomainLocation:
  751. typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 3);
  752. break;
  753. case hlsl::Semantic::Kind::TessFactor:
  754. typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
  755. theBuilder.getConstantUint32(4));
  756. break;
  757. case hlsl::Semantic::Kind::InsideTessFactor:
  758. typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
  759. theBuilder.getConstantUint32(2));
  760. break;
  761. case hlsl::Semantic::Kind::Coverage:
  762. typeId = theBuilder.getArrayType(typeId, theBuilder.getConstantUint32(1));
  763. break;
  764. }
  765. // Handle the extra arrayness
  766. const uint32_t elementTypeId = typeId; // Array element's type
  767. if (arraySize != 0)
  768. typeId = theBuilder.getArrayType(typeId,
  769. theBuilder.getConstantUint32(arraySize));
  770. StageVar stageVar(sigPoint, semanticStr, semantic, semanticIndex, typeId);
  771. llvm::Twine name = namePrefix + "." + semanticStr;
  772. const uint32_t varId = createSpirvStageVar(&stageVar, name, semanticLoc);
  773. if (varId == 0)
  774. return false;
  775. stageVar.setSpirvId(varId);
  776. stageVar.setLocationAttr(decl->getAttr<VKLocationAttr>());
  777. stageVars.push_back(stageVar);
  778. stageVarIds[decl] = varId;
  779. // TODO: the following may not be correct?
  780. if (sigPoint->GetSignatureKind() ==
  781. hlsl::DXIL::SignatureKind::PatchConstant)
  782. theBuilder.decorate(varId, spv::Decoration::Patch);
  783. // Decorate with interpolation modes for pixel shader input variables
  784. if (shaderModel.IsPS() && sigPoint->IsInput())
  785. decoratePSInterpolationMode(decl, type, varId);
  786. if (asInput) {
  787. *value = theBuilder.createLoad(typeId, varId);
  788. // Fix ups for corner cases
  789. // Special handling of SV_TessFactor DS patch constant input.
  790. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  791. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  792. // relevant indexes must be loaded.
  793. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  794. hlsl::GetArraySize(type) != 4) {
  795. llvm::SmallVector<uint32_t, 4> components;
  796. const auto f32TypeId = theBuilder.getFloat32Type();
  797. const auto tessFactorSize = hlsl::GetArraySize(type);
  798. const auto arrType = theBuilder.getArrayType(
  799. f32TypeId, theBuilder.getConstantUint32(tessFactorSize));
  800. for (uint32_t i = 0; i < tessFactorSize; ++i)
  801. components.push_back(
  802. theBuilder.createCompositeExtract(f32TypeId, *value, {i}));
  803. *value = theBuilder.createCompositeConstruct(arrType, components);
  804. }
  805. // Special handling of SV_InsideTessFactor DS patch constant input.
  806. // TessLevelInner is always an array of size 2 in SPIR-V, but
  807. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  808. // HLSL. If SV_InsideTessFactor is a scalar, only extract index 0 of
  809. // TessLevelInner.
  810. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  811. !type->isArrayType()) {
  812. *value = theBuilder.createCompositeExtract(theBuilder.getFloat32Type(),
  813. *value, {0});
  814. }
  815. // SV_DomainLocation can refer to a float2 or a float3, whereas TessCoord
  816. // is always a float3. To ensure SPIR-V validity, a float3 stage variable
  817. // is created, and we must extract a float2 from it before passing it to
  818. // the main function.
  819. else if (semanticKind == hlsl::Semantic::Kind::DomainLocation &&
  820. hlsl::GetHLSLVecSize(type) != 3) {
  821. const auto domainLocSize = hlsl::GetHLSLVecSize(type);
  822. *value = theBuilder.createVectorShuffle(
  823. theBuilder.getVecType(theBuilder.getFloat32Type(), domainLocSize),
  824. *value, *value, {0, 1});
  825. }
  826. // Special handling of SV_Coverage, which is an uint value. We need to
  827. // read SampleMask and extract its first element.
  828. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  829. *value = theBuilder.createCompositeExtract(srcTypeId, *value, {0});
  830. }
  831. } else {
  832. if (noWriteBack)
  833. return true;
  834. uint32_t ptr = varId;
  835. // Special handling of SV_TessFactor HS patch constant output.
  836. // TessLevelOuter is always an array of size 4 in SPIR-V, but
  837. // SV_TessFactor could be an array of size 2, 3, or 4 in HLSL. Only the
  838. // relevant indexes must be written to.
  839. if (semanticKind == hlsl::Semantic::Kind::TessFactor &&
  840. hlsl::GetArraySize(type) != 4) {
  841. const auto f32TypeId = theBuilder.getFloat32Type();
  842. const auto tessFactorSize = hlsl::GetArraySize(type);
  843. for (uint32_t i = 0; i < tessFactorSize; ++i) {
  844. const uint32_t ptrType =
  845. theBuilder.getPointerType(f32TypeId, spv::StorageClass::Output);
  846. ptr = theBuilder.createAccessChain(ptrType, varId,
  847. theBuilder.getConstantUint32(i));
  848. theBuilder.createStore(
  849. ptr, theBuilder.createCompositeExtract(f32TypeId, *value, i));
  850. }
  851. }
  852. // Special handling of SV_InsideTessFactor HS patch constant output.
  853. // TessLevelInner is always an array of size 2 in SPIR-V, but
  854. // SV_InsideTessFactor could be an array of size 1 (scalar) or size 2 in
  855. // HLSL. If SV_InsideTessFactor is a scalar, only write to index 0 of
  856. // TessLevelInner.
  857. else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor &&
  858. !type->isArrayType()) {
  859. ptr = theBuilder.createAccessChain(
  860. theBuilder.getPointerType(theBuilder.getFloat32Type(),
  861. spv::StorageClass::Output),
  862. varId, theBuilder.getConstantUint32(0));
  863. theBuilder.createStore(ptr, *value);
  864. }
  865. // Special handling of SV_Coverage, which is an unit value. We need to
  866. // write it to the first element in the SampleMask builtin.
  867. else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
  868. ptr = theBuilder.createAccessChain(
  869. theBuilder.getPointerType(srcTypeId, spv::StorageClass::Output),
  870. varId, theBuilder.getConstantUint32(0));
  871. theBuilder.createStore(ptr, *value);
  872. }
  873. // Special handling of HS ouput, for which we write to only one
  874. // element in the per-vertex data array: the one indexed by
  875. // SV_ControlPointID.
  876. else if (invocationId.hasValue()) {
  877. const uint32_t ptrType =
  878. theBuilder.getPointerType(elementTypeId, spv::StorageClass::Output);
  879. const uint32_t index = invocationId.getValue();
  880. ptr = theBuilder.createAccessChain(ptrType, varId, index);
  881. theBuilder.createStore(ptr, *value);
  882. }
  883. // For all normal cases
  884. else {
  885. theBuilder.createStore(ptr, *value);
  886. }
  887. }
  888. return true;
  889. }
  890. // If the decl itself doesn't have semantic string attached, it should be
  891. // a struct having all its fields with semantic strings.
  892. if (!type->isStructureType()) {
  893. emitError("semantic string missing for shader %select{output|input}0 "
  894. "variable '%1'",
  895. decl->getLocation())
  896. << asInput << decl->getName();
  897. return false;
  898. }
  899. const auto *structDecl = cast<RecordType>(type.getTypePtr())->getDecl();
  900. if (asInput) {
  901. // If this decl translates into multiple stage input variables, we need to
  902. // load their values into a composite.
  903. llvm::SmallVector<uint32_t, 4> subValues;
  904. for (const auto *field : structDecl->fields()) {
  905. uint32_t subValue = 0;
  906. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  907. arraySize, namePrefix, invocationId, &subValue,
  908. noWriteBack))
  909. return false;
  910. subValues.push_back(subValue);
  911. }
  912. if (arraySize == 0) {
  913. *value = theBuilder.createCompositeConstruct(typeId, subValues);
  914. return true;
  915. }
  916. // Handle the extra level of arrayness.
  917. // We need to return an array of structs. But we get arrays of fields
  918. // from visiting all fields. So now we need to extract all the elements
  919. // at the same index of each field arrays and compose a new struct out
  920. // of them.
  921. const uint32_t structType = typeTranslator.translateType(type);
  922. const uint32_t arrayType = theBuilder.getArrayType(
  923. structType, theBuilder.getConstantUint32(arraySize));
  924. llvm::SmallVector<uint32_t, 16> arrayElements;
  925. for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) {
  926. llvm::SmallVector<uint32_t, 8> fields;
  927. // Extract the element at index arrayIndex from each field
  928. for (const auto *field : structDecl->fields()) {
  929. const uint32_t fieldType =
  930. typeTranslator.translateType(field->getType());
  931. fields.push_back(theBuilder.createCompositeExtract(
  932. fieldType, subValues[field->getFieldIndex()], {arrayIndex}));
  933. }
  934. // Compose a new struct out of them
  935. arrayElements.push_back(
  936. theBuilder.createCompositeConstruct(structType, fields));
  937. }
  938. *value = theBuilder.createCompositeConstruct(arrayType, arrayElements);
  939. } else {
  940. // Unlike reading, which may require us to read stand-alone builtins and
  941. // stage input variables and compose an array of structs out of them,
  942. // it happens that we don't need to write an array of structs in a bunch
  943. // for all shader stages:
  944. //
  945. // * VS: output is a single struct, without extra arrayness
  946. // * HS: output is an array of structs, with extra arrayness,
  947. // but we only write to the struct at the InvocationID index
  948. // * DS: output is a single struct, without extra arrayness
  949. // * GS: output is controlled by OpEmitVertex, one vertex per time
  950. //
  951. // The interesting shader stage is HS. We need the InvocationID to write
  952. // out the value to the correct array element.
  953. for (const auto *field : structDecl->fields()) {
  954. const uint32_t fieldType = typeTranslator.translateType(field->getType());
  955. uint32_t subValue = 0;
  956. if (!noWriteBack)
  957. subValue = theBuilder.createCompositeExtract(fieldType, *value,
  958. {field->getFieldIndex()});
  959. if (!createStageVars(sigPoint, field, asInput, field->getType(),
  960. arraySize, namePrefix, invocationId, &subValue,
  961. noWriteBack))
  962. return false;
  963. }
  964. }
  965. return true;
  966. }
  967. bool DeclResultIdMapper::writeBackOutputStream(const ValueDecl *decl,
  968. uint32_t value) {
  969. assert(shaderModel.IsGS()); // Only for GS use
  970. QualType type = decl->getType();
  971. if (hlsl::IsHLSLStreamOutputType(type))
  972. type = hlsl::GetHLSLResourceResultType(type);
  973. if (hasGSPrimitiveTypeQualifier(decl))
  974. type = astContext.getAsConstantArrayType(type)->getElementType();
  975. llvm::StringRef semanticStr;
  976. const hlsl::Semantic *semantic = {};
  977. uint32_t semanticIndex = {};
  978. SourceLocation semanticLoc = {};
  979. if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
  980. &semanticLoc)) {
  981. // Found semantic attached directly to this Decl. Write the value for this
  982. // Decl to the corresponding stage output variable.
  983. const uint32_t srcTypeId = typeTranslator.translateType(type);
  984. // Handle SV_Position, SV_ClipDistance, and SV_CullDistance
  985. if (glPerVertex.tryToAccess(hlsl::DXIL::SigPointKind::GSOut,
  986. semantic->GetKind(), semanticIndex, llvm::None,
  987. &value, /*noWriteBack=*/false))
  988. return true;
  989. // Query the <result-id> for the stage output variable generated out
  990. // of this decl.
  991. const auto found = stageVarIds.find(decl);
  992. // We should have recorded its stage output variable previously.
  993. assert(found != stageVarIds.end());
  994. theBuilder.createStore(found->second, value);
  995. return true;
  996. }
  997. // If the decl itself doesn't have semantic string attached, it should be
  998. // a struct having all its fields with semantic strings.
  999. if (!type->isStructureType()) {
  1000. emitError("semantic string missing for shader output variable '%0'",
  1001. decl->getLocation())
  1002. << decl->getName();
  1003. return false;
  1004. }
  1005. const auto *structDecl = cast<RecordType>(type.getTypePtr())->getDecl();
  1006. // Write out each field
  1007. for (const auto *field : structDecl->fields()) {
  1008. const uint32_t fieldType = typeTranslator.translateType(field->getType());
  1009. const uint32_t subValue = theBuilder.createCompositeExtract(
  1010. fieldType, value, {field->getFieldIndex()});
  1011. if (!writeBackOutputStream(field, subValue))
  1012. return false;
  1013. }
  1014. return true;
  1015. }
  1016. void DeclResultIdMapper::decoratePSInterpolationMode(const DeclaratorDecl *decl,
  1017. QualType type,
  1018. uint32_t varId) {
  1019. const QualType elemType = typeTranslator.getElementType(type);
  1020. if (elemType->isBooleanType() || elemType->isIntegerType()) {
  1021. // TODO: Probably we can call hlsl::ValidateSignatureElement() for the
  1022. // following check.
  1023. if (decl->getAttr<HLSLLinearAttr>() || decl->getAttr<HLSLCentroidAttr>() ||
  1024. decl->getAttr<HLSLNoPerspectiveAttr>() ||
  1025. decl->getAttr<HLSLSampleAttr>()) {
  1026. emitError("only nointerpolation mode allowed for integer input "
  1027. "parameters in pixel shader",
  1028. decl->getLocation());
  1029. } else {
  1030. theBuilder.decorate(varId, spv::Decoration::Flat);
  1031. }
  1032. } else {
  1033. // Do nothing for HLSLLinearAttr since its the default
  1034. // Attributes can be used together. So cannot use else if.
  1035. if (decl->getAttr<HLSLCentroidAttr>())
  1036. theBuilder.decorate(varId, spv::Decoration::Centroid);
  1037. if (decl->getAttr<HLSLNoInterpolationAttr>())
  1038. theBuilder.decorate(varId, spv::Decoration::Flat);
  1039. if (decl->getAttr<HLSLNoPerspectiveAttr>())
  1040. theBuilder.decorate(varId, spv::Decoration::NoPerspective);
  1041. if (decl->getAttr<HLSLSampleAttr>()) {
  1042. theBuilder.requireCapability(spv::Capability::SampleRateShading);
  1043. theBuilder.decorate(varId, spv::Decoration::Sample);
  1044. }
  1045. }
  1046. }
  1047. uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
  1048. const llvm::Twine &name,
  1049. SourceLocation srcLoc) {
  1050. using spv::BuiltIn;
  1051. const auto sigPoint = stageVar->getSigPoint();
  1052. const auto semanticKind = stageVar->getSemantic()->GetKind();
  1053. const auto sigPointKind = sigPoint->GetKind();
  1054. const uint32_t type = stageVar->getSpirvTypeId();
  1055. spv::StorageClass sc = getStorageClassForSigPoint(sigPoint);
  1056. if (sc == spv::StorageClass::Max)
  1057. return 0;
  1058. stageVar->setStorageClass(sc);
  1059. // The following translation assumes that semantic validity in the current
  1060. // shader model is already checked, so it only covers valid SigPoints for
  1061. // each semantic.
  1062. switch (semanticKind) {
  1063. // According to DXIL spec, the Position SV can be used by all SigPoints
  1064. // other than PCIn, HSIn, GSIn, PSOut, CSIn.
  1065. // According to Vulkan spec, the Position BuiltIn can only be used
  1066. // by VSOut, HS/DS/GS In/Out.
  1067. case hlsl::Semantic::Kind::Position: {
  1068. switch (sigPointKind) {
  1069. case hlsl::SigPoint::Kind::VSIn:
  1070. case hlsl::SigPoint::Kind::PCOut:
  1071. case hlsl::SigPoint::Kind::DSIn:
  1072. return theBuilder.addStageIOVar(type, sc, name.str());
  1073. case hlsl::SigPoint::Kind::VSOut:
  1074. case hlsl::SigPoint::Kind::HSCPIn:
  1075. case hlsl::SigPoint::Kind::HSCPOut:
  1076. case hlsl::SigPoint::Kind::DSCPIn:
  1077. case hlsl::SigPoint::Kind::DSOut:
  1078. case hlsl::SigPoint::Kind::GSVIn:
  1079. llvm_unreachable("should be handled in gl_PerVertex struct");
  1080. case hlsl::SigPoint::Kind::GSOut:
  1081. stageVar->setIsSpirvBuiltin();
  1082. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::Position);
  1083. case hlsl::SigPoint::Kind::PSIn:
  1084. stageVar->setIsSpirvBuiltin();
  1085. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragCoord);
  1086. default:
  1087. llvm_unreachable("invalid usage of SV_Position sneaked in");
  1088. }
  1089. }
  1090. // According to DXIL spec, the VertexID SV can only be used by VSIn.
  1091. // According to Vulkan spec, the VertexIndex BuiltIn can only be used by
  1092. // VSIn.
  1093. case hlsl::Semantic::Kind::VertexID: {
  1094. stageVar->setIsSpirvBuiltin();
  1095. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::VertexIndex);
  1096. }
  1097. // According to DXIL spec, the InstanceID SV can be used by VSIn, VSOut,
  1098. // HSCPIn, HSCPOut, DSCPIn, DSOut, GSVIn, GSOut, PSIn.
  1099. // According to Vulkan spec, the InstanceIndex BuitIn can only be used by
  1100. // VSIn.
  1101. case hlsl::Semantic::Kind::InstanceID: {
  1102. switch (sigPointKind) {
  1103. case hlsl::SigPoint::Kind::VSIn:
  1104. stageVar->setIsSpirvBuiltin();
  1105. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InstanceIndex);
  1106. case hlsl::SigPoint::Kind::VSOut:
  1107. case hlsl::SigPoint::Kind::HSCPIn:
  1108. case hlsl::SigPoint::Kind::HSCPOut:
  1109. case hlsl::SigPoint::Kind::DSCPIn:
  1110. case hlsl::SigPoint::Kind::DSOut:
  1111. case hlsl::SigPoint::Kind::GSVIn:
  1112. case hlsl::SigPoint::Kind::GSOut:
  1113. case hlsl::SigPoint::Kind::PSIn:
  1114. return theBuilder.addStageIOVar(type, sc, name.str());
  1115. default:
  1116. llvm_unreachable("invalid usage of SV_InstanceID sneaked in");
  1117. }
  1118. }
  1119. // According to DXIL spec, the Depth{|GreaterEqual|LessEqual} SV can only be
  1120. // used by PSOut.
  1121. // According to Vulkan spec, the FragDepth BuiltIn can only be used by PSOut.
  1122. case hlsl::Semantic::Kind::Depth:
  1123. case hlsl::Semantic::Kind::DepthGreaterEqual:
  1124. case hlsl::Semantic::Kind::DepthLessEqual: {
  1125. stageVar->setIsSpirvBuiltin();
  1126. if (semanticKind == hlsl::Semantic::Kind::DepthGreaterEqual)
  1127. theBuilder.addExecutionMode(entryFunctionId,
  1128. spv::ExecutionMode::DepthGreater, {});
  1129. else if (semanticKind == hlsl::Semantic::Kind::DepthLessEqual)
  1130. theBuilder.addExecutionMode(entryFunctionId,
  1131. spv::ExecutionMode::DepthLess, {});
  1132. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragDepth);
  1133. }
  1134. // According to DXIL spec, the ClipDistance/CullDistance SV can be used by all
  1135. // SigPoints other than PCIn, HSIn, GSIn, PSOut, CSIn.
  1136. // According to Vulkan spec, the ClipDistance/CullDistance BuiltIn can only
  1137. // be
  1138. // used by VSOut, HS/DS/GS In/Out.
  1139. case hlsl::Semantic::Kind::ClipDistance:
  1140. case hlsl::Semantic::Kind::CullDistance: {
  1141. switch (sigPointKind) {
  1142. case hlsl::SigPoint::Kind::VSIn:
  1143. case hlsl::SigPoint::Kind::PCOut:
  1144. case hlsl::SigPoint::Kind::DSIn:
  1145. return theBuilder.addStageIOVar(type, sc, name.str());
  1146. case hlsl::SigPoint::Kind::VSOut:
  1147. case hlsl::SigPoint::Kind::HSCPIn:
  1148. case hlsl::SigPoint::Kind::HSCPOut:
  1149. case hlsl::SigPoint::Kind::DSCPIn:
  1150. case hlsl::SigPoint::Kind::DSOut:
  1151. case hlsl::SigPoint::Kind::GSVIn:
  1152. case hlsl::SigPoint::Kind::GSOut:
  1153. case hlsl::SigPoint::Kind::PSIn:
  1154. llvm_unreachable("should be handled in gl_PerVertex struct");
  1155. default:
  1156. llvm_unreachable(
  1157. "invalid usage of SV_ClipDistance/SV_CullDistance sneaked in");
  1158. }
  1159. }
  1160. // According to DXIL spec, the IsFrontFace SV can only be used by GSOut and
  1161. // PSIn.
  1162. // According to Vulkan spec, the FrontFacing BuitIn can only be used in PSIn.
  1163. case hlsl::Semantic::Kind::IsFrontFace: {
  1164. switch (sigPointKind) {
  1165. case hlsl::SigPoint::Kind::GSOut:
  1166. return theBuilder.addStageIOVar(type, sc, name.str());
  1167. case hlsl::SigPoint::Kind::PSIn:
  1168. stageVar->setIsSpirvBuiltin();
  1169. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FrontFacing);
  1170. default:
  1171. llvm_unreachable("invalid usage of SV_IsFrontFace sneaked in");
  1172. }
  1173. }
  1174. // According to DXIL spec, the Target SV can only be used by PSOut.
  1175. // There is no corresponding builtin decoration in SPIR-V. So generate normal
  1176. // Vulkan stage input/output variables.
  1177. case hlsl::Semantic::Kind::Target:
  1178. // An arbitrary semantic is defined by users. Generate normal Vulkan stage
  1179. // input/output variables.
  1180. case hlsl::Semantic::Kind::Arbitrary: {
  1181. return theBuilder.addStageIOVar(type, sc, name.str());
  1182. // TODO: patch constant function in hull shader
  1183. }
  1184. // According to DXIL spec, the DispatchThreadID SV can only be used by CSIn.
  1185. // According to Vulkan spec, the GlobalInvocationId can only be used in CSIn.
  1186. case hlsl::Semantic::Kind::DispatchThreadID: {
  1187. stageVar->setIsSpirvBuiltin();
  1188. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::GlobalInvocationId);
  1189. }
  1190. // According to DXIL spec, the GroupID SV can only be used by CSIn.
  1191. // According to Vulkan spec, the WorkgroupId can only be used in CSIn.
  1192. case hlsl::Semantic::Kind::GroupID: {
  1193. stageVar->setIsSpirvBuiltin();
  1194. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::WorkgroupId);
  1195. }
  1196. // According to DXIL spec, the GroupThreadID SV can only be used by CSIn.
  1197. // According to Vulkan spec, the LocalInvocationId can only be used in CSIn.
  1198. case hlsl::Semantic::Kind::GroupThreadID: {
  1199. stageVar->setIsSpirvBuiltin();
  1200. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::LocalInvocationId);
  1201. }
  1202. // According to DXIL spec, the GroupIndex SV can only be used by CSIn.
  1203. // According to Vulkan spec, the LocalInvocationIndex can only be used in
  1204. // CSIn.
  1205. case hlsl::Semantic::Kind::GroupIndex: {
  1206. stageVar->setIsSpirvBuiltin();
  1207. return theBuilder.addStageBuiltinVar(type, sc,
  1208. BuiltIn::LocalInvocationIndex);
  1209. }
  1210. // According to DXIL spec, the OutputControlID SV can only be used by HSIn.
  1211. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  1212. // HS/GS In.
  1213. case hlsl::Semantic::Kind::OutputControlPointID: {
  1214. stageVar->setIsSpirvBuiltin();
  1215. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
  1216. }
  1217. // According to DXIL spec, the PrimitiveID SV can only be used by PCIn, HSIn,
  1218. // DSIn, GSIn, GSOut, and PSIn.
  1219. // According to Vulkan spec, the PrimitiveId BuiltIn can only be used in
  1220. // HS/DS/PS In, GS In/Out.
  1221. case hlsl::Semantic::Kind::PrimitiveID: {
  1222. // PrimitiveId requires either Tessellation or Geometry capability.
  1223. // Need to require one for PSIn.
  1224. if (sigPointKind == hlsl::SigPoint::Kind::PSIn)
  1225. theBuilder.requireCapability(spv::Capability::Geometry);
  1226. // Translate to PrimitiveId BuiltIn for all valid SigPoints.
  1227. stageVar->setIsSpirvBuiltin();
  1228. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::PrimitiveId);
  1229. }
  1230. // According to DXIL spec, the TessFactor SV can only be used by PCOut and
  1231. // DSIn.
  1232. // According to Vulkan spec, the TessLevelOuter BuiltIn can only be used in
  1233. // PCOut and DSIn.
  1234. case hlsl::Semantic::Kind::TessFactor: {
  1235. stageVar->setIsSpirvBuiltin();
  1236. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelOuter);
  1237. }
  1238. // According to DXIL spec, the InsideTessFactor SV can only be used by PCOut
  1239. // and DSIn.
  1240. // According to Vulkan spec, the TessLevelInner BuiltIn can only be used in
  1241. // PCOut and DSIn.
  1242. case hlsl::Semantic::Kind::InsideTessFactor: {
  1243. stageVar->setIsSpirvBuiltin();
  1244. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelInner);
  1245. }
  1246. // According to DXIL spec, the DomainLocation SV can only be used by DSIn.
  1247. // According to Vulkan spec, the TessCoord BuiltIn can only be used in DSIn.
  1248. case hlsl::Semantic::Kind::DomainLocation: {
  1249. stageVar->setIsSpirvBuiltin();
  1250. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessCoord);
  1251. }
  1252. // According to DXIL spec, the GSInstanceID SV can only be used by GSIn.
  1253. // According to Vulkan spec, the InvocationId BuiltIn can only be used in
  1254. // HS/GS In.
  1255. case hlsl::Semantic::Kind::GSInstanceID: {
  1256. stageVar->setIsSpirvBuiltin();
  1257. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
  1258. }
  1259. // According to DXIL spec, the SampleIndex SV can only be used by PSIn.
  1260. // According to Vulkan spec, the SampleId BuiltIn can only be used in PSIn.
  1261. case hlsl::Semantic::Kind::SampleIndex: {
  1262. theBuilder.requireCapability(spv::Capability::SampleRateShading);
  1263. stageVar->setIsSpirvBuiltin();
  1264. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleId);
  1265. }
  1266. // According to DXIL spec, the StencilRef SV can only be used by PSOut.
  1267. case hlsl::Semantic::Kind::StencilRef: {
  1268. theBuilder.addExtension("SPV_EXT_shader_stencil_export");
  1269. theBuilder.requireCapability(spv::Capability::StencilExportEXT);
  1270. stageVar->setIsSpirvBuiltin();
  1271. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragStencilRefEXT);
  1272. }
  1273. // According to DXIL spec, the RenderTargetArrayIndex SV can only be used by
  1274. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn.
  1275. // According to Vulkan spec, the Layer BuiltIn can only be used in GSOut and
  1276. // PSIn.
  1277. case hlsl::Semantic::Kind::RenderTargetArrayIndex: {
  1278. switch (sigPointKind) {
  1279. case hlsl::SigPoint::Kind::VSIn:
  1280. case hlsl::SigPoint::Kind::VSOut:
  1281. case hlsl::SigPoint::Kind::HSCPIn:
  1282. case hlsl::SigPoint::Kind::HSCPOut:
  1283. case hlsl::SigPoint::Kind::PCOut:
  1284. case hlsl::SigPoint::Kind::DSIn:
  1285. case hlsl::SigPoint::Kind::DSCPIn:
  1286. case hlsl::SigPoint::Kind::DSOut:
  1287. case hlsl::SigPoint::Kind::GSVIn:
  1288. return theBuilder.addStageIOVar(type, sc, name.str());
  1289. case hlsl::SigPoint::Kind::GSOut:
  1290. case hlsl::SigPoint::Kind::PSIn:
  1291. theBuilder.requireCapability(spv::Capability::Geometry);
  1292. stageVar->setIsSpirvBuiltin();
  1293. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::Layer);
  1294. default:
  1295. llvm_unreachable("invalid usage of SV_RenderTargetArrayIndex sneaked in");
  1296. }
  1297. }
  1298. // According to DXIL spec, the ViewportArrayIndex SV can only be used by
  1299. // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn.
  1300. // According to Vulkan spec, the ViewportIndex BuiltIn can only be used in
  1301. // GSOut and PSIn.
  1302. case hlsl::Semantic::Kind::ViewPortArrayIndex: {
  1303. switch (sigPointKind) {
  1304. case hlsl::SigPoint::Kind::VSIn:
  1305. case hlsl::SigPoint::Kind::VSOut:
  1306. case hlsl::SigPoint::Kind::HSCPIn:
  1307. case hlsl::SigPoint::Kind::HSCPOut:
  1308. case hlsl::SigPoint::Kind::PCOut:
  1309. case hlsl::SigPoint::Kind::DSIn:
  1310. case hlsl::SigPoint::Kind::DSCPIn:
  1311. case hlsl::SigPoint::Kind::DSOut:
  1312. case hlsl::SigPoint::Kind::GSVIn:
  1313. return theBuilder.addStageIOVar(type, sc, name.str());
  1314. case hlsl::SigPoint::Kind::GSOut:
  1315. case hlsl::SigPoint::Kind::PSIn:
  1316. theBuilder.requireCapability(spv::Capability::MultiViewport);
  1317. stageVar->setIsSpirvBuiltin();
  1318. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::ViewportIndex);
  1319. default:
  1320. llvm_unreachable("invalid usage of SV_ViewportArrayIndex sneaked in");
  1321. }
  1322. }
  1323. // According to DXIL spec, the Coverage SV can only be used by PSIn and PSOut.
  1324. // According to Vulkan spec, the SampleMask BuiltIn can only be used in
  1325. // PSIn and PSOut.
  1326. case hlsl::Semantic::Kind::Coverage: {
  1327. stageVar->setIsSpirvBuiltin();
  1328. return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleMask);
  1329. }
  1330. case hlsl::Semantic::Kind::InnerCoverage: {
  1331. emitError("no equivalent for semantic SV_InnerCoverage in Vulkan", srcLoc);
  1332. return 0;
  1333. }
  1334. default:
  1335. emitError("semantic %0 unimplemented", srcLoc)
  1336. << stageVar->getSemantic()->GetName();
  1337. break;
  1338. }
  1339. return 0;
  1340. }
  1341. spv::StorageClass
  1342. DeclResultIdMapper::getStorageClassForSigPoint(const hlsl::SigPoint *sigPoint) {
  1343. // This translation is done based on the HLSL reference (see docs/dxil.rst).
  1344. const auto sigPointKind = sigPoint->GetKind();
  1345. const auto signatureKind = sigPoint->GetSignatureKind();
  1346. spv::StorageClass sc = spv::StorageClass::Max;
  1347. switch (signatureKind) {
  1348. case hlsl::DXIL::SignatureKind::Input:
  1349. sc = spv::StorageClass::Input;
  1350. break;
  1351. case hlsl::DXIL::SignatureKind::Output:
  1352. sc = spv::StorageClass::Output;
  1353. break;
  1354. case hlsl::DXIL::SignatureKind::Invalid: {
  1355. // There are some special cases in HLSL (See docs/dxil.rst):
  1356. // SignatureKind is "invalid" for PCIn, HSIn, GSIn, and CSIn.
  1357. switch (sigPointKind) {
  1358. case hlsl::DXIL::SigPointKind::PCIn:
  1359. case hlsl::DXIL::SigPointKind::HSIn:
  1360. case hlsl::DXIL::SigPointKind::GSIn:
  1361. case hlsl::DXIL::SigPointKind::CSIn:
  1362. sc = spv::StorageClass::Input;
  1363. break;
  1364. default:
  1365. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1366. }
  1367. break;
  1368. }
  1369. case hlsl::DXIL::SignatureKind::PatchConstant: {
  1370. // There are some special cases in HLSL (See docs/dxil.rst):
  1371. // SignatureKind is "PatchConstant" for PCOut and DSIn.
  1372. switch (sigPointKind) {
  1373. case hlsl::DXIL::SigPointKind::PCOut:
  1374. // Patch Constant Output (Output of Hull which is passed to Domain).
  1375. sc = spv::StorageClass::Output;
  1376. break;
  1377. case hlsl::DXIL::SigPointKind::DSIn:
  1378. // Domain Shader regular input - Patch Constant data plus system values.
  1379. sc = spv::StorageClass::Input;
  1380. break;
  1381. default:
  1382. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1383. }
  1384. break;
  1385. }
  1386. default:
  1387. llvm_unreachable("Found invalid SigPoint kind for semantic");
  1388. }
  1389. return sc;
  1390. }
  1391. } // end namespace spirv
  1392. } // end namespace clang