DxilTypeSystem.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilTypeSystem.cpp //
  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. ///////////////////////////////////////////////////////////////////////////////
  9. #include "dxc/HLSL/DxilTypeSystem.h"
  10. #include "dxc/Support/Global.h"
  11. #include "llvm/IR/Module.h"
  12. #include "llvm/IR/LLVMContext.h"
  13. #include "llvm/Support/raw_ostream.h"
  14. using namespace llvm;
  15. using std::unique_ptr;
  16. using std::string;
  17. using std::vector;
  18. using std::map;
  19. namespace hlsl {
  20. //------------------------------------------------------------------------------
  21. //
  22. // DxilMatrixAnnotation class methods.
  23. //
  24. DxilMatrixAnnotation::DxilMatrixAnnotation()
  25. : Rows(0)
  26. , Cols(0)
  27. , Orientation(MatrixOrientation::Undefined) {
  28. }
  29. //------------------------------------------------------------------------------
  30. //
  31. // DxilFieldAnnotation class methods.
  32. //
  33. DxilFieldAnnotation::DxilFieldAnnotation()
  34. : m_bPrecise(false)
  35. , m_ResourceAttribute(nullptr)
  36. , m_CBufferOffset(UINT_MAX) {
  37. }
  38. bool DxilFieldAnnotation::IsPrecise() const { return m_bPrecise; }
  39. void DxilFieldAnnotation::SetPrecise(bool b) { m_bPrecise = b; }
  40. bool DxilFieldAnnotation::HasMatrixAnnotation() const { return m_Matrix.Cols != 0; }
  41. const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
  42. void DxilFieldAnnotation::SetMatrixAnnotation(const DxilMatrixAnnotation &MA) { m_Matrix = MA; }
  43. bool DxilFieldAnnotation::HasResourceAttribute() const {
  44. return m_ResourceAttribute;
  45. }
  46. llvm::MDNode *DxilFieldAnnotation::GetResourceAttribute() const {
  47. return m_ResourceAttribute;
  48. }
  49. void DxilFieldAnnotation::SetResourceAttribute(llvm::MDNode *MD) {
  50. m_ResourceAttribute = MD;
  51. }
  52. bool DxilFieldAnnotation::HasCBufferOffset() const { return m_CBufferOffset != UINT_MAX; }
  53. unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }
  54. void DxilFieldAnnotation::SetCBufferOffset(unsigned Offset) { m_CBufferOffset = Offset; }
  55. bool DxilFieldAnnotation::HasCompType() const { return m_CompType.GetKind() != CompType::Kind::Invalid; }
  56. const CompType &DxilFieldAnnotation::GetCompType() const { return m_CompType; }
  57. void DxilFieldAnnotation::SetCompType(CompType::Kind kind) { m_CompType = CompType(kind); }
  58. bool DxilFieldAnnotation::HasSemanticString() const { return !m_Semantic.empty(); }
  59. const std::string &DxilFieldAnnotation::GetSemanticString() const { return m_Semantic; }
  60. llvm::StringRef DxilFieldAnnotation::GetSemanticStringRef() const { return llvm::StringRef(m_Semantic); }
  61. void DxilFieldAnnotation::SetSemanticString(const std::string &SemString) { m_Semantic = SemString; }
  62. bool DxilFieldAnnotation::HasInterpolationMode() const { return !m_InterpMode.IsUndefined(); }
  63. const InterpolationMode &DxilFieldAnnotation::GetInterpolationMode() const { return m_InterpMode; }
  64. void DxilFieldAnnotation::SetInterpolationMode(const InterpolationMode &IM) { m_InterpMode = IM; }
  65. bool DxilFieldAnnotation::HasFieldName() const { return !m_FieldName.empty(); }
  66. const std::string &DxilFieldAnnotation::GetFieldName() const { return m_FieldName; }
  67. void DxilFieldAnnotation::SetFieldName(const std::string &FieldName) { m_FieldName = FieldName; }
  68. //------------------------------------------------------------------------------
  69. //
  70. // DxilStructAnnotation class methods.
  71. //
  72. unsigned DxilStructAnnotation::GetNumFields() const {
  73. return (unsigned)m_FieldAnnotations.size();
  74. }
  75. DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) {
  76. return m_FieldAnnotations[FieldIdx];
  77. }
  78. const DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) const {
  79. return m_FieldAnnotations[FieldIdx];
  80. }
  81. const StructType *DxilStructAnnotation::GetStructType() const {
  82. return m_pStructType;
  83. }
  84. unsigned DxilStructAnnotation::GetCBufferSize() const { return m_CBufferSize; }
  85. void DxilStructAnnotation::SetCBufferSize(unsigned size) { m_CBufferSize = size; }
  86. void DxilStructAnnotation::MarkEmptyStruct() { m_FieldAnnotations.clear(); }
  87. bool DxilStructAnnotation::IsEmptyStruct() { return m_FieldAnnotations.empty(); }
  88. //------------------------------------------------------------------------------
  89. //
  90. // DxilParameterAnnotation class methods.
  91. //
  92. DxilParameterAnnotation::DxilParameterAnnotation()
  93. : m_inputQual(DxilParamInputQual::In), DxilFieldAnnotation() {
  94. }
  95. DxilParamInputQual DxilParameterAnnotation::GetParamInputQual() const {
  96. return m_inputQual;
  97. }
  98. void DxilParameterAnnotation::SetParamInputQual(DxilParamInputQual qual) {
  99. m_inputQual = qual;
  100. }
  101. const std::vector<unsigned> &DxilParameterAnnotation::GetSemanticIndexVec() const {
  102. return m_semanticIndex;
  103. }
  104. void DxilParameterAnnotation::SetSemanticIndexVec(const std::vector<unsigned> &Vec) {
  105. m_semanticIndex = Vec;
  106. }
  107. void DxilParameterAnnotation::AppendSemanticIndex(unsigned SemIdx) {
  108. m_semanticIndex.emplace_back(SemIdx);
  109. }
  110. //------------------------------------------------------------------------------
  111. //
  112. // DxilFunctionAnnotation class methods.
  113. //
  114. unsigned DxilFunctionAnnotation::GetNumParameters() const {
  115. return (unsigned)m_parameterAnnotations.size();
  116. }
  117. DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) {
  118. return m_parameterAnnotations[ParamIdx];
  119. }
  120. const DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) const {
  121. return m_parameterAnnotations[ParamIdx];
  122. }
  123. DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() {
  124. return m_retTypeAnnotation;
  125. }
  126. const DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() const {
  127. return m_retTypeAnnotation;
  128. }
  129. const Function *DxilFunctionAnnotation::GetFunction() const {
  130. return m_pFunction;
  131. }
  132. //------------------------------------------------------------------------------
  133. //
  134. // DxilStructAnnotationSystem class methods.
  135. //
  136. DxilTypeSystem::DxilTypeSystem(Module *pModule)
  137. : m_pModule(pModule) {
  138. }
  139. DxilStructAnnotation *DxilTypeSystem::AddStructAnnotation(const StructType *pStructType) {
  140. DXASSERT_NOMSG(m_StructAnnotations.find(pStructType) == m_StructAnnotations.end());
  141. DxilStructAnnotation *pA = new DxilStructAnnotation();
  142. m_StructAnnotations[pStructType] = unique_ptr<DxilStructAnnotation>(pA);
  143. pA->m_pStructType = pStructType;
  144. pA->m_FieldAnnotations.resize(pStructType->getNumElements());
  145. return pA;
  146. }
  147. DxilStructAnnotation *DxilTypeSystem::GetStructAnnotation(const StructType *pStructType) {
  148. auto it = m_StructAnnotations.find(pStructType);
  149. if (it != m_StructAnnotations.end()) {
  150. return it->second.get();
  151. } else {
  152. return nullptr;
  153. }
  154. }
  155. void DxilTypeSystem::EraseStructAnnotation(const StructType *pStructType) {
  156. DXASSERT_NOMSG(m_StructAnnotations.count(pStructType));
  157. m_StructAnnotations.remove_if([pStructType](
  158. const std::pair<const StructType *, std::unique_ptr<DxilStructAnnotation>>
  159. &I) { return pStructType == I.first; });
  160. }
  161. DxilTypeSystem::StructAnnotationMap &DxilTypeSystem::GetStructAnnotationMap() {
  162. return m_StructAnnotations;
  163. }
  164. DxilFunctionAnnotation *DxilTypeSystem::AddFunctionAnnotation(const Function *pFunction) {
  165. DXASSERT_NOMSG(m_FunctionAnnotations.find(pFunction) == m_FunctionAnnotations.end());
  166. DxilFunctionAnnotation *pA = new DxilFunctionAnnotation();
  167. m_FunctionAnnotations[pFunction] = unique_ptr<DxilFunctionAnnotation>(pA);
  168. pA->m_pFunction = pFunction;
  169. pA->m_parameterAnnotations.resize(pFunction->getFunctionType()->getNumParams());
  170. return pA;
  171. }
  172. DxilFunctionAnnotation *DxilTypeSystem::GetFunctionAnnotation(const Function *pFunction) {
  173. auto it = m_FunctionAnnotations.find(pFunction);
  174. if (it != m_FunctionAnnotations.end()) {
  175. return it->second.get();
  176. } else {
  177. return nullptr;
  178. }
  179. }
  180. void DxilTypeSystem::EraseFunctionAnnotation(const Function *pFunction) {
  181. DXASSERT_NOMSG(m_FunctionAnnotations.count(pFunction));
  182. m_FunctionAnnotations.remove_if([pFunction](
  183. const std::pair<const Function *, std::unique_ptr<DxilFunctionAnnotation>>
  184. &I) { return pFunction == I.first; });
  185. }
  186. DxilTypeSystem::FunctionAnnotationMap &DxilTypeSystem::GetFunctionAnnotationMap() {
  187. return m_FunctionAnnotations;
  188. }
  189. StructType *DxilTypeSystem::GetSNormF32Type(unsigned NumComps) {
  190. return GetNormFloatType(CompType::getSNormF32(), NumComps);
  191. }
  192. StructType *DxilTypeSystem::GetUNormF32Type(unsigned NumComps) {
  193. return GetNormFloatType(CompType::getUNormF32(), NumComps);
  194. }
  195. StructType *DxilTypeSystem::GetNormFloatType(CompType CT, unsigned NumComps) {
  196. Type *pCompType = CT.GetLLVMType(m_pModule->getContext());
  197. DXASSERT_NOMSG(pCompType->isFloatTy());
  198. Type *pFieldType = pCompType;
  199. string TypeName;
  200. raw_string_ostream NameStream(TypeName);
  201. if (NumComps > 1) {
  202. (NameStream << "dx.types." << NumComps << "x" << CT.GetName()).flush();
  203. pFieldType = VectorType::get(pFieldType, NumComps);
  204. } else {
  205. (NameStream << "dx.types." << CT.GetName()).flush();
  206. }
  207. StructType *pStructType = m_pModule->getTypeByName(TypeName);
  208. if (pStructType == nullptr) {
  209. pStructType = StructType::create(m_pModule->getContext(), pFieldType, TypeName);
  210. DxilStructAnnotation &TA = *AddStructAnnotation(pStructType);
  211. DxilFieldAnnotation &FA = TA.GetFieldAnnotation(0);
  212. FA.SetCompType(CT.GetKind());
  213. DXASSERT_NOMSG(CT.IsSNorm() || CT.IsUNorm());
  214. }
  215. return pStructType;
  216. }
  217. DXIL::SigPointKind SigPointFromInputQual(DxilParamInputQual Q, DXIL::ShaderKind SK, bool isPC) {
  218. DXASSERT(Q != DxilParamInputQual::Inout, "Inout not expected for SigPointFromInputQual");
  219. switch (SK) {
  220. case DXIL::ShaderKind::Vertex:
  221. switch (Q) {
  222. case DxilParamInputQual::In:
  223. return DXIL::SigPointKind::VSIn;
  224. case DxilParamInputQual::Out:
  225. return DXIL::SigPointKind::VSOut;
  226. }
  227. break;
  228. case DXIL::ShaderKind::Hull:
  229. switch (Q) {
  230. case DxilParamInputQual::In:
  231. if (isPC)
  232. return DXIL::SigPointKind::PCIn;
  233. else
  234. return DXIL::SigPointKind::HSIn;
  235. case DxilParamInputQual::Out:
  236. if (isPC)
  237. return DXIL::SigPointKind::PCOut;
  238. else
  239. return DXIL::SigPointKind::HSCPOut;
  240. case DxilParamInputQual::InputPatch:
  241. return DXIL::SigPointKind::HSCPIn;
  242. case DxilParamInputQual::OutputPatch:
  243. return DXIL::SigPointKind::HSCPOut;
  244. }
  245. break;
  246. case DXIL::ShaderKind::Domain:
  247. switch (Q) {
  248. case DxilParamInputQual::In:
  249. return DXIL::SigPointKind::DSIn;
  250. case DxilParamInputQual::Out:
  251. return DXIL::SigPointKind::DSOut;
  252. case DxilParamInputQual::InputPatch:
  253. case DxilParamInputQual::OutputPatch:
  254. return DXIL::SigPointKind::DSCPIn;
  255. }
  256. break;
  257. case DXIL::ShaderKind::Geometry:
  258. switch (Q) {
  259. case DxilParamInputQual::In:
  260. return DXIL::SigPointKind::GSIn;
  261. case DxilParamInputQual::InputPrimitive:
  262. return DXIL::SigPointKind::GSVIn;
  263. case DxilParamInputQual::OutStream0:
  264. case DxilParamInputQual::OutStream1:
  265. case DxilParamInputQual::OutStream2:
  266. case DxilParamInputQual::OutStream3:
  267. return DXIL::SigPointKind::GSOut;
  268. }
  269. break;
  270. case DXIL::ShaderKind::Pixel:
  271. switch (Q) {
  272. case DxilParamInputQual::In:
  273. return DXIL::SigPointKind::PSIn;
  274. case DxilParamInputQual::Out:
  275. return DXIL::SigPointKind::PSOut;
  276. }
  277. break;
  278. case DXIL::ShaderKind::Compute:
  279. switch (Q) {
  280. case DxilParamInputQual::In:
  281. return DXIL::SigPointKind::CSIn;
  282. }
  283. break;
  284. }
  285. return DXIL::SigPointKind::Invalid;
  286. }
  287. } // namespace hlsl