DxilTypeSystem.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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/DXIL/DxilTypeSystem.h"
  10. #include "dxc/DXIL/DxilModule.h"
  11. #include "dxc/Support/Global.h"
  12. #include "dxc/Support/WinFunctions.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/IR/LLVMContext.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. using namespace llvm;
  17. using std::unique_ptr;
  18. using std::string;
  19. using std::vector;
  20. using std::map;
  21. namespace hlsl {
  22. //------------------------------------------------------------------------------
  23. //
  24. // DxilMatrixAnnotation class methods.
  25. //
  26. DxilMatrixAnnotation::DxilMatrixAnnotation()
  27. : Rows(0)
  28. , Cols(0)
  29. , Orientation(MatrixOrientation::Undefined) {
  30. }
  31. //------------------------------------------------------------------------------
  32. //
  33. // DxilFieldAnnotation class methods.
  34. //
  35. DxilFieldAnnotation::DxilFieldAnnotation()
  36. : m_bPrecise(false)
  37. , m_ResourceAttribute(nullptr)
  38. , m_CBufferOffset(UINT_MAX)
  39. , m_bCBufferVarUsed(false)
  40. {}
  41. bool DxilFieldAnnotation::IsPrecise() const { return m_bPrecise; }
  42. void DxilFieldAnnotation::SetPrecise(bool b) { m_bPrecise = b; }
  43. bool DxilFieldAnnotation::HasMatrixAnnotation() const { return m_Matrix.Cols != 0; }
  44. const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
  45. void DxilFieldAnnotation::SetMatrixAnnotation(const DxilMatrixAnnotation &MA) { m_Matrix = MA; }
  46. bool DxilFieldAnnotation::HasResourceAttribute() const {
  47. return m_ResourceAttribute;
  48. }
  49. llvm::MDNode *DxilFieldAnnotation::GetResourceAttribute() const {
  50. return m_ResourceAttribute;
  51. }
  52. void DxilFieldAnnotation::SetResourceAttribute(llvm::MDNode *MD) {
  53. m_ResourceAttribute = MD;
  54. }
  55. bool DxilFieldAnnotation::HasCBufferOffset() const { return m_CBufferOffset != UINT_MAX; }
  56. unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }
  57. void DxilFieldAnnotation::SetCBufferOffset(unsigned Offset) { m_CBufferOffset = Offset; }
  58. bool DxilFieldAnnotation::HasCompType() const { return m_CompType.GetKind() != CompType::Kind::Invalid; }
  59. const CompType &DxilFieldAnnotation::GetCompType() const { return m_CompType; }
  60. void DxilFieldAnnotation::SetCompType(CompType::Kind kind) { m_CompType = CompType(kind); }
  61. bool DxilFieldAnnotation::HasSemanticString() const { return !m_Semantic.empty(); }
  62. const std::string &DxilFieldAnnotation::GetSemanticString() const { return m_Semantic; }
  63. llvm::StringRef DxilFieldAnnotation::GetSemanticStringRef() const { return llvm::StringRef(m_Semantic); }
  64. void DxilFieldAnnotation::SetSemanticString(const std::string &SemString) { m_Semantic = SemString; }
  65. bool DxilFieldAnnotation::HasInterpolationMode() const { return !m_InterpMode.IsUndefined(); }
  66. const InterpolationMode &DxilFieldAnnotation::GetInterpolationMode() const { return m_InterpMode; }
  67. void DxilFieldAnnotation::SetInterpolationMode(const InterpolationMode &IM) { m_InterpMode = IM; }
  68. bool DxilFieldAnnotation::HasFieldName() const { return !m_FieldName.empty(); }
  69. const std::string &DxilFieldAnnotation::GetFieldName() const { return m_FieldName; }
  70. void DxilFieldAnnotation::SetFieldName(const std::string &FieldName) { m_FieldName = FieldName; }
  71. bool DxilFieldAnnotation::IsCBVarUsed() const { return m_bCBufferVarUsed; }
  72. void DxilFieldAnnotation::SetCBVarUsed(bool used) { m_bCBufferVarUsed = used; }
  73. //------------------------------------------------------------------------------
  74. //
  75. // DxilPayloadFieldAnnotation class methods.
  76. //
  77. bool DxilPayloadFieldAnnotation::HasCompType() const { return m_CompType.GetKind() != CompType::Kind::Invalid; }
  78. const CompType &DxilPayloadFieldAnnotation::GetCompType() const { return m_CompType; }
  79. void DxilPayloadFieldAnnotation::SetCompType(CompType::Kind kind) { m_CompType = CompType(kind); }
  80. uint32_t DxilPayloadFieldAnnotation::GetPayloadFieldQualifierMask() const {
  81. return m_bitmask;
  82. }
  83. unsigned DxilPayloadFieldAnnotation::GetBitOffsetForShaderStage(DXIL::PayloadAccessShaderStage shaderStage ) {
  84. unsigned bitOffset = static_cast<unsigned>(shaderStage) *
  85. DXIL::PayloadAccessQualifierBitsPerStage;
  86. return bitOffset;
  87. }
  88. void DxilPayloadFieldAnnotation::SetPayloadFieldQualifierMask(uint32_t fieldBitmask) {
  89. DXASSERT((fieldBitmask & ~DXIL::PayloadAccessQualifierValidMask) == 0,
  90. "Unknown payload access qualifier bits set");
  91. m_bitmask = fieldBitmask & DXIL::PayloadAccessQualifierValidMask;
  92. }
  93. void DxilPayloadFieldAnnotation::AddPayloadFieldQualifier(
  94. DXIL::PayloadAccessShaderStage shaderStage, DXIL::PayloadAccessQualifier qualifier) {
  95. unsigned accessBits = static_cast<unsigned>(qualifier);
  96. DXASSERT((accessBits & ~DXIL::PayloadAccessQualifierValidMaskPerStage) == 0,
  97. "Unknown payload access qualifier bits set");
  98. accessBits &= DXIL::PayloadAccessQualifierValidMaskPerStage;
  99. accessBits <<= GetBitOffsetForShaderStage(shaderStage);
  100. m_bitmask |= accessBits;
  101. }
  102. DXIL::PayloadAccessQualifier DxilPayloadFieldAnnotation::GetPayloadFieldQualifier(
  103. DXIL::PayloadAccessShaderStage shaderStage) const {
  104. int bitOffset = GetBitOffsetForShaderStage(shaderStage);
  105. // default type is always ReadWrite
  106. DXIL::PayloadAccessQualifier accessType = DXIL::PayloadAccessQualifier::ReadWrite;
  107. const unsigned readBit = static_cast<unsigned>(DXIL::PayloadAccessQualifier::Read);
  108. const unsigned writeBit = static_cast<unsigned>(DXIL::PayloadAccessQualifier::Write);
  109. unsigned accessBits = m_bitmask >> bitOffset;
  110. if (accessBits & readBit) {
  111. // set Read if the first bit is set
  112. accessType = DXIL::PayloadAccessQualifier::Read;
  113. }
  114. if (accessBits & writeBit) {
  115. // set Write only if the second bit set, if both are set set to ReadWrite
  116. accessType = accessType == DXIL::PayloadAccessQualifier::ReadWrite
  117. ? DXIL::PayloadAccessQualifier::Write
  118. : DXIL::PayloadAccessQualifier::ReadWrite;
  119. }
  120. return accessType;
  121. }
  122. bool DxilPayloadFieldAnnotation::HasAnnotations() const {
  123. return m_bitmask != 0;
  124. }
  125. //------------------------------------------------------------------------------
  126. //
  127. // DxilStructAnnotation class methods.
  128. //
  129. DxilTemplateArgAnnotation::DxilTemplateArgAnnotation()
  130. : DxilFieldAnnotation(), m_Type(nullptr), m_Integral(0)
  131. {}
  132. bool DxilTemplateArgAnnotation::IsType() const { return m_Type != nullptr; }
  133. const llvm::Type *DxilTemplateArgAnnotation::GetType() const { return m_Type; }
  134. void DxilTemplateArgAnnotation::SetType(const llvm::Type *pType) { m_Type = pType; }
  135. bool DxilTemplateArgAnnotation::IsIntegral() const { return m_Type == nullptr; }
  136. int64_t DxilTemplateArgAnnotation::GetIntegral() const { return m_Integral; }
  137. void DxilTemplateArgAnnotation::SetIntegral(int64_t i64) { m_Type = nullptr; m_Integral = i64; }
  138. unsigned DxilStructAnnotation::GetNumFields() const {
  139. return (unsigned)m_FieldAnnotations.size();
  140. }
  141. DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) {
  142. return m_FieldAnnotations[FieldIdx];
  143. }
  144. const DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) const {
  145. return m_FieldAnnotations[FieldIdx];
  146. }
  147. const StructType *DxilStructAnnotation::GetStructType() const {
  148. return m_pStructType;
  149. }
  150. void DxilStructAnnotation::SetStructType(const llvm::StructType *Ty) {
  151. m_pStructType = Ty;
  152. }
  153. unsigned DxilStructAnnotation::GetCBufferSize() const { return m_CBufferSize; }
  154. void DxilStructAnnotation::SetCBufferSize(unsigned size) { m_CBufferSize = size; }
  155. void DxilStructAnnotation::MarkEmptyStruct() { m_FieldAnnotations.clear(); }
  156. bool DxilStructAnnotation::IsEmptyStruct() { return m_FieldAnnotations.empty(); }
  157. // For template args, GetNumTemplateArgs() will return 0 if not a template
  158. unsigned DxilStructAnnotation::GetNumTemplateArgs() const {
  159. return (unsigned)m_TemplateAnnotations.size();
  160. }
  161. void DxilStructAnnotation::SetNumTemplateArgs(unsigned count) {
  162. DXASSERT(m_TemplateAnnotations.empty(), "template args already initialized");
  163. m_TemplateAnnotations.resize(count);
  164. }
  165. DxilTemplateArgAnnotation &DxilStructAnnotation::GetTemplateArgAnnotation(unsigned argIdx) {
  166. return m_TemplateAnnotations[argIdx];
  167. }
  168. const DxilTemplateArgAnnotation &DxilStructAnnotation::GetTemplateArgAnnotation(unsigned argIdx) const {
  169. return m_TemplateAnnotations[argIdx];
  170. }
  171. //------------------------------------------------------------------------------
  172. //
  173. // DxilParameterAnnotation class methods.
  174. //
  175. DxilParameterAnnotation::DxilParameterAnnotation()
  176. : DxilFieldAnnotation(), m_inputQual(DxilParamInputQual::In) {
  177. }
  178. DxilParamInputQual DxilParameterAnnotation::GetParamInputQual() const {
  179. return m_inputQual;
  180. }
  181. void DxilParameterAnnotation::SetParamInputQual(DxilParamInputQual qual) {
  182. m_inputQual = qual;
  183. }
  184. const std::vector<unsigned> &DxilParameterAnnotation::GetSemanticIndexVec() const {
  185. return m_semanticIndex;
  186. }
  187. void DxilParameterAnnotation::SetSemanticIndexVec(const std::vector<unsigned> &Vec) {
  188. m_semanticIndex = Vec;
  189. }
  190. void DxilParameterAnnotation::AppendSemanticIndex(unsigned SemIdx) {
  191. m_semanticIndex.emplace_back(SemIdx);
  192. }
  193. //------------------------------------------------------------------------------
  194. //
  195. // DxilFunctionAnnotation class methods.
  196. //
  197. unsigned DxilFunctionAnnotation::GetNumParameters() const {
  198. return (unsigned)m_parameterAnnotations.size();
  199. }
  200. DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) {
  201. return m_parameterAnnotations[ParamIdx];
  202. }
  203. const DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) const {
  204. return m_parameterAnnotations[ParamIdx];
  205. }
  206. DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() {
  207. return m_retTypeAnnotation;
  208. }
  209. const DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() const {
  210. return m_retTypeAnnotation;
  211. }
  212. const Function *DxilFunctionAnnotation::GetFunction() const {
  213. return m_pFunction;
  214. }
  215. //------------------------------------------------------------------------------
  216. //
  217. // DxilPayloadAnnotation class methods.
  218. //
  219. unsigned DxilPayloadAnnotation::GetNumFields() const {
  220. return (unsigned)m_FieldAnnotations.size();
  221. }
  222. DxilPayloadFieldAnnotation &DxilPayloadAnnotation::GetFieldAnnotation(unsigned FieldIdx) {
  223. return m_FieldAnnotations[FieldIdx];
  224. }
  225. const DxilPayloadFieldAnnotation &DxilPayloadAnnotation::GetFieldAnnotation(unsigned FieldIdx) const {
  226. return m_FieldAnnotations[FieldIdx];
  227. }
  228. const StructType *DxilPayloadAnnotation::GetStructType() const {
  229. return m_pStructType;
  230. }
  231. void DxilPayloadAnnotation::SetStructType(const llvm::StructType *Ty) {
  232. m_pStructType = Ty;
  233. }
  234. //------------------------------------------------------------------------------
  235. //
  236. // DxilTypeSystem class methods.
  237. //
  238. DxilTypeSystem::DxilTypeSystem(Module *pModule)
  239. : m_pModule(pModule),
  240. m_LowPrecisionMode(DXIL::LowPrecisionMode::Undefined) {}
  241. DxilStructAnnotation *DxilTypeSystem::AddStructAnnotation(const StructType *pStructType, unsigned numTemplateArgs) {
  242. DXASSERT_NOMSG(m_StructAnnotations.find(pStructType) == m_StructAnnotations.end());
  243. DxilStructAnnotation *pA = new DxilStructAnnotation();
  244. m_StructAnnotations[pStructType] = unique_ptr<DxilStructAnnotation>(pA);
  245. pA->m_pStructType = pStructType;
  246. pA->m_FieldAnnotations.resize(pStructType->getNumElements());
  247. pA->SetNumTemplateArgs(numTemplateArgs);
  248. return pA;
  249. }
  250. DxilStructAnnotation *DxilTypeSystem::GetStructAnnotation(const StructType *pStructType) {
  251. auto it = m_StructAnnotations.find(pStructType);
  252. if (it != m_StructAnnotations.end()) {
  253. return it->second.get();
  254. } else {
  255. return nullptr;
  256. }
  257. }
  258. const DxilStructAnnotation *
  259. DxilTypeSystem::GetStructAnnotation(const StructType *pStructType) const {
  260. auto it = m_StructAnnotations.find(pStructType);
  261. if (it != m_StructAnnotations.end()) {
  262. return it->second.get();
  263. } else {
  264. return nullptr;
  265. }
  266. }
  267. void DxilTypeSystem::EraseStructAnnotation(const StructType *pStructType) {
  268. DXASSERT_NOMSG(m_StructAnnotations.count(pStructType));
  269. m_StructAnnotations.remove_if([pStructType](
  270. const std::pair<const StructType *, std::unique_ptr<DxilStructAnnotation>>
  271. &I) { return pStructType == I.first; });
  272. }
  273. DxilTypeSystem::StructAnnotationMap &DxilTypeSystem::GetStructAnnotationMap() {
  274. return m_StructAnnotations;
  275. }
  276. const DxilTypeSystem::StructAnnotationMap &DxilTypeSystem::GetStructAnnotationMap() const{
  277. return m_StructAnnotations;
  278. }
  279. DxilPayloadAnnotation *DxilTypeSystem::AddPayloadAnnotation(const StructType *pStructType) {
  280. DXASSERT_NOMSG(m_PayloadAnnotations.find(pStructType) == m_PayloadAnnotations.end());
  281. DxilPayloadAnnotation *pA = new DxilPayloadAnnotation();
  282. m_PayloadAnnotations[pStructType] = unique_ptr<DxilPayloadAnnotation>(pA);
  283. pA->m_pStructType = pStructType;
  284. pA->m_FieldAnnotations.resize(pStructType->getNumElements());
  285. return pA;
  286. }
  287. DxilPayloadAnnotation *DxilTypeSystem::GetPayloadAnnotation(const StructType *pStructType) {
  288. auto it = m_PayloadAnnotations.find(pStructType);
  289. if (it != m_PayloadAnnotations.end()) {
  290. return it->second.get();
  291. } else {
  292. return nullptr;
  293. }
  294. }
  295. const DxilPayloadAnnotation *
  296. DxilTypeSystem::GetPayloadAnnotation(const StructType *pStructType) const {
  297. auto it = m_PayloadAnnotations.find(pStructType);
  298. if (it != m_PayloadAnnotations.end()) {
  299. return it->second.get();
  300. } else {
  301. return nullptr;
  302. }
  303. }
  304. void DxilTypeSystem::ErasePayloadAnnotation(const StructType *pStructType) {
  305. DXASSERT_NOMSG(m_StructAnnotations.count(pStructType));
  306. m_PayloadAnnotations.remove_if([pStructType](
  307. const std::pair<const StructType *, std::unique_ptr<DxilPayloadAnnotation>>
  308. &I) { return pStructType == I.first; });
  309. }
  310. DxilTypeSystem::PayloadAnnotationMap &DxilTypeSystem::GetPayloadAnnotationMap() {
  311. return m_PayloadAnnotations;
  312. }
  313. const DxilTypeSystem::PayloadAnnotationMap &DxilTypeSystem::GetPayloadAnnotationMap() const{
  314. return m_PayloadAnnotations;
  315. }
  316. DxilFunctionAnnotation *DxilTypeSystem::AddFunctionAnnotation(const Function *pFunction) {
  317. DXASSERT_NOMSG(m_FunctionAnnotations.find(pFunction) == m_FunctionAnnotations.end());
  318. DxilFunctionAnnotation *pA = new DxilFunctionAnnotation();
  319. m_FunctionAnnotations[pFunction] = unique_ptr<DxilFunctionAnnotation>(pA);
  320. pA->m_pFunction = pFunction;
  321. pA->m_parameterAnnotations.resize(pFunction->getFunctionType()->getNumParams());
  322. return pA;
  323. }
  324. DxilFunctionAnnotation *DxilTypeSystem::GetFunctionAnnotation(const Function *pFunction) {
  325. auto it = m_FunctionAnnotations.find(pFunction);
  326. if (it != m_FunctionAnnotations.end()) {
  327. return it->second.get();
  328. } else {
  329. return nullptr;
  330. }
  331. }
  332. const DxilFunctionAnnotation *
  333. DxilTypeSystem::GetFunctionAnnotation(const Function *pFunction) const {
  334. auto it = m_FunctionAnnotations.find(pFunction);
  335. if (it != m_FunctionAnnotations.end()) {
  336. return it->second.get();
  337. } else {
  338. return nullptr;
  339. }
  340. }
  341. void DxilTypeSystem::EraseFunctionAnnotation(const Function *pFunction) {
  342. DXASSERT_NOMSG(m_FunctionAnnotations.count(pFunction));
  343. m_FunctionAnnotations.remove_if([pFunction](
  344. const std::pair<const Function *, std::unique_ptr<DxilFunctionAnnotation>>
  345. &I) { return pFunction == I.first; });
  346. }
  347. DxilTypeSystem::FunctionAnnotationMap &DxilTypeSystem::GetFunctionAnnotationMap() {
  348. return m_FunctionAnnotations;
  349. }
  350. StructType *DxilTypeSystem::GetSNormF32Type(unsigned NumComps) {
  351. return GetNormFloatType(CompType::getSNormF32(), NumComps);
  352. }
  353. StructType *DxilTypeSystem::GetUNormF32Type(unsigned NumComps) {
  354. return GetNormFloatType(CompType::getUNormF32(), NumComps);
  355. }
  356. StructType *DxilTypeSystem::GetNormFloatType(CompType CT, unsigned NumComps) {
  357. Type *pCompType = CT.GetLLVMType(m_pModule->getContext());
  358. DXASSERT_NOMSG(pCompType->isFloatTy());
  359. Type *pFieldType = pCompType;
  360. string TypeName;
  361. raw_string_ostream NameStream(TypeName);
  362. if (NumComps > 1) {
  363. (NameStream << "dx.types." << NumComps << "x" << CT.GetName()).flush();
  364. pFieldType = VectorType::get(pFieldType, NumComps);
  365. } else {
  366. (NameStream << "dx.types." << CT.GetName()).flush();
  367. }
  368. StructType *pStructType = m_pModule->getTypeByName(TypeName);
  369. if (pStructType == nullptr) {
  370. pStructType = StructType::create(m_pModule->getContext(), pFieldType, TypeName);
  371. DxilStructAnnotation &TA = *AddStructAnnotation(pStructType);
  372. DxilFieldAnnotation &FA = TA.GetFieldAnnotation(0);
  373. FA.SetCompType(CT.GetKind());
  374. DXASSERT_NOMSG(CT.IsSNorm() || CT.IsUNorm());
  375. }
  376. return pStructType;
  377. }
  378. void DxilTypeSystem::CopyTypeAnnotation(const llvm::Type *Ty,
  379. const DxilTypeSystem &src) {
  380. if (isa<PointerType>(Ty))
  381. Ty = Ty->getPointerElementType();
  382. while (isa<ArrayType>(Ty))
  383. Ty = Ty->getArrayElementType();
  384. // Only struct type has annotation.
  385. if (!isa<StructType>(Ty))
  386. return;
  387. const StructType *ST = cast<StructType>(Ty);
  388. // Already exist.
  389. if (GetStructAnnotation(ST))
  390. return;
  391. if (const DxilStructAnnotation *annot = src.GetStructAnnotation(ST)) {
  392. DxilStructAnnotation *dstAnnot = AddStructAnnotation(ST);
  393. // Copy the annotation.
  394. *dstAnnot = *annot;
  395. // Copy field type annotations.
  396. for (Type *Ty : ST->elements()) {
  397. CopyTypeAnnotation(Ty, src);
  398. }
  399. }
  400. }
  401. void DxilTypeSystem::CopyFunctionAnnotation(const llvm::Function *pDstFunction,
  402. const llvm::Function *pSrcFunction,
  403. const DxilTypeSystem &src) {
  404. const DxilFunctionAnnotation *annot = src.GetFunctionAnnotation(pSrcFunction);
  405. // Don't have annotation.
  406. if (!annot)
  407. return;
  408. // Already exist.
  409. if (GetFunctionAnnotation(pDstFunction))
  410. return;
  411. DxilFunctionAnnotation *dstAnnot = AddFunctionAnnotation(pDstFunction);
  412. // Copy the annotation.
  413. *dstAnnot = *annot;
  414. dstAnnot->m_pFunction = pDstFunction;
  415. // Clone ret type annotation.
  416. CopyTypeAnnotation(pDstFunction->getReturnType(), src);
  417. // Clone param type annotations.
  418. for (const Argument &arg : pDstFunction->args()) {
  419. CopyTypeAnnotation(arg.getType(), src);
  420. }
  421. }
  422. DXIL::SigPointKind SigPointFromInputQual(DxilParamInputQual Q, DXIL::ShaderKind SK, bool isPC) {
  423. DXASSERT(Q != DxilParamInputQual::Inout, "Inout not expected for SigPointFromInputQual");
  424. switch (SK) {
  425. case DXIL::ShaderKind::Vertex:
  426. switch (Q) {
  427. case DxilParamInputQual::In:
  428. return DXIL::SigPointKind::VSIn;
  429. case DxilParamInputQual::Out:
  430. return DXIL::SigPointKind::VSOut;
  431. default:
  432. break;
  433. }
  434. break;
  435. case DXIL::ShaderKind::Hull:
  436. switch (Q) {
  437. case DxilParamInputQual::In:
  438. if (isPC)
  439. return DXIL::SigPointKind::PCIn;
  440. else
  441. return DXIL::SigPointKind::HSIn;
  442. case DxilParamInputQual::Out:
  443. if (isPC)
  444. return DXIL::SigPointKind::PCOut;
  445. else
  446. return DXIL::SigPointKind::HSCPOut;
  447. case DxilParamInputQual::InputPatch:
  448. return DXIL::SigPointKind::HSCPIn;
  449. case DxilParamInputQual::OutputPatch:
  450. return DXIL::SigPointKind::HSCPOut;
  451. default:
  452. break;
  453. }
  454. break;
  455. case DXIL::ShaderKind::Domain:
  456. switch (Q) {
  457. case DxilParamInputQual::In:
  458. return DXIL::SigPointKind::DSIn;
  459. case DxilParamInputQual::Out:
  460. return DXIL::SigPointKind::DSOut;
  461. case DxilParamInputQual::InputPatch:
  462. case DxilParamInputQual::OutputPatch:
  463. return DXIL::SigPointKind::DSCPIn;
  464. default:
  465. break;
  466. }
  467. break;
  468. case DXIL::ShaderKind::Geometry:
  469. switch (Q) {
  470. case DxilParamInputQual::In:
  471. return DXIL::SigPointKind::GSIn;
  472. case DxilParamInputQual::InputPrimitive:
  473. return DXIL::SigPointKind::GSVIn;
  474. case DxilParamInputQual::OutStream0:
  475. case DxilParamInputQual::OutStream1:
  476. case DxilParamInputQual::OutStream2:
  477. case DxilParamInputQual::OutStream3:
  478. return DXIL::SigPointKind::GSOut;
  479. default:
  480. break;
  481. }
  482. break;
  483. case DXIL::ShaderKind::Pixel:
  484. switch (Q) {
  485. case DxilParamInputQual::In:
  486. return DXIL::SigPointKind::PSIn;
  487. case DxilParamInputQual::Out:
  488. return DXIL::SigPointKind::PSOut;
  489. default:
  490. break;
  491. }
  492. break;
  493. case DXIL::ShaderKind::Compute:
  494. switch (Q) {
  495. case DxilParamInputQual::In:
  496. return DXIL::SigPointKind::CSIn;
  497. default:
  498. break;
  499. }
  500. break;
  501. case DXIL::ShaderKind::Mesh:
  502. switch (Q) {
  503. case DxilParamInputQual::In:
  504. case DxilParamInputQual::InPayload:
  505. return DXIL::SigPointKind::MSIn;
  506. case DxilParamInputQual::OutIndices:
  507. case DxilParamInputQual::OutVertices:
  508. return DXIL::SigPointKind::MSOut;
  509. case DxilParamInputQual::OutPrimitives:
  510. return DXIL::SigPointKind::MSPOut;
  511. default:
  512. break;
  513. }
  514. break;
  515. case DXIL::ShaderKind::Amplification:
  516. switch (Q) {
  517. case DxilParamInputQual::In:
  518. return DXIL::SigPointKind::ASIn;
  519. default:
  520. break;
  521. }
  522. break;
  523. default:
  524. break;
  525. }
  526. return DXIL::SigPointKind::Invalid;
  527. }
  528. void RemapSemantic(llvm::StringRef &oldSemName, llvm::StringRef &oldSemFullName, const char *newSemName,
  529. DxilParameterAnnotation &paramInfo, llvm::LLVMContext &Context) {
  530. // format deprecation warning
  531. Context.emitWarning(Twine("DX9-style semantic \"") + oldSemName + Twine("\" mapped to DX10 system semantic \"") + newSemName +
  532. Twine("\" due to -Gec flag. This functionality is deprecated in newer language versions."));
  533. // create new semantic name with the same index
  534. std::string newSemNameStr(newSemName);
  535. unsigned indexLen = oldSemFullName.size() - oldSemName.size();
  536. if (indexLen > 0) {
  537. newSemNameStr = newSemNameStr.append(oldSemFullName.data() + oldSemName.size(), indexLen);
  538. }
  539. paramInfo.SetSemanticString(newSemNameStr);
  540. }
  541. void RemapObsoleteSemantic(DxilParameterAnnotation &paramInfo, DXIL::SigPointKind sigPoint, llvm::LLVMContext &Context) {
  542. DXASSERT(paramInfo.HasSemanticString(), "expected paramInfo with semantic");
  543. //*ppWarningMsg = nullptr;
  544. llvm::StringRef semFullName = paramInfo.GetSemanticStringRef();
  545. llvm::StringRef semName;
  546. unsigned semIndex;
  547. Semantic::DecomposeNameAndIndex(semFullName, &semName, &semIndex);
  548. if (sigPoint == DXIL::SigPointKind::PSOut) {
  549. if (semName.size() == 5) {
  550. if (_strnicmp(semName.data(), "COLOR", 5) == 0) {
  551. RemapSemantic(semName, semFullName, "SV_Target", paramInfo, Context);
  552. }
  553. else if (_strnicmp(semName.data(), "DEPTH", 5) == 0) {
  554. RemapSemantic(semName, semFullName, "SV_Depth", paramInfo, Context);
  555. }
  556. }
  557. }
  558. else if ((sigPoint == DXIL::SigPointKind::VSOut && semName.size() == 8 && _strnicmp(semName.data(), "POSITION", 8) == 0) ||
  559. (sigPoint == DXIL::SigPointKind::PSIn && semName.size() == 4 && _strnicmp(semName.data(), "VPOS", 4) == 0)) {
  560. RemapSemantic(semName, semFullName, "SV_Position", paramInfo, Context);
  561. }
  562. }
  563. bool DxilTypeSystem::UseMinPrecision() {
  564. return m_LowPrecisionMode == DXIL::LowPrecisionMode::UseMinPrecision;
  565. }
  566. void DxilTypeSystem::SetMinPrecision(bool bMinPrecision) {
  567. DXIL::LowPrecisionMode mode =
  568. bMinPrecision ? DXIL::LowPrecisionMode::UseMinPrecision
  569. : DXIL::LowPrecisionMode::UseNativeLowPrecision;
  570. DXASSERT((mode == m_LowPrecisionMode ||
  571. m_LowPrecisionMode == DXIL::LowPrecisionMode::Undefined),
  572. "LowPrecisionMode should only be set once.");
  573. m_LowPrecisionMode = mode;
  574. }
  575. DxilStructTypeIterator::DxilStructTypeIterator(llvm::StructType *sTy, DxilStructAnnotation *sAnnotation,
  576. unsigned idx)
  577. : STy(sTy), SAnnotation(sAnnotation), index(idx) {
  578. DXASSERT(
  579. sTy->getNumElements() == sAnnotation->GetNumFields(),
  580. "Otherwise the pairing of annotation and struct type does not match.");
  581. }
  582. // prefix
  583. DxilStructTypeIterator &DxilStructTypeIterator::operator++() {
  584. index++;
  585. return *this;
  586. }
  587. // postfix
  588. DxilStructTypeIterator DxilStructTypeIterator::operator++(int) {
  589. DxilStructTypeIterator iter(STy, SAnnotation, index);
  590. index++;
  591. return iter;
  592. }
  593. bool DxilStructTypeIterator::operator==(DxilStructTypeIterator iter) {
  594. return iter.STy == STy && iter.SAnnotation == SAnnotation &&
  595. iter.index == index;
  596. }
  597. bool DxilStructTypeIterator::operator!=(DxilStructTypeIterator iter) { return !(operator==(iter)); }
  598. std::pair<llvm::Type *, DxilFieldAnnotation *> DxilStructTypeIterator::operator*() {
  599. return std::pair<llvm::Type *, DxilFieldAnnotation *>(
  600. STy->getElementType(index), &SAnnotation->GetFieldAnnotation(index));
  601. }
  602. DxilStructTypeIterator begin(llvm::StructType *STy, DxilStructAnnotation *SAnno) {
  603. return { STy, SAnno, 0 };
  604. }
  605. DxilStructTypeIterator end(llvm::StructType *STy, DxilStructAnnotation *SAnno) {
  606. return { STy, SAnno, STy->getNumElements() };
  607. }
  608. } // namespace hlsl