DxilPackSignatureElement.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilSignatureElement.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. // Class to pack HLSL signature element. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "dxc/Support/Global.h"
  12. #include "dxc/DXIL/DxilSignature.h"
  13. #include "dxc/HLSL/DxilSignatureAllocator.h"
  14. #include "dxc/DXIL/DxilSigPoint.h"
  15. #include "dxc/HLSL/DxilPackSignatureElement.h"
  16. using namespace hlsl;
  17. using namespace llvm;
  18. namespace hlsl {
  19. unsigned PackDxilSignature(DxilSignature &sig, DXIL::PackingStrategy packing) {
  20. unsigned rowsUsed = 0;
  21. bool bUseMinPrecision = sig.UseMinPrecision();
  22. // Transfer to elements derived from DxilSignatureAllocator::PackElement
  23. std::vector<DxilPackElement> packElements;
  24. for (auto &SE : sig.GetElements()) {
  25. if (DxilSignature::ShouldBeAllocated(SE.get()->GetInterpretation()))
  26. packElements.emplace_back(SE.get(), bUseMinPrecision);
  27. }
  28. DXIL::SigPointKind Kind = sig.GetSigPointKind();
  29. if (Kind == DXIL::SigPointKind::GSOut) {
  30. // Special case due to support for multiple streams
  31. DxilSignatureAllocator alloc[4] = {{32, bUseMinPrecision},
  32. {32, bUseMinPrecision},
  33. {32, bUseMinPrecision},
  34. {32, bUseMinPrecision}};
  35. std::vector<DxilSignatureAllocator::PackElement*> elements[4];
  36. for (auto &SE : packElements) {
  37. elements[SE.Get()->GetOutputStream()].push_back(&SE);
  38. }
  39. for (unsigned i = 0; i < 4; ++i) {
  40. if (!elements[i].empty()) {
  41. unsigned streamRowsUsed = 0;
  42. switch (packing) {
  43. case DXIL::PackingStrategy::PrefixStable:
  44. streamRowsUsed = alloc[i].PackPrefixStable(elements[i], 0, 32);
  45. break;
  46. case DXIL::PackingStrategy::Optimized:
  47. streamRowsUsed = alloc[i].PackOptimized(elements[i], 0, 32);
  48. break;
  49. default:
  50. DXASSERT(false, "otherwise, invalid packing strategy supplied");
  51. }
  52. if (streamRowsUsed > rowsUsed)
  53. rowsUsed = streamRowsUsed;
  54. }
  55. }
  56. // rowsUsed isn't really meaningful in this case.
  57. return rowsUsed;
  58. }
  59. const SigPoint *SP = SigPoint::GetSigPoint(Kind);
  60. DXIL::PackingKind PK = SP->GetPackingKind();
  61. switch (PK) {
  62. case DXIL::PackingKind::None:
  63. // no packing.
  64. break;
  65. case DXIL::PackingKind::InputAssembler:
  66. // incrementally assign each element that belongs in the signature to the start of the next free row
  67. for (auto &SE : packElements) {
  68. SE.SetLocation(rowsUsed, 0);
  69. rowsUsed += SE.GetRows();
  70. }
  71. break;
  72. case DXIL::PackingKind::Vertex:
  73. case DXIL::PackingKind::PatchConstant: {
  74. DxilSignatureAllocator alloc(32, bUseMinPrecision);
  75. std::vector<DxilSignatureAllocator::PackElement*> elements;
  76. elements.reserve(packElements.size());
  77. for (auto &SE : packElements){
  78. elements.push_back(&SE);
  79. }
  80. switch (packing) {
  81. case DXIL::PackingStrategy::PrefixStable:
  82. rowsUsed = alloc.PackPrefixStable(elements, 0, 32);
  83. break;
  84. case DXIL::PackingStrategy::Optimized:
  85. rowsUsed = alloc.PackOptimized(elements, 0, 32);
  86. break;
  87. default:
  88. DXASSERT(false, "otherwise, invalid packing strategy supplied");
  89. }
  90. }
  91. break;
  92. case DXIL::PackingKind::Target:
  93. // for SV_Target, assign rows according to semantic index, the rest are unassigned (-1)
  94. // Note: Overlapping semantic indices should be checked elsewhere
  95. for (auto &SE : packElements) {
  96. if (SE.GetKind() != DXIL::SemanticKind::Target)
  97. continue;
  98. unsigned row = SE.Get()->GetSemanticStartIndex();
  99. SE.SetLocation(row, 0);
  100. DXASSERT(SE.GetRows() == 1, "otherwise, SV_Target output not broken into separate rows earlier");
  101. row += SE.GetRows();
  102. if (rowsUsed < row)
  103. rowsUsed = row;
  104. }
  105. break;
  106. case DXIL::PackingKind::Invalid:
  107. default:
  108. DXASSERT(false, "unexpected PackingKind.");
  109. }
  110. return rowsUsed;
  111. }
  112. }
  113. #include <algorithm>
  114. #include "dxc/HLSL/DxilSignatureAllocator.inl"