DxilTypeSystem.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  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. // DxilStructAnnotation class methods.
  76. //
  77. DxilTemplateArgAnnotation::DxilTemplateArgAnnotation()
  78. : DxilFieldAnnotation(), m_Type(nullptr), m_Integral(0)
  79. {}
  80. bool DxilTemplateArgAnnotation::IsType() const { return m_Type != nullptr; }
  81. const llvm::Type *DxilTemplateArgAnnotation::GetType() const { return m_Type; }
  82. void DxilTemplateArgAnnotation::SetType(const llvm::Type *pType) { m_Type = pType; }
  83. bool DxilTemplateArgAnnotation::IsIntegral() const { return m_Type == nullptr; }
  84. int64_t DxilTemplateArgAnnotation::GetIntegral() const { return m_Integral; }
  85. void DxilTemplateArgAnnotation::SetIntegral(int64_t i64) { m_Type = nullptr; m_Integral = i64; }
  86. //------------------------------------------------------------------------------
  87. //
  88. // DxilStructAnnotation class methods.
  89. //
  90. unsigned DxilStructAnnotation::GetNumFields() const {
  91. return (unsigned)m_FieldAnnotations.size();
  92. }
  93. DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) {
  94. return m_FieldAnnotations[FieldIdx];
  95. }
  96. const DxilFieldAnnotation &DxilStructAnnotation::GetFieldAnnotation(unsigned FieldIdx) const {
  97. return m_FieldAnnotations[FieldIdx];
  98. }
  99. const StructType *DxilStructAnnotation::GetStructType() const {
  100. return m_pStructType;
  101. }
  102. void DxilStructAnnotation::SetStructType(const llvm::StructType *Ty) {
  103. m_pStructType = Ty;
  104. }
  105. unsigned DxilStructAnnotation::GetCBufferSize() const { return m_CBufferSize; }
  106. void DxilStructAnnotation::SetCBufferSize(unsigned size) { m_CBufferSize = size; }
  107. void DxilStructAnnotation::MarkEmptyStruct() { m_FieldAnnotations.clear(); }
  108. bool DxilStructAnnotation::IsEmptyStruct() { return m_FieldAnnotations.empty(); }
  109. // For template args, GetNumTemplateArgs() will return 0 if not a template
  110. unsigned DxilStructAnnotation::GetNumTemplateArgs() const {
  111. return (unsigned)m_TemplateAnnotations.size();
  112. }
  113. void DxilStructAnnotation::SetNumTemplateArgs(unsigned count) {
  114. DXASSERT(m_TemplateAnnotations.empty(), "template args already initialized");
  115. m_TemplateAnnotations.resize(count);
  116. }
  117. DxilTemplateArgAnnotation &DxilStructAnnotation::GetTemplateArgAnnotation(unsigned argIdx) {
  118. return m_TemplateAnnotations[argIdx];
  119. }
  120. const DxilTemplateArgAnnotation &DxilStructAnnotation::GetTemplateArgAnnotation(unsigned argIdx) const {
  121. return m_TemplateAnnotations[argIdx];
  122. }
  123. //------------------------------------------------------------------------------
  124. //
  125. // DxilParameterAnnotation class methods.
  126. //
  127. DxilParameterAnnotation::DxilParameterAnnotation()
  128. : DxilFieldAnnotation(), m_inputQual(DxilParamInputQual::In) {
  129. }
  130. DxilParamInputQual DxilParameterAnnotation::GetParamInputQual() const {
  131. return m_inputQual;
  132. }
  133. void DxilParameterAnnotation::SetParamInputQual(DxilParamInputQual qual) {
  134. m_inputQual = qual;
  135. }
  136. const std::vector<unsigned> &DxilParameterAnnotation::GetSemanticIndexVec() const {
  137. return m_semanticIndex;
  138. }
  139. void DxilParameterAnnotation::SetSemanticIndexVec(const std::vector<unsigned> &Vec) {
  140. m_semanticIndex = Vec;
  141. }
  142. void DxilParameterAnnotation::AppendSemanticIndex(unsigned SemIdx) {
  143. m_semanticIndex.emplace_back(SemIdx);
  144. }
  145. //------------------------------------------------------------------------------
  146. //
  147. // DxilFunctionAnnotation class methods.
  148. //
  149. unsigned DxilFunctionAnnotation::GetNumParameters() const {
  150. return (unsigned)m_parameterAnnotations.size();
  151. }
  152. DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) {
  153. return m_parameterAnnotations[ParamIdx];
  154. }
  155. const DxilParameterAnnotation &DxilFunctionAnnotation::GetParameterAnnotation(unsigned ParamIdx) const {
  156. return m_parameterAnnotations[ParamIdx];
  157. }
  158. DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() {
  159. return m_retTypeAnnotation;
  160. }
  161. const DxilParameterAnnotation &DxilFunctionAnnotation::GetRetTypeAnnotation() const {
  162. return m_retTypeAnnotation;
  163. }
  164. const Function *DxilFunctionAnnotation::GetFunction() const {
  165. return m_pFunction;
  166. }
  167. //------------------------------------------------------------------------------
  168. //
  169. // DxilStructAnnotationSystem class methods.
  170. //
  171. DxilTypeSystem::DxilTypeSystem(Module *pModule)
  172. : m_pModule(pModule),
  173. m_LowPrecisionMode(DXIL::LowPrecisionMode::Undefined) {}
  174. DxilStructAnnotation *DxilTypeSystem::AddStructAnnotation(const StructType *pStructType, unsigned numTemplateArgs) {
  175. DXASSERT_NOMSG(m_StructAnnotations.find(pStructType) == m_StructAnnotations.end());
  176. DxilStructAnnotation *pA = new DxilStructAnnotation();
  177. m_StructAnnotations[pStructType] = unique_ptr<DxilStructAnnotation>(pA);
  178. pA->m_pStructType = pStructType;
  179. pA->m_FieldAnnotations.resize(pStructType->getNumElements());
  180. pA->SetNumTemplateArgs(numTemplateArgs);
  181. return pA;
  182. }
  183. DxilStructAnnotation *DxilTypeSystem::GetStructAnnotation(const StructType *pStructType) {
  184. auto it = m_StructAnnotations.find(pStructType);
  185. if (it != m_StructAnnotations.end()) {
  186. return it->second.get();
  187. } else {
  188. return nullptr;
  189. }
  190. }
  191. const DxilStructAnnotation *
  192. DxilTypeSystem::GetStructAnnotation(const StructType *pStructType) const {
  193. auto it = m_StructAnnotations.find(pStructType);
  194. if (it != m_StructAnnotations.end()) {
  195. return it->second.get();
  196. } else {
  197. return nullptr;
  198. }
  199. }
  200. void DxilTypeSystem::EraseStructAnnotation(const StructType *pStructType) {
  201. DXASSERT_NOMSG(m_StructAnnotations.count(pStructType));
  202. m_StructAnnotations.remove_if([pStructType](
  203. const std::pair<const StructType *, std::unique_ptr<DxilStructAnnotation>>
  204. &I) { return pStructType == I.first; });
  205. }
  206. DxilTypeSystem::StructAnnotationMap &DxilTypeSystem::GetStructAnnotationMap() {
  207. return m_StructAnnotations;
  208. }
  209. DxilFunctionAnnotation *DxilTypeSystem::AddFunctionAnnotation(const Function *pFunction) {
  210. DXASSERT_NOMSG(m_FunctionAnnotations.find(pFunction) == m_FunctionAnnotations.end());
  211. DxilFunctionAnnotation *pA = new DxilFunctionAnnotation();
  212. m_FunctionAnnotations[pFunction] = unique_ptr<DxilFunctionAnnotation>(pA);
  213. pA->m_pFunction = pFunction;
  214. pA->m_parameterAnnotations.resize(pFunction->getFunctionType()->getNumParams());
  215. return pA;
  216. }
  217. DxilFunctionAnnotation *DxilTypeSystem::GetFunctionAnnotation(const Function *pFunction) {
  218. auto it = m_FunctionAnnotations.find(pFunction);
  219. if (it != m_FunctionAnnotations.end()) {
  220. return it->second.get();
  221. } else {
  222. return nullptr;
  223. }
  224. }
  225. const DxilFunctionAnnotation *
  226. DxilTypeSystem::GetFunctionAnnotation(const Function *pFunction) const {
  227. auto it = m_FunctionAnnotations.find(pFunction);
  228. if (it != m_FunctionAnnotations.end()) {
  229. return it->second.get();
  230. } else {
  231. return nullptr;
  232. }
  233. }
  234. void DxilTypeSystem::EraseFunctionAnnotation(const Function *pFunction) {
  235. DXASSERT_NOMSG(m_FunctionAnnotations.count(pFunction));
  236. m_FunctionAnnotations.remove_if([pFunction](
  237. const std::pair<const Function *, std::unique_ptr<DxilFunctionAnnotation>>
  238. &I) { return pFunction == I.first; });
  239. }
  240. DxilTypeSystem::FunctionAnnotationMap &DxilTypeSystem::GetFunctionAnnotationMap() {
  241. return m_FunctionAnnotations;
  242. }
  243. StructType *DxilTypeSystem::GetSNormF32Type(unsigned NumComps) {
  244. return GetNormFloatType(CompType::getSNormF32(), NumComps);
  245. }
  246. StructType *DxilTypeSystem::GetUNormF32Type(unsigned NumComps) {
  247. return GetNormFloatType(CompType::getUNormF32(), NumComps);
  248. }
  249. StructType *DxilTypeSystem::GetNormFloatType(CompType CT, unsigned NumComps) {
  250. Type *pCompType = CT.GetLLVMType(m_pModule->getContext());
  251. DXASSERT_NOMSG(pCompType->isFloatTy());
  252. Type *pFieldType = pCompType;
  253. string TypeName;
  254. raw_string_ostream NameStream(TypeName);
  255. if (NumComps > 1) {
  256. (NameStream << "dx.types." << NumComps << "x" << CT.GetName()).flush();
  257. pFieldType = VectorType::get(pFieldType, NumComps);
  258. } else {
  259. (NameStream << "dx.types." << CT.GetName()).flush();
  260. }
  261. StructType *pStructType = m_pModule->getTypeByName(TypeName);
  262. if (pStructType == nullptr) {
  263. pStructType = StructType::create(m_pModule->getContext(), pFieldType, TypeName);
  264. DxilStructAnnotation &TA = *AddStructAnnotation(pStructType);
  265. DxilFieldAnnotation &FA = TA.GetFieldAnnotation(0);
  266. FA.SetCompType(CT.GetKind());
  267. DXASSERT_NOMSG(CT.IsSNorm() || CT.IsUNorm());
  268. }
  269. return pStructType;
  270. }
  271. void DxilTypeSystem::CopyTypeAnnotation(const llvm::Type *Ty,
  272. const DxilTypeSystem &src) {
  273. if (isa<PointerType>(Ty))
  274. Ty = Ty->getPointerElementType();
  275. while (isa<ArrayType>(Ty))
  276. Ty = Ty->getArrayElementType();
  277. // Only struct type has annotation.
  278. if (!isa<StructType>(Ty))
  279. return;
  280. const StructType *ST = cast<StructType>(Ty);
  281. // Already exist.
  282. if (GetStructAnnotation(ST))
  283. return;
  284. if (const DxilStructAnnotation *annot = src.GetStructAnnotation(ST)) {
  285. DxilStructAnnotation *dstAnnot = AddStructAnnotation(ST);
  286. // Copy the annotation.
  287. *dstAnnot = *annot;
  288. // Copy field type annotations.
  289. for (Type *Ty : ST->elements()) {
  290. CopyTypeAnnotation(Ty, src);
  291. }
  292. }
  293. }
  294. void DxilTypeSystem::CopyFunctionAnnotation(const llvm::Function *pDstFunction,
  295. const llvm::Function *pSrcFunction,
  296. const DxilTypeSystem &src) {
  297. const DxilFunctionAnnotation *annot = src.GetFunctionAnnotation(pSrcFunction);
  298. // Don't have annotation.
  299. if (!annot)
  300. return;
  301. // Already exist.
  302. if (GetFunctionAnnotation(pDstFunction))
  303. return;
  304. DxilFunctionAnnotation *dstAnnot = AddFunctionAnnotation(pDstFunction);
  305. // Copy the annotation.
  306. *dstAnnot = *annot;
  307. dstAnnot->m_pFunction = pDstFunction;
  308. // Clone ret type annotation.
  309. CopyTypeAnnotation(pDstFunction->getReturnType(), src);
  310. // Clone param type annotations.
  311. for (const Argument &arg : pDstFunction->args()) {
  312. CopyTypeAnnotation(arg.getType(), src);
  313. }
  314. }
  315. DXIL::SigPointKind SigPointFromInputQual(DxilParamInputQual Q, DXIL::ShaderKind SK, bool isPC) {
  316. DXASSERT(Q != DxilParamInputQual::Inout, "Inout not expected for SigPointFromInputQual");
  317. switch (SK) {
  318. case DXIL::ShaderKind::Vertex:
  319. switch (Q) {
  320. case DxilParamInputQual::In:
  321. return DXIL::SigPointKind::VSIn;
  322. case DxilParamInputQual::Out:
  323. return DXIL::SigPointKind::VSOut;
  324. default:
  325. break;
  326. }
  327. break;
  328. case DXIL::ShaderKind::Hull:
  329. switch (Q) {
  330. case DxilParamInputQual::In:
  331. if (isPC)
  332. return DXIL::SigPointKind::PCIn;
  333. else
  334. return DXIL::SigPointKind::HSIn;
  335. case DxilParamInputQual::Out:
  336. if (isPC)
  337. return DXIL::SigPointKind::PCOut;
  338. else
  339. return DXIL::SigPointKind::HSCPOut;
  340. case DxilParamInputQual::InputPatch:
  341. return DXIL::SigPointKind::HSCPIn;
  342. case DxilParamInputQual::OutputPatch:
  343. return DXIL::SigPointKind::HSCPOut;
  344. default:
  345. break;
  346. }
  347. break;
  348. case DXIL::ShaderKind::Domain:
  349. switch (Q) {
  350. case DxilParamInputQual::In:
  351. return DXIL::SigPointKind::DSIn;
  352. case DxilParamInputQual::Out:
  353. return DXIL::SigPointKind::DSOut;
  354. case DxilParamInputQual::InputPatch:
  355. case DxilParamInputQual::OutputPatch:
  356. return DXIL::SigPointKind::DSCPIn;
  357. default:
  358. break;
  359. }
  360. break;
  361. case DXIL::ShaderKind::Geometry:
  362. switch (Q) {
  363. case DxilParamInputQual::In:
  364. return DXIL::SigPointKind::GSIn;
  365. case DxilParamInputQual::InputPrimitive:
  366. return DXIL::SigPointKind::GSVIn;
  367. case DxilParamInputQual::OutStream0:
  368. case DxilParamInputQual::OutStream1:
  369. case DxilParamInputQual::OutStream2:
  370. case DxilParamInputQual::OutStream3:
  371. return DXIL::SigPointKind::GSOut;
  372. default:
  373. break;
  374. }
  375. break;
  376. case DXIL::ShaderKind::Pixel:
  377. switch (Q) {
  378. case DxilParamInputQual::In:
  379. return DXIL::SigPointKind::PSIn;
  380. case DxilParamInputQual::Out:
  381. return DXIL::SigPointKind::PSOut;
  382. default:
  383. break;
  384. }
  385. break;
  386. case DXIL::ShaderKind::Compute:
  387. switch (Q) {
  388. case DxilParamInputQual::In:
  389. return DXIL::SigPointKind::CSIn;
  390. default:
  391. break;
  392. }
  393. break;
  394. case DXIL::ShaderKind::Mesh:
  395. switch (Q) {
  396. case DxilParamInputQual::In:
  397. case DxilParamInputQual::InPayload:
  398. return DXIL::SigPointKind::MSIn;
  399. case DxilParamInputQual::OutIndices:
  400. case DxilParamInputQual::OutVertices:
  401. return DXIL::SigPointKind::MSOut;
  402. case DxilParamInputQual::OutPrimitives:
  403. return DXIL::SigPointKind::MSPOut;
  404. default:
  405. break;
  406. }
  407. break;
  408. case DXIL::ShaderKind::Amplification:
  409. switch (Q) {
  410. case DxilParamInputQual::In:
  411. return DXIL::SigPointKind::ASIn;
  412. default:
  413. break;
  414. }
  415. break;
  416. default:
  417. break;
  418. }
  419. return DXIL::SigPointKind::Invalid;
  420. }
  421. void RemapSemantic(llvm::StringRef &oldSemName, llvm::StringRef &oldSemFullName, const char *newSemName,
  422. DxilParameterAnnotation &paramInfo, llvm::LLVMContext &Context) {
  423. // format deprecation warning
  424. Context.emitWarning(Twine("DX9-style semantic \"") + oldSemName + Twine("\" mapped to DX10 system semantic \"") + newSemName +
  425. Twine("\" due to -Gec flag. This functionality is deprecated in newer language versions."));
  426. // create new semantic name with the same index
  427. std::string newSemNameStr(newSemName);
  428. unsigned indexLen = oldSemFullName.size() - oldSemName.size();
  429. if (indexLen > 0) {
  430. newSemNameStr = newSemNameStr.append(oldSemFullName.data() + oldSemName.size(), indexLen);
  431. }
  432. paramInfo.SetSemanticString(newSemNameStr);
  433. }
  434. void RemapObsoleteSemantic(DxilParameterAnnotation &paramInfo, DXIL::SigPointKind sigPoint, llvm::LLVMContext &Context) {
  435. DXASSERT(paramInfo.HasSemanticString(), "expected paramInfo with semantic");
  436. //*ppWarningMsg = nullptr;
  437. llvm::StringRef semFullName = paramInfo.GetSemanticStringRef();
  438. llvm::StringRef semName;
  439. unsigned semIndex;
  440. Semantic::DecomposeNameAndIndex(semFullName, &semName, &semIndex);
  441. if (sigPoint == DXIL::SigPointKind::PSOut) {
  442. if (semName.size() == 5) {
  443. if (_strnicmp(semName.data(), "COLOR", 5) == 0) {
  444. RemapSemantic(semName, semFullName, "SV_Target", paramInfo, Context);
  445. }
  446. else if (_strnicmp(semName.data(), "DEPTH", 5) == 0) {
  447. RemapSemantic(semName, semFullName, "SV_Depth", paramInfo, Context);
  448. }
  449. }
  450. }
  451. else if ((sigPoint == DXIL::SigPointKind::VSOut && semName.size() == 8 && _strnicmp(semName.data(), "POSITION", 8) == 0) ||
  452. (sigPoint == DXIL::SigPointKind::PSIn && semName.size() == 4 && _strnicmp(semName.data(), "VPOS", 4) == 0)) {
  453. RemapSemantic(semName, semFullName, "SV_Position", paramInfo, Context);
  454. }
  455. }
  456. bool DxilTypeSystem::UseMinPrecision() {
  457. return m_LowPrecisionMode == DXIL::LowPrecisionMode::UseMinPrecision;
  458. }
  459. void DxilTypeSystem::SetMinPrecision(bool bMinPrecision) {
  460. DXIL::LowPrecisionMode mode =
  461. bMinPrecision ? DXIL::LowPrecisionMode::UseMinPrecision
  462. : DXIL::LowPrecisionMode::UseNativeLowPrecision;
  463. DXASSERT((mode == m_LowPrecisionMode ||
  464. m_LowPrecisionMode == DXIL::LowPrecisionMode::Undefined),
  465. "LowPrecisionMode should only be set once.");
  466. m_LowPrecisionMode = mode;
  467. }
  468. DxilStructTypeIterator::DxilStructTypeIterator(llvm::StructType *sTy, DxilStructAnnotation *sAnnotation,
  469. unsigned idx)
  470. : STy(sTy), SAnnotation(sAnnotation), index(idx) {
  471. DXASSERT(
  472. sTy->getNumElements() == sAnnotation->GetNumFields(),
  473. "Otherwise the pairing of annotation and struct type does not match.");
  474. }
  475. // prefix
  476. DxilStructTypeIterator &DxilStructTypeIterator::operator++() {
  477. index++;
  478. return *this;
  479. }
  480. // postfix
  481. DxilStructTypeIterator DxilStructTypeIterator::operator++(int) {
  482. DxilStructTypeIterator iter(STy, SAnnotation, index);
  483. index++;
  484. return iter;
  485. }
  486. bool DxilStructTypeIterator::operator==(DxilStructTypeIterator iter) {
  487. return iter.STy == STy && iter.SAnnotation == SAnnotation &&
  488. iter.index == index;
  489. }
  490. bool DxilStructTypeIterator::operator!=(DxilStructTypeIterator iter) { return !(operator==(iter)); }
  491. std::pair<llvm::Type *, DxilFieldAnnotation *> DxilStructTypeIterator::operator*() {
  492. return std::pair<llvm::Type *, DxilFieldAnnotation *>(
  493. STy->getElementType(index), &SAnnotation->GetFieldAnnotation(index));
  494. }
  495. DxilStructTypeIterator begin(llvm::StructType *STy, DxilStructAnnotation *SAnno) {
  496. return { STy, SAnno, 0 };
  497. }
  498. DxilStructTypeIterator end(llvm::StructType *STy, DxilStructAnnotation *SAnno) {
  499. return { STy, SAnno, STy->getNumElements() };
  500. }
  501. } // namespace hlsl