DxilMetadataHelper.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilMetadataHelper.h //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // Helper to serialize/desialize metadata for DxilModule. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include "dxc/DXIL/DxilConstants.h"
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include <memory>
  15. #include <string>
  16. #include <vector>
  17. namespace llvm {
  18. class LLVMContext;
  19. class Module;
  20. class Function;
  21. class Instruction;
  22. class DbgDeclareInst;
  23. class Value;
  24. class MDOperand;
  25. class Metadata;
  26. class ConstantAsMetadata;
  27. class MDTuple;
  28. class MDNode;
  29. class NamedMDNode;
  30. class GlobalVariable;
  31. class StringRef;
  32. class Type;
  33. }
  34. namespace hlsl {
  35. class ShaderModel;
  36. class DxilSignature;
  37. struct DxilEntrySignature;
  38. class DxilSignatureElement;
  39. class DxilModule;
  40. class DxilResourceBase;
  41. class DxilCBuffer;
  42. class DxilResource;
  43. class DxilSampler;
  44. class DxilTypeSystem;
  45. class DxilStructAnnotation;
  46. class DxilFieldAnnotation;
  47. class DxilPayloadAnnotation;
  48. class DxilPayloadFieldAnnotation;
  49. class DxilTemplateArgAnnotation;
  50. class DxilFunctionAnnotation;
  51. class DxilParameterAnnotation;
  52. class RootSignatureHandle;
  53. struct DxilFunctionProps;
  54. class DxilSubobjects;
  55. class DxilSubobject;
  56. struct DxilCounters;
  57. // Additional debug information for SROA'ed array variables,
  58. // where adjacent elements in DXIL might not have been adjacent
  59. // in the original user variable.
  60. struct DxilDIArrayDim {
  61. unsigned StrideInBits;
  62. unsigned NumElements;
  63. };
  64. /// Use this class to manipulate DXIL-spcific metadata.
  65. // In our code, only DxilModule and HLModule should use this class.
  66. class DxilMDHelper {
  67. public:
  68. //
  69. // Constants for metadata names and field positions.
  70. //
  71. // Dxil version.
  72. static const char kDxilVersionMDName[];
  73. static const unsigned kDxilVersionNumFields = 2;
  74. static const unsigned kDxilVersionMajorIdx = 0; // DXIL version major.
  75. static const unsigned kDxilVersionMinorIdx = 1; // DXIL version minor.
  76. // Shader model.
  77. static const char kDxilShaderModelMDName[];
  78. static const unsigned kDxilShaderModelNumFields = 3;
  79. static const unsigned kDxilShaderModelTypeIdx = 0; // Shader type (vs,ps,cs,gs,ds,hs).
  80. static const unsigned kDxilShaderModelMajorIdx = 1; // Shader model major.
  81. static const unsigned kDxilShaderModelMinorIdx = 2; // Shader model minor.
  82. // Intermediate codegen/optimizer options, not valid in final DXIL module.
  83. static const char kDxilIntermediateOptionsMDName[];
  84. static const unsigned kDxilIntermediateOptionsFlags = 0; // Unique element ID.
  85. // DxilCounters
  86. static const char kDxilCountersMDName[];
  87. // !{!"<counter>", i32 <count>, !"<counter>", i32 <count>, ...}
  88. // Entry points.
  89. static const char kDxilEntryPointsMDName[];
  90. // Root Signature, for intermediate use, not valid in final DXIL module.
  91. static const char kDxilRootSignatureMDName[];
  92. // ViewId state.
  93. static const char kDxilViewIdStateMDName[];
  94. // Subobjects
  95. static const char kDxilSubobjectsMDName[];
  96. // Source info.
  97. static const char kDxilSourceContentsMDName[];
  98. static const char kDxilSourceDefinesMDName[];
  99. static const char kDxilSourceMainFileNameMDName[];
  100. static const char kDxilSourceArgsMDName[];
  101. // Old source info.
  102. static const char kDxilSourceContentsOldMDName[];
  103. static const char kDxilSourceDefinesOldMDName[];
  104. static const char kDxilSourceMainFileNameOldMDName[];
  105. static const char kDxilSourceArgsOldMDName[];
  106. static const unsigned kDxilEntryPointNumFields = 5;
  107. static const unsigned kDxilEntryPointFunction = 0; // Entry point function symbol.
  108. static const unsigned kDxilEntryPointName = 1; // Entry point unmangled name.
  109. static const unsigned kDxilEntryPointSignatures = 2; // Entry point signature tuple.
  110. static const unsigned kDxilEntryPointResources = 3; // Entry point resource tuple.
  111. static const unsigned kDxilEntryPointProperties = 4; // Entry point properties tuple.
  112. // Signatures.
  113. static const unsigned kDxilNumSignatureFields = 3;
  114. static const unsigned kDxilInputSignature = 0; // Shader input signature.
  115. static const unsigned kDxilOutputSignature = 1; // Shader output signature.
  116. static const unsigned kDxilPatchConstantSignature = 2; // Shader patch constant (PC) signature.
  117. // Signature Element.
  118. static const unsigned kDxilSignatureElementNumFields = 11;
  119. static const unsigned kDxilSignatureElementID = 0; // Unique element ID.
  120. static const unsigned kDxilSignatureElementName = 1; // Element name.
  121. static const unsigned kDxilSignatureElementType = 2; // Element type.
  122. static const unsigned kDxilSignatureElementSystemValue = 3; // Effective system value.
  123. static const unsigned kDxilSignatureElementIndexVector = 4; // Semantic index vector.
  124. static const unsigned kDxilSignatureElementInterpMode = 5; // Interpolation mode.
  125. static const unsigned kDxilSignatureElementRows = 6; // Number of rows.
  126. static const unsigned kDxilSignatureElementCols = 7; // Number of columns.
  127. static const unsigned kDxilSignatureElementStartRow = 8; // Element packing start row.
  128. static const unsigned kDxilSignatureElementStartCol = 9; // Element packing start column.
  129. static const unsigned kDxilSignatureElementNameValueList = 10; // Name-value list for extended properties.
  130. // Signature Element Extended Properties.
  131. static const unsigned kDxilSignatureElementOutputStreamTag = 0;
  132. static const unsigned kHLSignatureElementGlobalSymbolTag = 1;
  133. static const unsigned kDxilSignatureElementDynIdxCompMaskTag = 2;
  134. static const unsigned kDxilSignatureElementUsageCompMaskTag = 3;
  135. // Resources.
  136. static const char kDxilResourcesMDName[];
  137. static const unsigned kDxilNumResourceFields = 4;
  138. static const unsigned kDxilResourceSRVs = 0;
  139. static const unsigned kDxilResourceUAVs = 1;
  140. static const unsigned kDxilResourceCBuffers = 2;
  141. static const unsigned kDxilResourceSamplers = 3;
  142. // ResourceBase.
  143. static const unsigned kDxilResourceBaseNumFields = 6;
  144. static const unsigned kDxilResourceBaseID = 0; // Unique (per type) resource ID.
  145. static const unsigned kDxilResourceBaseVariable = 1; // Resource global variable.
  146. static const unsigned kDxilResourceBaseName = 2; // Original (HLSL) name of the resource.
  147. static const unsigned kDxilResourceBaseSpaceID = 3; // Resource range space ID.
  148. static const unsigned kDxilResourceBaseLowerBound = 4; // Resource range lower bound.
  149. static const unsigned kDxilResourceBaseRangeSize = 5; // Resource range size.
  150. // SRV-specific.
  151. static const unsigned kDxilSRVNumFields = 9;
  152. static const unsigned kDxilSRVShape = 6; // SRV shape.
  153. static const unsigned kDxilSRVSampleCount = 7; // SRV sample count.
  154. static const unsigned kDxilSRVNameValueList = 8; // Name-value list for extended properties.
  155. // UAV-specific.
  156. static const unsigned kDxilUAVNumFields = 11;
  157. static const unsigned kDxilUAVShape = 6; // UAV shape.
  158. static const unsigned kDxilUAVGloballyCoherent = 7; // Globally-coherent UAV.
  159. static const unsigned kDxilUAVCounter = 8; // UAV with a counter.
  160. static const unsigned kDxilUAVRasterizerOrderedView = 9; // UAV that is a ROV.
  161. static const unsigned kDxilUAVNameValueList = 10; // Name-value list for extended properties.
  162. // CBuffer-specific.
  163. static const unsigned kDxilCBufferNumFields = 8;
  164. static const unsigned kDxilCBufferSizeInBytes = 6; // CBuffer size in bytes.
  165. static const unsigned kDxilCBufferNameValueList = 7; // Name-value list for extended properties.
  166. // CBuffer extended properties
  167. static const unsigned kHLCBufferIsTBufferTag = 0; // CBuffer is actually TBuffer, not yet converted to SRV.
  168. // Sampler-specific.
  169. static const unsigned kDxilSamplerNumFields = 8;
  170. static const unsigned kDxilSamplerType = 6; // Sampler type.
  171. static const unsigned kDxilSamplerNameValueList = 7; // Name-value list for extended properties.
  172. // Resource extended property tags.
  173. static const unsigned kDxilTypedBufferElementTypeTag = 0;
  174. static const unsigned kDxilStructuredBufferElementStrideTag = 1;
  175. static const unsigned kDxilSamplerFeedbackKindTag = 2;
  176. static const unsigned kDxilAtomic64UseTag = 3;
  177. // Type system.
  178. static const char kDxilTypeSystemMDName[];
  179. static const char kDxilTypeSystemHelperVariablePrefix[];
  180. static const unsigned kDxilTypeSystemStructTag = 0;
  181. static const unsigned kDxilTypeSystemFunctionTag = 1;
  182. static const unsigned kDxilFieldAnnotationSNormTag = 0;
  183. static const unsigned kDxilFieldAnnotationUNormTag = 1;
  184. static const unsigned kDxilFieldAnnotationMatrixTag = 2;
  185. static const unsigned kDxilFieldAnnotationCBufferOffsetTag = 3;
  186. static const unsigned kDxilFieldAnnotationSemanticStringTag = 4;
  187. static const unsigned kDxilFieldAnnotationInterpolationModeTag = 5;
  188. static const unsigned kDxilFieldAnnotationFieldNameTag = 6;
  189. static const unsigned kDxilFieldAnnotationCompTypeTag = 7;
  190. static const unsigned kDxilFieldAnnotationPreciseTag = 8;
  191. static const unsigned kDxilFieldAnnotationCBUsedTag = 9;
  192. // DXR Payload Annotations
  193. static const unsigned kDxilPayloadAnnotationStructTag = 0;
  194. static const unsigned kDxilPayloadFieldAnnotationAccessTag = 0;
  195. // StructAnnotation extended property tags (DXIL 1.5+ only, appended)
  196. static const unsigned kDxilTemplateArgumentsTag = 0; // Name for name-value list of extended struct properties
  197. // TemplateArgument tags
  198. static const unsigned kDxilTemplateArgTypeTag = 0; // Type template argument, followed by undef of type
  199. static const unsigned kDxilTemplateArgIntegralTag = 1; // Integral template argument, followed by i64 value
  200. static const unsigned kDxilTemplateArgValue = 1; // Position of template arg value (type or int)
  201. // Control flow hint.
  202. static const char kDxilControlFlowHintMDName[];
  203. // Resource attribute.
  204. static const char kHLDxilResourceAttributeMDName[];
  205. static const unsigned kHLDxilResourceAttributeNumFields = 2;
  206. static const unsigned kHLDxilResourceAttributeClass = 0;
  207. static const unsigned kHLDxilResourceAttributeMeta = 1;
  208. // Precise attribute.
  209. static const char kDxilPreciseAttributeMDName[];
  210. // NonUniform attribute.
  211. static const char kDxilNonUniformAttributeMDName[];
  212. // Variable debug layout metadata.
  213. static const char kDxilVariableDebugLayoutMDName[];
  214. // Indication of temporary storage metadata.
  215. static const char kDxilTempAllocaMDName[];
  216. // Validator version.
  217. static const char kDxilValidatorVersionMDName[];
  218. // Validator version uses the same constants for fields as kDxilVersion*
  219. // DXR Payload Annotations metadata.
  220. static const char kDxilDxrPayloadAnnotationsMDName[];
  221. // Extended shader property tags.
  222. static const unsigned kDxilShaderFlagsTag = 0;
  223. static const unsigned kDxilGSStateTag = 1;
  224. static const unsigned kDxilDSStateTag = 2;
  225. static const unsigned kDxilHSStateTag = 3;
  226. static const unsigned kDxilNumThreadsTag = 4;
  227. static const unsigned kDxilAutoBindingSpaceTag = 5;
  228. static const unsigned kDxilRayPayloadSizeTag = 6;
  229. static const unsigned kDxilRayAttribSizeTag = 7;
  230. static const unsigned kDxilShaderKindTag = 8;
  231. static const unsigned kDxilMSStateTag = 9;
  232. static const unsigned kDxilASStateTag = 10;
  233. static const unsigned kDxilWaveSizeTag = 11;
  234. static const unsigned kDxilEntryRootSigTag = 12;
  235. // GSState.
  236. static const unsigned kDxilGSStateNumFields = 5;
  237. static const unsigned kDxilGSStateInputPrimitive = 0;
  238. static const unsigned kDxilGSStateMaxVertexCount = 1;
  239. static const unsigned kDxilGSStateActiveStreamMask = 2;
  240. static const unsigned kDxilGSStateOutputStreamTopology = 3;
  241. static const unsigned kDxilGSStateGSInstanceCount = 4;
  242. // DSState.
  243. static const unsigned kDxilDSStateNumFields = 2;
  244. static const unsigned kDxilDSStateTessellatorDomain = 0;
  245. static const unsigned kDxilDSStateInputControlPointCount = 1;
  246. // HSState.
  247. static const unsigned kDxilHSStateNumFields = 7;
  248. static const unsigned kDxilHSStatePatchConstantFunction = 0;
  249. static const unsigned kDxilHSStateInputControlPointCount = 1;
  250. static const unsigned kDxilHSStateOutputControlPointCount = 2;
  251. static const unsigned kDxilHSStateTessellatorDomain = 3;
  252. static const unsigned kDxilHSStateTessellatorPartitioning = 4;
  253. static const unsigned kDxilHSStateTessellatorOutputPrimitive= 5;
  254. static const unsigned kDxilHSStateMaxTessellationFactor = 6;
  255. // MSState.
  256. static const unsigned kDxilMSStateNumFields = 5;
  257. static const unsigned kDxilMSStateNumThreads = 0;
  258. static const unsigned kDxilMSStateMaxVertexCount = 1;
  259. static const unsigned kDxilMSStateMaxPrimitiveCount = 2;
  260. static const unsigned kDxilMSStateOutputTopology = 3;
  261. static const unsigned kDxilMSStatePayloadSizeInBytes = 4;
  262. // ASState.
  263. static const unsigned kDxilASStateNumFields = 2;
  264. static const unsigned kDxilASStateNumThreads = 0;
  265. static const unsigned kDxilASStatePayloadSizeInBytes = 1;
  266. public:
  267. /// Use this class to manipulate metadata of DXIL or high-level DX IR specific fields in the record.
  268. class ExtraPropertyHelper {
  269. public:
  270. ExtraPropertyHelper(llvm::Module *pModule);
  271. virtual ~ExtraPropertyHelper() {}
  272. virtual void EmitSRVProperties(const DxilResource &SRV, std::vector<llvm::Metadata *> &MDVals) = 0;
  273. virtual void LoadSRVProperties(const llvm::MDOperand &MDO, DxilResource &SRV) = 0;
  274. virtual void EmitUAVProperties(const DxilResource &UAV, std::vector<llvm::Metadata *> &MDVals) = 0;
  275. virtual void LoadUAVProperties(const llvm::MDOperand &MDO, DxilResource &UAV) = 0;
  276. virtual void EmitCBufferProperties(const DxilCBuffer &CB, std::vector<llvm::Metadata *> &MDVals) = 0;
  277. virtual void LoadCBufferProperties(const llvm::MDOperand &MDO, DxilCBuffer &CB) = 0;
  278. virtual void EmitSamplerProperties(const DxilSampler &S, std::vector<llvm::Metadata *> &MDVals) = 0;
  279. virtual void LoadSamplerProperties(const llvm::MDOperand &MDO, DxilSampler &S) = 0;
  280. virtual void EmitSignatureElementProperties(const DxilSignatureElement &SE, std::vector<llvm::Metadata *> &MDVals) = 0;
  281. virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO, DxilSignatureElement &SE) = 0;
  282. protected:
  283. llvm::LLVMContext &m_Ctx;
  284. llvm::Module *m_pModule;
  285. public:
  286. unsigned m_ValMajor, m_ValMinor; // Reported validation version in DXIL
  287. unsigned m_MinValMajor, m_MinValMinor; // Minimum validation version dictated by shader model
  288. bool m_bExtraMetadata;
  289. };
  290. public:
  291. DxilMDHelper(llvm::Module *pModule, std::unique_ptr<ExtraPropertyHelper> EPH);
  292. ~DxilMDHelper();
  293. void SetShaderModel(const ShaderModel *pSM);
  294. const ShaderModel *GetShaderModel() const;
  295. // Dxil version.
  296. void EmitDxilVersion(unsigned Major, unsigned Minor);
  297. void LoadDxilVersion(unsigned &Major, unsigned &Minor);
  298. // Validator version.
  299. void EmitValidatorVersion(unsigned Major, unsigned Minor);
  300. void LoadValidatorVersion(unsigned &Major, unsigned &Minor);
  301. // Shader model.
  302. void EmitDxilShaderModel(const ShaderModel *pSM);
  303. void LoadDxilShaderModel(const ShaderModel *&pSM);
  304. // Intermediate flags
  305. void EmitDxilIntermediateOptions(uint32_t flags);
  306. void LoadDxilIntermediateOptions(uint32_t &flags);
  307. // Entry points.
  308. void EmitDxilEntryPoints(std::vector<llvm::MDNode *> &MDEntries);
  309. void UpdateDxilEntryPoints(std::vector<llvm::MDNode *> &MDEntries);
  310. const llvm::NamedMDNode *GetDxilEntryPoints();
  311. llvm::MDTuple *EmitDxilEntryPointTuple(llvm::Function *pFunc, const std::string &Name, llvm::MDTuple *pSignatures,
  312. llvm::MDTuple *pResources, llvm::MDTuple *pProperties);
  313. void GetDxilEntryPoint(const llvm::MDNode *MDO, llvm::Function *&pFunc, std::string &Name,
  314. const llvm::MDOperand *&pSignatures, const llvm::MDOperand *&pResources,
  315. const llvm::MDOperand *&pProperties);
  316. // Signatures.
  317. llvm::MDTuple *EmitDxilSignatures(const DxilEntrySignature &EntrySig);
  318. void LoadDxilSignatures(const llvm::MDOperand &MDO,
  319. DxilEntrySignature &EntrySig);
  320. llvm::MDTuple *EmitSignatureMetadata(const DxilSignature &Sig);
  321. void EmitRootSignature(std::vector<uint8_t> &SerializedRootSignature);
  322. void LoadSignatureMetadata(const llvm::MDOperand &MDO, DxilSignature &Sig);
  323. llvm::MDTuple *EmitSignatureElement(const DxilSignatureElement &SE);
  324. void LoadSignatureElement(const llvm::MDOperand &MDO, DxilSignatureElement &SE);
  325. void LoadRootSignature(std::vector<uint8_t> &SerializedRootSignature);
  326. // Resources.
  327. llvm::MDTuple *EmitDxilResourceTuple(llvm::MDTuple *pSRVs, llvm::MDTuple *pUAVs,
  328. llvm::MDTuple *pCBuffers, llvm::MDTuple *pSamplers);
  329. void EmitDxilResources(llvm::MDTuple *pDxilResourceTuple);
  330. void UpdateDxilResources(llvm::MDTuple *pDxilResourceTuple);
  331. void GetDxilResources(const llvm::MDOperand &MDO, const llvm::MDTuple *&pSRVs, const llvm::MDTuple *&pUAVs,
  332. const llvm::MDTuple *&pCBuffers, const llvm::MDTuple *&pSamplers);
  333. void EmitDxilResourceBase(const DxilResourceBase &R, llvm::Metadata *ppMDVals[]);
  334. void LoadDxilResourceBase(const llvm::MDOperand &MDO, DxilResourceBase &R);
  335. llvm::MDTuple *EmitDxilSRV(const DxilResource &SRV);
  336. void LoadDxilSRV(const llvm::MDOperand &MDO, DxilResource &SRV);
  337. llvm::MDTuple *EmitDxilUAV(const DxilResource &UAV);
  338. void LoadDxilUAV(const llvm::MDOperand &MDO, DxilResource &UAV);
  339. llvm::MDTuple *EmitDxilCBuffer(const DxilCBuffer &CB);
  340. void LoadDxilCBuffer(const llvm::MDOperand &MDO, DxilCBuffer &CB);
  341. llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
  342. void LoadDxilSampler(const llvm::MDOperand &MDO, DxilSampler &S);
  343. const llvm::MDOperand &GetResourceClass(llvm::MDNode *MD, DXIL::ResourceClass &RC);
  344. void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
  345. void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
  346. void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
  347. // Type system.
  348. void EmitDxilTypeSystem(DxilTypeSystem &TypeSystem, std::vector<llvm::GlobalVariable *> &LLVMUsed);
  349. void LoadDxilTypeSystemNode(const llvm::MDTuple &MDT, DxilTypeSystem &TypeSystem);
  350. void LoadDxilTypeSystem(DxilTypeSystem &TypeSystem);
  351. llvm::Metadata *EmitDxilStructAnnotation(const DxilStructAnnotation &SA);
  352. void LoadDxilStructAnnotation(const llvm::MDOperand &MDO, DxilStructAnnotation &SA);
  353. llvm::Metadata *EmitDxilFieldAnnotation(const DxilFieldAnnotation &FA);
  354. void LoadDxilFieldAnnotation(const llvm::MDOperand &MDO, DxilFieldAnnotation &FA);
  355. llvm::Metadata *EmitDxilFunctionAnnotation(const DxilFunctionAnnotation &FA);
  356. void LoadDxilFunctionAnnotation(const llvm::MDOperand &MDO, DxilFunctionAnnotation &FA);
  357. llvm::Metadata *EmitDxilParamAnnotation(const DxilParameterAnnotation &PA);
  358. void LoadDxilParamAnnotation(const llvm::MDOperand &MDO, DxilParameterAnnotation &PA);
  359. llvm::Metadata *EmitDxilParamAnnotations(const DxilFunctionAnnotation &FA);
  360. void LoadDxilParamAnnotations(const llvm::MDOperand &MDO, DxilFunctionAnnotation &FA);
  361. llvm::Metadata *EmitDxilTemplateArgAnnotation(const DxilTemplateArgAnnotation &annotation);
  362. void LoadDxilTemplateArgAnnotation(const llvm::MDOperand &MDO, DxilTemplateArgAnnotation &annotation);
  363. // DXR Payload Annotations
  364. void EmitDxrPayloadAnnotations(DxilTypeSystem &TypeSystem);
  365. llvm::Metadata *EmitDxrPayloadStructAnnotation(const DxilPayloadAnnotation& SA);
  366. llvm::Metadata *EmitDxrPayloadFieldAnnotation(const DxilPayloadFieldAnnotation &FA, llvm::Type* fieldType);
  367. void LoadDxrPayloadAnnotationNode(const llvm::MDTuple &MDT, DxilTypeSystem &TypeSystem);
  368. void LoadDxrPayloadAnnotations(DxilTypeSystem &TypeSystem);
  369. void LoadDxrPayloadFieldAnnoations(const llvm::MDOperand& MDO, DxilPayloadAnnotation& SA);
  370. void LoadDxrPayloadFieldAnnoation(const llvm::MDOperand &MDO, DxilPayloadFieldAnnotation &FA);
  371. void LoadDxrPayloadAccessQualifiers(const llvm::MDOperand &MDO, DxilPayloadFieldAnnotation &FA);
  372. // Function props.
  373. llvm::MDTuple *EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
  374. const llvm::Function *F);
  375. const llvm::Function *LoadDxilFunctionProps(const llvm::MDTuple *pProps,
  376. hlsl::DxilFunctionProps *props);
  377. llvm::MDTuple *EmitDxilEntryProperties(uint64_t rawShaderFlag,
  378. const hlsl::DxilFunctionProps &props,
  379. uint32_t autoBindingSpace);
  380. void LoadDxilEntryProperties(const llvm::MDOperand &MDO,
  381. uint64_t &rawShaderFlag,
  382. hlsl::DxilFunctionProps &props,
  383. uint32_t &autoBindingSpace);
  384. // ViewId state.
  385. void EmitDxilViewIdState(std::vector<unsigned> &SerializedState);
  386. void LoadDxilViewIdState(std::vector<unsigned> &SerializedState);
  387. // Control flow hints.
  388. static llvm::MDNode *EmitControlFlowHints(llvm::LLVMContext &Ctx, std::vector<DXIL::ControlFlowHint> &hints);
  389. static unsigned GetControlFlowHintMask(const llvm::Instruction *I);
  390. static bool HasControlFlowHintToPreventFlatten(const llvm::Instruction *I);
  391. // Subobjects
  392. void EmitSubobjects(const DxilSubobjects &Subobjects);
  393. void LoadSubobjects(DxilSubobjects &Subobjects);
  394. llvm::Metadata *EmitSubobject(const DxilSubobject &obj);
  395. void LoadSubobject(const llvm::MDNode &MDO, DxilSubobjects &Subobjects);
  396. // Extra metadata present
  397. bool HasExtraMetadata() { return m_bExtraMetadata; }
  398. // Instruction Counters
  399. void EmitDxilCounters(const DxilCounters &counters);
  400. void LoadDxilCounters(DxilCounters &counters) const;
  401. // Shader specific.
  402. private:
  403. llvm::MDTuple *EmitDxilGSState(DXIL::InputPrimitive Primitive, unsigned MaxVertexCount,
  404. unsigned ActiveStreamMask, DXIL::PrimitiveTopology StreamPrimitiveTopology,
  405. unsigned GSInstanceCount);
  406. void LoadDxilGSState(const llvm::MDOperand &MDO, DXIL::InputPrimitive &Primitive, unsigned &MaxVertexCount,
  407. unsigned &ActiveStreamMask, DXIL::PrimitiveTopology &StreamPrimitiveTopology,
  408. unsigned &GSInstanceCount);
  409. llvm::MDTuple *EmitDxilDSState(DXIL::TessellatorDomain Domain, unsigned InputControlPointCount);
  410. void LoadDxilDSState(const llvm::MDOperand &MDO, DXIL::TessellatorDomain &Domain, unsigned &InputControlPointCount);
  411. llvm::MDTuple *EmitDxilHSState(llvm::Function *pPatchConstantFunction,
  412. unsigned InputControlPointCount,
  413. unsigned OutputControlPointCount,
  414. DXIL::TessellatorDomain TessDomain,
  415. DXIL::TessellatorPartitioning TessPartitioning,
  416. DXIL::TessellatorOutputPrimitive TessOutputPrimitive,
  417. float MaxTessFactor);
  418. void LoadDxilHSState(const llvm::MDOperand &MDO,
  419. llvm::Function *&pPatchConstantFunction,
  420. unsigned &InputControlPointCount,
  421. unsigned &OutputControlPointCount,
  422. DXIL::TessellatorDomain &TessDomain,
  423. DXIL::TessellatorPartitioning &TessPartitioning,
  424. DXIL::TessellatorOutputPrimitive &TessOutputPrimitive,
  425. float &MaxTessFactor);
  426. llvm::MDTuple *EmitDxilMSState(const unsigned *NumThreads,
  427. unsigned MaxVertexCount,
  428. unsigned MaxPrimitiveCount,
  429. DXIL::MeshOutputTopology OutputTopology,
  430. unsigned payloadSizeInBytes);
  431. void LoadDxilMSState(const llvm::MDOperand &MDO,
  432. unsigned *NumThreads,
  433. unsigned &MaxVertexCount,
  434. unsigned &MaxPrimitiveCount,
  435. DXIL::MeshOutputTopology &OutputTopology,
  436. unsigned &payloadSizeInBytes);
  437. llvm::MDTuple *EmitDxilASState(const unsigned *NumThreads, unsigned payloadSizeInBytes);
  438. void LoadDxilASState(const llvm::MDOperand &MDO, unsigned *NumThreads, unsigned &payloadSizeInBytes);
  439. void AddCounterIfNonZero(uint32_t value, llvm::StringRef name, std::vector<llvm::Metadata*> &MDVals);
  440. void LoadCounterMD(const llvm::MDOperand &MDName, const llvm::MDOperand &MDValue, DxilCounters &counters) const;
  441. public:
  442. // Utility functions.
  443. static bool IsKnownNamedMetaData(const llvm::NamedMDNode &Node);
  444. static bool IsKnownMetadataID(llvm::LLVMContext &Ctx, unsigned ID);
  445. static void GetKnownMetadataIDs(llvm::LLVMContext &Ctx, llvm::SmallVectorImpl<unsigned> *pIDs);
  446. static void combineDxilMetadata(llvm::Instruction *K, const llvm::Instruction *J);
  447. static llvm::ConstantAsMetadata *Int32ToConstMD(int32_t v, llvm::LLVMContext &Ctx);
  448. llvm::ConstantAsMetadata *Int32ToConstMD(int32_t v);
  449. static llvm::ConstantAsMetadata *Uint32ToConstMD(unsigned v, llvm::LLVMContext &Ctx);
  450. llvm::ConstantAsMetadata *Uint32ToConstMD(unsigned v);
  451. static llvm::ConstantAsMetadata *Uint64ToConstMD(uint64_t v, llvm::LLVMContext &Ctx);
  452. llvm::ConstantAsMetadata *Uint64ToConstMD(uint64_t v);
  453. llvm::ConstantAsMetadata *Int8ToConstMD(int8_t v);
  454. llvm::ConstantAsMetadata *Uint8ToConstMD(uint8_t v);
  455. static llvm::ConstantAsMetadata *BoolToConstMD(bool v, llvm::LLVMContext &Ctx);
  456. llvm::ConstantAsMetadata *BoolToConstMD(bool v);
  457. llvm::ConstantAsMetadata *FloatToConstMD(float v);
  458. static int32_t ConstMDToInt32(const llvm::MDOperand &MDO);
  459. static unsigned ConstMDToUint32(const llvm::MDOperand &MDO);
  460. static uint64_t ConstMDToUint64(const llvm::MDOperand &MDO);
  461. static int8_t ConstMDToInt8(const llvm::MDOperand &MDO);
  462. static uint8_t ConstMDToUint8(const llvm::MDOperand &MDO);
  463. static bool ConstMDToBool(const llvm::MDOperand &MDO);
  464. static float ConstMDToFloat(const llvm::MDOperand &MDO);
  465. static std::string StringMDToString(const llvm::MDOperand &MDO);
  466. static llvm::StringRef StringMDToStringRef(const llvm::MDOperand &MDO);
  467. static llvm::Value *ValueMDToValue(const llvm::MDOperand &MDO);
  468. llvm::MDTuple *Uint32VectorToConstMDTuple(const std::vector<unsigned> &Vec);
  469. void ConstMDTupleToUint32Vector(llvm::MDTuple *pTupleMD, std::vector<unsigned> &Vec);
  470. static bool IsMarkedPrecise(const llvm::Instruction *inst);
  471. static void MarkPrecise(llvm::Instruction *inst);
  472. static bool IsMarkedNonUniform(const llvm::Instruction *inst);
  473. static void MarkNonUniform(llvm::Instruction *inst);
  474. static bool GetVariableDebugLayout(llvm::DbgDeclareInst *inst,
  475. unsigned &StartOffsetInBits, std::vector<DxilDIArrayDim> &ArrayDims);
  476. static void SetVariableDebugLayout(llvm::DbgDeclareInst *inst,
  477. unsigned StartOffsetInBits, const std::vector<DxilDIArrayDim> &ArrayDims);
  478. static void CopyMetadata(llvm::Instruction &I, llvm::Instruction &SrcInst, llvm::ArrayRef<unsigned>WL = llvm::ArrayRef<unsigned>());
  479. private:
  480. llvm::LLVMContext &m_Ctx;
  481. llvm::Module *m_pModule;
  482. const ShaderModel *m_pSM;
  483. std::unique_ptr<ExtraPropertyHelper> m_ExtraPropertyHelper;
  484. unsigned m_ValMajor, m_ValMinor; // Reported validation version in DXIL
  485. unsigned m_MinValMajor, m_MinValMinor; // Minimum validation version dictated by shader model
  486. // Non-fatal if extra metadata is found, but will fail validation.
  487. // This is how metadata can be exteneded.
  488. bool m_bExtraMetadata;
  489. };
  490. /// Use this class to manipulate metadata of extra metadata record properties that are specific to DXIL.
  491. class DxilExtraPropertyHelper : public DxilMDHelper::ExtraPropertyHelper {
  492. public:
  493. DxilExtraPropertyHelper(llvm::Module *pModule);
  494. virtual ~DxilExtraPropertyHelper() {}
  495. virtual void EmitSRVProperties(const DxilResource &SRV, std::vector<llvm::Metadata *> &MDVals);
  496. virtual void LoadSRVProperties(const llvm::MDOperand &MDO, DxilResource &SRV);
  497. virtual void EmitUAVProperties(const DxilResource &UAV, std::vector<llvm::Metadata *> &MDVals);
  498. virtual void LoadUAVProperties(const llvm::MDOperand &MDO, DxilResource &UAV);
  499. virtual void EmitCBufferProperties(const DxilCBuffer &CB, std::vector<llvm::Metadata *> &MDVals);
  500. virtual void LoadCBufferProperties(const llvm::MDOperand &MDO, DxilCBuffer &CB);
  501. virtual void EmitSamplerProperties(const DxilSampler &S, std::vector<llvm::Metadata *> &MDVals);
  502. virtual void LoadSamplerProperties(const llvm::MDOperand &MDO, DxilSampler &S);
  503. virtual void EmitSignatureElementProperties(const DxilSignatureElement &SE, std::vector<llvm::Metadata *> &MDVals);
  504. virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO, DxilSignatureElement &SE);
  505. };
  506. } // namespace hlsl