DxilTypeSystem.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilTypeSystem.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. // DXIL extension to LLVM type system. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include "llvm/ADT/StringRef.h"
  13. #include "llvm/ADT/MapVector.h"
  14. #include "dxc/DXIL/DxilConstants.h"
  15. #include "dxc/DXIL/DxilCompType.h"
  16. #include "dxc/DXIL/DxilInterpolationMode.h"
  17. #include <memory>
  18. #include <string>
  19. #include <vector>
  20. namespace llvm {
  21. class LLVMContext;
  22. class Module;
  23. class Function;
  24. class MDNode;
  25. class Type;
  26. class StructType;
  27. class StringRef;
  28. }
  29. namespace hlsl {
  30. enum class MatrixOrientation { Undefined = 0, RowMajor, ColumnMajor, LastEntry };
  31. struct DxilMatrixAnnotation {
  32. unsigned Rows;
  33. unsigned Cols;
  34. MatrixOrientation Orientation;
  35. DxilMatrixAnnotation();
  36. };
  37. /// Use this class to represent type annotation for structure field.
  38. class DxilFieldAnnotation {
  39. public:
  40. DxilFieldAnnotation();
  41. bool IsPrecise() const;
  42. void SetPrecise(bool b = true);
  43. bool HasMatrixAnnotation() const;
  44. const DxilMatrixAnnotation &GetMatrixAnnotation() const;
  45. void SetMatrixAnnotation(const DxilMatrixAnnotation &MA);
  46. bool HasResourceAttribute() const;
  47. llvm::MDNode *GetResourceAttribute() const;
  48. void SetResourceAttribute(llvm::MDNode *MD);
  49. bool HasCBufferOffset() const;
  50. unsigned GetCBufferOffset() const;
  51. void SetCBufferOffset(unsigned Offset);
  52. bool HasCompType() const;
  53. const CompType &GetCompType() const;
  54. void SetCompType(CompType::Kind kind);
  55. bool HasSemanticString() const;
  56. const std::string &GetSemanticString() const;
  57. llvm::StringRef GetSemanticStringRef() const;
  58. void SetSemanticString(const std::string &SemString);
  59. bool HasInterpolationMode() const;
  60. const InterpolationMode &GetInterpolationMode() const;
  61. void SetInterpolationMode(const InterpolationMode &IM);
  62. bool HasFieldName() const;
  63. const std::string &GetFieldName() const;
  64. void SetFieldName(const std::string &FieldName);
  65. bool IsCBVarUsed() const;
  66. void SetCBVarUsed(bool used);
  67. private:
  68. bool m_bPrecise;
  69. CompType m_CompType;
  70. DxilMatrixAnnotation m_Matrix;
  71. llvm::MDNode *m_ResourceAttribute;
  72. unsigned m_CBufferOffset;
  73. std::string m_Semantic;
  74. InterpolationMode m_InterpMode;
  75. std::string m_FieldName;
  76. bool m_bCBufferVarUsed; // true if this field represents a top level variable in CB structure, and it is used.
  77. };
  78. class DxilTemplateArgAnnotation : DxilFieldAnnotation {
  79. public:
  80. DxilTemplateArgAnnotation();
  81. bool IsType() const;
  82. const llvm::Type *GetType() const;
  83. void SetType(const llvm::Type *pType);
  84. bool IsIntegral() const;
  85. int64_t GetIntegral() const;
  86. void SetIntegral(int64_t i64);
  87. private:
  88. const llvm::Type *m_Type;
  89. int64_t m_Integral;
  90. };
  91. /// Use this class to represent LLVM structure annotation.
  92. class DxilStructAnnotation {
  93. friend class DxilTypeSystem;
  94. public:
  95. unsigned GetNumFields() const;
  96. DxilFieldAnnotation &GetFieldAnnotation(unsigned FieldIdx);
  97. const DxilFieldAnnotation &GetFieldAnnotation(unsigned FieldIdx) const;
  98. const llvm::StructType *GetStructType() const;
  99. void SetStructType(const llvm::StructType *Ty);
  100. unsigned GetCBufferSize() const;
  101. void SetCBufferSize(unsigned size);
  102. void MarkEmptyStruct();
  103. bool IsEmptyStruct();
  104. // For template args, GetNumTemplateArgs() will return 0 if not a template
  105. unsigned GetNumTemplateArgs() const;
  106. void SetNumTemplateArgs(unsigned count);
  107. DxilTemplateArgAnnotation &GetTemplateArgAnnotation(unsigned argIdx);
  108. const DxilTemplateArgAnnotation &GetTemplateArgAnnotation(unsigned argIdx) const;
  109. private:
  110. const llvm::StructType *m_pStructType;
  111. std::vector<DxilFieldAnnotation> m_FieldAnnotations;
  112. unsigned m_CBufferSize; // The size of struct if inside constant buffer.
  113. std::vector<DxilTemplateArgAnnotation> m_TemplateAnnotations;
  114. };
  115. /// Use this class to represent type annotation for DXR payload field.
  116. class DxilPayloadFieldAnnotation {
  117. public:
  118. static unsigned GetBitOffsetForShaderStage(DXIL::PayloadAccessShaderStage shaderStage);
  119. DxilPayloadFieldAnnotation() = default;
  120. bool HasCompType() const;
  121. const CompType &GetCompType() const;
  122. void SetCompType(CompType::Kind kind);
  123. uint32_t GetPayloadFieldQualifierMask() const;
  124. void SetPayloadFieldQualifierMask(uint32_t fieldBitmask);
  125. void AddPayloadFieldQualifier(DXIL::PayloadAccessShaderStage shaderStage, DXIL::PayloadAccessQualifier qualifier);
  126. DXIL::PayloadAccessQualifier GetPayloadFieldQualifier(DXIL::PayloadAccessShaderStage shaderStage) const;
  127. bool HasAnnotations() const;
  128. private:
  129. CompType m_CompType;
  130. unsigned m_bitmask = 0;
  131. };
  132. /// Use this class to represent DXR payload structures.
  133. class DxilPayloadAnnotation {
  134. friend class DxilTypeSystem;
  135. public:
  136. unsigned GetNumFields() const;
  137. DxilPayloadFieldAnnotation &GetFieldAnnotation(unsigned FieldIdx);
  138. const DxilPayloadFieldAnnotation &GetFieldAnnotation(unsigned FieldIdx) const;
  139. const llvm::StructType *GetStructType() const;
  140. void SetStructType(const llvm::StructType *Ty);
  141. private:
  142. const llvm::StructType *m_pStructType;
  143. std::vector<DxilPayloadFieldAnnotation> m_FieldAnnotations;
  144. };
  145. enum class DxilParamInputQual {
  146. In,
  147. Out,
  148. Inout,
  149. InputPatch,
  150. OutputPatch,
  151. OutStream0,
  152. OutStream1,
  153. OutStream2,
  154. OutStream3,
  155. InputPrimitive,
  156. OutIndices,
  157. OutVertices,
  158. OutPrimitives,
  159. InPayload,
  160. };
  161. /// Use this class to represent type annotation for function parameter.
  162. class DxilParameterAnnotation : public DxilFieldAnnotation {
  163. public:
  164. DxilParameterAnnotation();
  165. DxilParamInputQual GetParamInputQual() const;
  166. void SetParamInputQual(DxilParamInputQual qual);
  167. const std::vector<unsigned> &GetSemanticIndexVec() const;
  168. void SetSemanticIndexVec(const std::vector<unsigned> &Vec);
  169. void AppendSemanticIndex(unsigned SemIdx);
  170. private:
  171. DxilParamInputQual m_inputQual;
  172. std::vector<unsigned> m_semanticIndex;
  173. };
  174. /// Use this class to represent LLVM function annotation.
  175. class DxilFunctionAnnotation {
  176. friend class DxilTypeSystem;
  177. public:
  178. unsigned GetNumParameters() const;
  179. DxilParameterAnnotation &GetParameterAnnotation(unsigned ParamIdx);
  180. const DxilParameterAnnotation &GetParameterAnnotation(unsigned ParamIdx) const;
  181. const llvm::Function *GetFunction() const;
  182. DxilParameterAnnotation &GetRetTypeAnnotation();
  183. const DxilParameterAnnotation &GetRetTypeAnnotation() const;
  184. private:
  185. const llvm::Function *m_pFunction;
  186. std::vector<DxilParameterAnnotation> m_parameterAnnotations;
  187. DxilParameterAnnotation m_retTypeAnnotation;
  188. };
  189. /// Use this class to represent structure type annotations in HL and DXIL.
  190. class DxilTypeSystem {
  191. public:
  192. using StructAnnotationMap = llvm::MapVector<const llvm::StructType *, std::unique_ptr<DxilStructAnnotation> >;
  193. using PayloadAnnotationMap = llvm::MapVector<const llvm::StructType *, std::unique_ptr<DxilPayloadAnnotation> >;
  194. using FunctionAnnotationMap = llvm::MapVector<const llvm::Function *, std::unique_ptr<DxilFunctionAnnotation> >;
  195. DxilTypeSystem(llvm::Module *pModule);
  196. DxilStructAnnotation *AddStructAnnotation(const llvm::StructType *pStructType, unsigned numTemplateArgs = 0);
  197. DxilStructAnnotation *GetStructAnnotation(const llvm::StructType *pStructType);
  198. const DxilStructAnnotation *GetStructAnnotation(const llvm::StructType *pStructType) const;
  199. void EraseStructAnnotation(const llvm::StructType *pStructType);
  200. StructAnnotationMap &GetStructAnnotationMap();
  201. const StructAnnotationMap &GetStructAnnotationMap() const;
  202. DxilPayloadAnnotation *AddPayloadAnnotation(const llvm::StructType *pStructType);
  203. DxilPayloadAnnotation *GetPayloadAnnotation(const llvm::StructType *pStructType);
  204. const DxilPayloadAnnotation *GetPayloadAnnotation(const llvm::StructType *pStructType) const;
  205. void ErasePayloadAnnotation(const llvm::StructType *pStructType);
  206. PayloadAnnotationMap &GetPayloadAnnotationMap();
  207. const PayloadAnnotationMap &GetPayloadAnnotationMap() const;
  208. DxilFunctionAnnotation *AddFunctionAnnotation(const llvm::Function *pFunction);
  209. DxilFunctionAnnotation *GetFunctionAnnotation(const llvm::Function *pFunction);
  210. const DxilFunctionAnnotation *GetFunctionAnnotation(const llvm::Function *pFunction) const;
  211. void EraseFunctionAnnotation(const llvm::Function *pFunction);
  212. FunctionAnnotationMap &GetFunctionAnnotationMap();
  213. // Utility methods to create stand-alone SNORM and UNORM.
  214. // We may want to move them to a more centralized place for most utilities.
  215. llvm::StructType *GetSNormF32Type(unsigned NumComps);
  216. llvm::StructType *GetUNormF32Type(unsigned NumComps);
  217. // Methods to copy annotation from another DxilTypeSystem.
  218. void CopyTypeAnnotation(const llvm::Type *Ty, const DxilTypeSystem &src);
  219. void CopyFunctionAnnotation(const llvm::Function *pDstFunction,
  220. const llvm::Function *pSrcFunction,
  221. const DxilTypeSystem &src);
  222. bool UseMinPrecision();
  223. void SetMinPrecision(bool bMinPrecision);
  224. private:
  225. llvm::Module *m_pModule;
  226. StructAnnotationMap m_StructAnnotations;
  227. PayloadAnnotationMap m_PayloadAnnotations;
  228. FunctionAnnotationMap m_FunctionAnnotations;
  229. DXIL::LowPrecisionMode m_LowPrecisionMode;
  230. llvm::StructType *GetNormFloatType(CompType CT, unsigned NumComps);
  231. };
  232. DXIL::SigPointKind SigPointFromInputQual(DxilParamInputQual Q, DXIL::ShaderKind SK, bool isPC);
  233. void RemapObsoleteSemantic(DxilParameterAnnotation &paramInfo, DXIL::SigPointKind sigPoint, llvm::LLVMContext &Context);
  234. class DxilStructTypeIterator
  235. : public std::iterator<std::input_iterator_tag,
  236. std::pair<llvm::Type *, DxilFieldAnnotation *>> {
  237. private:
  238. llvm::StructType *STy;
  239. DxilStructAnnotation *SAnnotation;
  240. unsigned index;
  241. public:
  242. DxilStructTypeIterator(llvm::StructType *sTy,
  243. DxilStructAnnotation *sAnnotation, unsigned idx = 0);
  244. // prefix
  245. DxilStructTypeIterator &operator++();
  246. // postfix
  247. DxilStructTypeIterator operator++(int);
  248. bool operator==(DxilStructTypeIterator iter);
  249. bool operator!=(DxilStructTypeIterator iter);
  250. std::pair<llvm::Type *, DxilFieldAnnotation *> operator*();
  251. };
  252. DxilStructTypeIterator begin(llvm::StructType *STy,
  253. DxilStructAnnotation *SAnno);
  254. DxilStructTypeIterator end(llvm::StructType *STy, DxilStructAnnotation *SAnno);
  255. } // namespace hlsl