DxilSignature.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilSignature.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/Support/Global.h"
  10. #include "dxc/HLSL/DxilSignature.h"
  11. #include "dxc/HLSL/DxilSignatureAllocator.h"
  12. #include "dxc/HLSL/DxilSigPoint.h"
  13. #include "llvm/ADT/STLExtras.h"
  14. using std::vector;
  15. using std::unique_ptr;
  16. namespace hlsl {
  17. //------------------------------------------------------------------------------
  18. //
  19. // Singnature methods.
  20. //
  21. DxilSignature::DxilSignature(DXIL::ShaderKind shaderKind,
  22. DXIL::SignatureKind sigKind,
  23. bool useMinPrecision)
  24. : m_sigPointKind(SigPoint::GetKind(shaderKind, sigKind,
  25. /*isPatchConstantFunction*/ false,
  26. /*isSpecialInput*/ false)),
  27. m_UseMinPrecision(useMinPrecision) {}
  28. DxilSignature::DxilSignature(DXIL::SigPointKind sigPointKind,
  29. bool useMinPrecision)
  30. : m_sigPointKind(sigPointKind),
  31. m_UseMinPrecision(useMinPrecision) {}
  32. DxilSignature::DxilSignature(const DxilSignature &src)
  33. : m_sigPointKind(src.m_sigPointKind),
  34. m_UseMinPrecision(src.m_UseMinPrecision) {
  35. const bool bSetID = false;
  36. for (auto &Elt : src.GetElements()) {
  37. std::unique_ptr<DxilSignatureElement> newElt = CreateElement();
  38. newElt->Initialize(Elt->GetName(), Elt->GetCompType(),
  39. Elt->GetInterpolationMode()->GetKind(), Elt->GetRows(),
  40. Elt->GetCols(), Elt->GetStartRow(), Elt->GetStartCol(),
  41. Elt->GetID(), Elt->GetSemanticIndexVec());
  42. AppendElement(std::move(newElt), bSetID);
  43. }
  44. }
  45. DxilSignature::~DxilSignature() {
  46. }
  47. bool DxilSignature::IsInput() const {
  48. return SigPoint::GetSigPoint(m_sigPointKind)->IsInput();
  49. }
  50. bool DxilSignature::IsOutput() const {
  51. return SigPoint::GetSigPoint(m_sigPointKind)->IsOutput();
  52. }
  53. unique_ptr<DxilSignatureElement> DxilSignature::CreateElement() {
  54. return llvm::make_unique<DxilSignatureElement>(m_sigPointKind);
  55. }
  56. unsigned DxilSignature::AppendElement(std::unique_ptr<DxilSignatureElement> pSE, bool bSetID) {
  57. DXASSERT_NOMSG((unsigned)m_Elements.size() < UINT_MAX);
  58. unsigned Id = (unsigned)m_Elements.size();
  59. if (bSetID) {
  60. pSE->SetID(Id);
  61. }
  62. m_Elements.emplace_back(std::move(pSE));
  63. return Id;
  64. }
  65. DxilSignatureElement &DxilSignature::GetElement(unsigned idx) {
  66. return *m_Elements[idx];
  67. }
  68. const DxilSignatureElement &DxilSignature::GetElement(unsigned idx) const {
  69. return *m_Elements[idx];
  70. }
  71. const std::vector<std::unique_ptr<DxilSignatureElement> > &DxilSignature::GetElements() const {
  72. return m_Elements;
  73. }
  74. namespace {
  75. static bool ShouldBeAllocated(const DxilSignatureElement *SE) {
  76. DXIL::SemanticInterpretationKind I = SE->GetInterpretation();
  77. switch (I) {
  78. case DXIL::SemanticInterpretationKind::NA:
  79. case DXIL::SemanticInterpretationKind::NotInSig:
  80. case DXIL::SemanticInterpretationKind::NotPacked:
  81. case DXIL::SemanticInterpretationKind::Shadow:
  82. return false;
  83. default:
  84. break;
  85. }
  86. return true;
  87. }
  88. } // anonymous namespace
  89. bool DxilSignature::IsFullyAllocated() const {
  90. for (auto &SE : m_Elements) {
  91. if (!ShouldBeAllocated(SE.get()))
  92. continue;
  93. if (!SE->IsAllocated())
  94. return false;
  95. }
  96. return true;
  97. }
  98. unsigned DxilSignature::NumVectorsUsed(unsigned streamIndex) const {
  99. unsigned NumVectors = 0;
  100. for (auto &SE : m_Elements) {
  101. if (SE->IsAllocated() && SE->GetOutputStream() == streamIndex)
  102. NumVectors = std::max(NumVectors, (unsigned)SE->GetStartRow() + SE->GetRows());
  103. }
  104. return NumVectors;
  105. }
  106. unsigned DxilSignature::PackElements(DXIL::PackingStrategy packing) {
  107. unsigned rowsUsed = 0;
  108. // Transfer to elements derived from DxilSignatureAllocator::PackElement
  109. std::vector<DxilPackElement> packElements;
  110. for (auto &SE : m_Elements) {
  111. if (ShouldBeAllocated(SE.get()))
  112. packElements.emplace_back(SE.get(), m_UseMinPrecision);
  113. }
  114. if (m_sigPointKind == DXIL::SigPointKind::GSOut) {
  115. // Special case due to support for multiple streams
  116. DxilSignatureAllocator alloc[4] = {{32, UseMinPrecision()},
  117. {32, UseMinPrecision()},
  118. {32, UseMinPrecision()},
  119. {32, UseMinPrecision()}};
  120. std::vector<DxilSignatureAllocator::PackElement*> elements[4];
  121. for (auto &SE : packElements) {
  122. elements[SE.Get()->GetOutputStream()].push_back(&SE);
  123. }
  124. for (unsigned i = 0; i < 4; ++i) {
  125. if (!elements[i].empty()) {
  126. unsigned streamRowsUsed = 0;
  127. switch (packing) {
  128. case DXIL::PackingStrategy::PrefixStable:
  129. streamRowsUsed = alloc[i].PackPrefixStable(elements[i], 0, 32);
  130. break;
  131. case DXIL::PackingStrategy::Optimized:
  132. streamRowsUsed = alloc[i].PackOptimized(elements[i], 0, 32);
  133. break;
  134. default:
  135. DXASSERT(false, "otherwise, invalid packing strategy supplied");
  136. }
  137. if (streamRowsUsed > rowsUsed)
  138. rowsUsed = streamRowsUsed;
  139. }
  140. }
  141. // rowsUsed isn't really meaningful in this case.
  142. return rowsUsed;
  143. }
  144. const SigPoint *SP = SigPoint::GetSigPoint(m_sigPointKind);
  145. DXIL::PackingKind PK = SP->GetPackingKind();
  146. switch (PK) {
  147. case DXIL::PackingKind::None:
  148. // no packing.
  149. break;
  150. case DXIL::PackingKind::InputAssembler:
  151. // incrementally assign each element that belongs in the signature to the start of the next free row
  152. for (auto &SE : packElements) {
  153. SE.SetLocation(rowsUsed, 0);
  154. rowsUsed += SE.GetRows();
  155. }
  156. break;
  157. case DXIL::PackingKind::Vertex:
  158. case DXIL::PackingKind::PatchConstant: {
  159. DxilSignatureAllocator alloc(32, UseMinPrecision());
  160. std::vector<DxilSignatureAllocator::PackElement*> elements;
  161. elements.reserve(packElements.size());
  162. for (auto &SE : packElements){
  163. elements.push_back(&SE);
  164. }
  165. switch (packing) {
  166. case DXIL::PackingStrategy::PrefixStable:
  167. rowsUsed = alloc.PackPrefixStable(elements, 0, 32);
  168. break;
  169. case DXIL::PackingStrategy::Optimized:
  170. rowsUsed = alloc.PackOptimized(elements, 0, 32);
  171. break;
  172. default:
  173. DXASSERT(false, "otherwise, invalid packing strategy supplied");
  174. }
  175. }
  176. break;
  177. case DXIL::PackingKind::Target:
  178. // for SV_Target, assign rows according to semantic index, the rest are unassigned (-1)
  179. // Note: Overlapping semantic indices should be checked elsewhere
  180. for (auto &SE : packElements) {
  181. if (SE.GetKind() != DXIL::SemanticKind::Target)
  182. continue;
  183. unsigned row = SE.Get()->GetSemanticStartIndex();
  184. SE.SetLocation(row, 0);
  185. DXASSERT(SE.GetRows() == 1, "otherwise, SV_Target output not broken into separate rows earlier");
  186. row += SE.GetRows();
  187. if (rowsUsed < row)
  188. rowsUsed = row;
  189. }
  190. break;
  191. case DXIL::PackingKind::Invalid:
  192. default:
  193. DXASSERT(false, "unexpected PackingKind.");
  194. }
  195. return rowsUsed;
  196. }
  197. //------------------------------------------------------------------------------
  198. //
  199. // EntrySingnature methods.
  200. //
  201. DxilEntrySignature::DxilEntrySignature(const DxilEntrySignature &src)
  202. : InputSignature(src.InputSignature), OutputSignature(src.OutputSignature),
  203. PatchConstantSignature(src.PatchConstantSignature) {}
  204. } // namespace hlsl
  205. #include <algorithm>
  206. #include "dxc/HLSL/DxilSignatureAllocator.inl"
  207. #include "dxc/HLSL/DxilSigPoint.inl"
  208. #include "dxc/HLSL/DxilPipelineStateValidation.h"
  209. #include <functional>
  210. #include "dxc/HLSL/ViewIDPipelineValidation.inl"