DxilTypeSystem.h 8.7 KB

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