DX12Shader.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "DX12Shader.h"
  2. #include "Logging.h"
  3. using namespace Framework;
  4. Framework::DX12ShaderSignature::DX12ShaderSignature(ID3D12Device5* zDevice,
  5. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature)
  6. : ReferenceCounter(),
  7. signature(0),
  8. zDevice(zDevice),
  9. pfnD3D12SerializeRootSignature(pfnD3D12SerializeRootSignature)
  10. {}
  11. Framework::DX12ShaderSignature::~DX12ShaderSignature()
  12. {
  13. if (signature)
  14. {
  15. signature->Release();
  16. }
  17. }
  18. void Framework::DX12ShaderSignature::addRegisterUsage(
  19. DX12ShaderRegister registerType, int registerIndex)
  20. {
  21. addRegisterUsage(registerType, registerIndex, 0);
  22. }
  23. void Framework::DX12ShaderSignature::addRegisterUsage(
  24. DX12ShaderRegister registerType, int registerIndex, int spaceIndex)
  25. {
  26. registerUsages.add({registerType, registerIndex, spaceIndex});
  27. }
  28. void Framework::DX12ShaderSignature::createSignature()
  29. {
  30. if (signature)
  31. {
  32. signature->Release();
  33. signature = 0;
  34. }
  35. D3D12_ROOT_PARAMETER descriptorTable;
  36. descriptorTable.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
  37. descriptorTable.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  38. descriptorTable.DescriptorTable.NumDescriptorRanges
  39. = registerUsages.getEntryCount();
  40. D3D12_DESCRIPTOR_RANGE* descriptorRanges
  41. = new D3D12_DESCRIPTOR_RANGE[registerUsages.getEntryCount()];
  42. int index = 0;
  43. for (const auto& usage : registerUsages)
  44. {
  45. D3D12_DESCRIPTOR_RANGE* range = &descriptorRanges[index];
  46. switch (usage.registerType)
  47. {
  48. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  49. range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
  50. break;
  51. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  52. range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  53. break;
  54. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  55. range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
  56. break;
  57. default:
  58. Logging::error() << "Unknown register type for root signature: "
  59. << usage.registerType;
  60. range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  61. }
  62. range->NumDescriptors
  63. = 1; // TODO: optimize when multiple descriptors are used in a row
  64. // e.g. u0, u1, u2 with the same range then NumDescriptors can
  65. // be 3 for u0 and u1 and u2 would not be needed in this array
  66. range->BaseShaderRegister = usage.registerIndex;
  67. range->RegisterSpace = usage.spaceIndex;
  68. range->OffsetInDescriptorsFromTableStart = index;
  69. index++;
  70. }
  71. descriptorTable.DescriptorTable.pDescriptorRanges = descriptorRanges;
  72. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  73. rootDesc.NumParameters = 1;
  74. rootDesc.pParameters = &descriptorTable;
  75. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
  76. ID3DBlob* pSigBlob = 0;
  77. ID3DBlob* pErrorBlob = 0;
  78. HRESULT hr = pfnD3D12SerializeRootSignature(
  79. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  80. if (pSigBlob)
  81. {
  82. zDevice->CreateRootSignature(0,
  83. pSigBlob->GetBufferPointer(),
  84. pSigBlob->GetBufferSize(),
  85. __uuidof(ID3D12RootSignature),
  86. (void**)&signature);
  87. pSigBlob->Release();
  88. }
  89. if (pErrorBlob)
  90. {
  91. std::string errorMessage(
  92. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  93. pErrorBlob->GetBufferSize());
  94. Logging::error() << "Failed to serialize root signature: "
  95. << errorMessage;
  96. pErrorBlob->Release();
  97. }
  98. delete[] descriptorRanges;
  99. }
  100. ID3D12RootSignature* Framework::DX12ShaderSignature::zSignature() const
  101. {
  102. return signature;
  103. }