git.s-ol.nu ~forks/DiligentCore / 19b00dc
Some more updates to D3D12 PSO and ShaderResourceLayoutVk assiduous 9 months ago
3 changed file(s) with 68 addition(s) and 75 deletion(s). Raw diff Collapse all Expand all
162162 return Dst;
163163 }
164164
165 NODISCARD wchar_t* CopyWString(const char* Str)
165 NODISCARD wchar_t* CopyWString(const char* Str, size_t len = 0)
166166 {
167167 if (Str == nullptr)
168168 return nullptr;
169169
170 size_t len = strlen(Str);
171 auto* Dst = Allocate<wchar_t>(len + 1);
170 if (len == 0)
171 len = strlen(Str);
172 else
173 VERIFY_EXPR(len <= strlen(Str));
174
175 auto* Dst = Allocate<wchar_t>(len + 1);
172176 for (size_t i = 0; i < len; ++i)
173177 {
174178 Dst[i] = static_cast<wchar_t>(Str[i]);
180184 NODISCARD Char* CopyString(const String& Str)
181185 {
182186 return CopyString(Str.c_str(), Str.length());
187 }
188
189 NODISCARD wchar_t* CopyWString(const String& Str)
190 {
191 return CopyWString(Str.c_str(), Str.length());
183192 }
184193
185194 private:
2626
2727 #include "pch.h"
2828 #include <array>
29 #include <sstream>
30
2931 #include "PipelineStateD3D12Impl.hpp"
3032 #include "ShaderD3D12Impl.hpp"
3133 #include "D3D12TypeConversions.hpp"
110112 {
111113 #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__)
112114
113 Uint32 UnnamedShaderIndex = 0;
115 Uint32 UnnamedExportIndex = 0;
114116
115117 std::unordered_map<IShader*, LPCWSTR> UniqueShaders;
116
117 const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR {
118 const Uint32 Len = sizeof(Index) * 2;
119 auto* const Dst = TempPool.Allocate<WCHAR>(Len + 1);
120 for (Uint32 i = 0; i < Len; ++i)
121 {
122 Dst[Len - 1 - i] = L"0123456789ABCDEF"[Index & 0x0F];
123 Index >>= 4;
124 }
125 Dst[Len] = 0;
126 return Dst;
127 };
128118
129119 const auto AddDxilLib = [&](IShader* pShader, const char* Name) -> LPCWSTR {
130120 if (pShader == nullptr)
154144 if (Name != nullptr)
155145 ExportDesc.Name = TempPool.CopyWString(Name);
156146 else
157 ExportDesc.Name = ShaderIndexToStr(++UnnamedShaderIndex);
147 {
148 std::stringstream ss;
149 ss << "__Shader_" << std::setfill('0') << std::setw(4) << UnnamedExportIndex++;
150 ExportDesc.Name = TempPool.CopyWString(ss.str());
151 }
158152
159153 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY, &LibDesc});
160154 ShaderBlobs.push_back(pBlob);
206200
207201 auto& PipelineConfig = *TempPool.Construct<D3D12_RAYTRACING_PIPELINE_CONFIG>();
208202 // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all.
209 PipelineConfig.MaxTraceRecursionDepth = CreateInfo.RayTracingPipeline.MaxRecursionDepth + 1;
203 PipelineConfig.MaxTraceRecursionDepth = CreateInfo.RayTracingPipeline.MaxRecursionDepth;
210204 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig});
211205
212206 auto& ShaderConfig = *TempPool.Construct<D3D12_RAYTRACING_SHADER_CONFIG>();
220214 void GetShaderIdentifiers(ID3D12DeviceChild* pSO,
221215 const RayTracingPipelineStateCreateInfo& CreateInfo,
222216 const TNameToGroupIndexMap& NameToGroupIndex,
223 Uint8* ShaderData)
224 {
225 const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
226
217 Uint8* ShaderData,
218 Uint32 ShaderIdentifierSize)
219 {
227220 CComPtr<ID3D12StateObjectProperties> pStateObjectProperties;
228221
229222 auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties));
235228 const auto& GeneralShader = CreateInfo.pGeneralShaders[i];
236229
237230 auto iter = NameToGroupIndex.find(GeneralShader.Name);
238 if (iter == NameToGroupIndex.end())
239 LOG_ERROR_AND_THROW("Failed to get shader group index for general shader group '", GeneralShader.Name, "'");
231 VERIFY(iter != NameToGroupIndex.end(),
232 "Can't find general shader '", GeneralShader.Name,
233 "'. This looks to be a bug as NameToGroupIndex is initialized by "
234 "CopyRTShaderGroupNames() that processes the same general shaders.");
240235
241236 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(GeneralShader.Name).c_str());
242237 if (ShaderID == nullptr)
244239
245240 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
246241 }
242
247243 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
248244 {
249245 const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i];
250246
251247 auto iter = NameToGroupIndex.find(TriHitShader.Name);
252 if (iter == NameToGroupIndex.end())
253 LOG_ERROR_AND_THROW("Failed to get shader group index for triangle hit group '", TriHitShader.Name, "'");
248 VERIFY(iter != NameToGroupIndex.end(),
249 "Can't find triangle hit group '", TriHitShader.Name,
250 "'. This looks to be a bug as NameToGroupIndex is initialized by "
251 "CopyRTShaderGroupNames() that processes the same hit groups.");
254252
255253 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(TriHitShader.Name).c_str());
256254 if (ShaderID == nullptr)
258256
259257 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
260258 }
259
261260 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
262261 {
263262 const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i];
264263
265264 auto iter = NameToGroupIndex.find(ProcHitShader.Name);
266 if (iter == NameToGroupIndex.end())
267 LOG_ERROR_AND_THROW("Failed to get shader group index for procedural hit shader group '", ProcHitShader.Name, "'");
265 VERIFY(iter != NameToGroupIndex.end(),
266 "Can't find procedural hit group '", ProcHitShader.Name,
267 "'. This looks to be a bug as NameToGroupIndex is initialized by "
268 "CopyRTShaderGroupNames() that processes the same hit groups.");
268269
269270 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(ProcHitShader.Name).c_str());
270271 if (ShaderID == nullptr)
722723 if (FAILED(hr))
723724 LOG_ERROR_AND_THROW("Failed to create ray tracing state object");
724725
725 GetShaderIdentifiers(m_pd3d12PSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex, m_pRayTracingPipelineData->ShaderHandles);
726 GetShaderIdentifiers(m_pd3d12PSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex,
727 m_pRayTracingPipelineData->ShaderHandles, m_pRayTracingPipelineData->ShaderHandleSize);
726728
727729 if (*m_Desc.Name != 0)
728730 {
571571 // Mappings from resource name to its index, for every shader stage
572572 std::array<ResourceNameToIndex_t, MAX_SHADERS_IN_PIPELINE> ResourceNameToIndexArray;
573573
574 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr;
575 const Uint32 NumAllowedTypes = 0;
576 const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
577
578574 constexpr bool AllocateImmutableSamplers = true;
579575
580576 std::vector<StringPool> stringPools;
583579 {
584580 stringPools.emplace_back(
585581 Layouts[s].AllocateMemory(ShaderStages[s].Shaders, LayoutDataAllocator, ResourceLayoutDesc,
586 AllowedVarTypes, NumAllowedTypes, ResourceNameToIndexArray[s],
587 AllocateImmutableSamplers));
582 nullptr, 0, ResourceNameToIndexArray[s], AllocateImmutableSamplers));
588583 }
589584
590585 // Current resource index, for every variable type in every shader stage
596591 std::unordered_map<Uint32, std::pair<Uint32, Uint32>> dbgBindings_CacheOffsets;
597592 #endif
598593
599 auto AddResource = [&](const Uint32 ShaderInd,
600 ShaderResourceLayoutVk& ResLayout,
594 auto AddResource = [&](const Uint32 ShaderStageInd,
601595 const SPIRVShaderResources& Resources,
602596 const SPIRVShaderResourceAttribs& Attribs,
603 ResourceNameToIndex_t& ResourceNameToIndex,
604597 std::vector<uint32_t>& SPIRV) //
605598 {
606 const auto ShaderType = Resources.GetShaderType();
607 const SHADER_RESOURCE_VARIABLE_TYPE VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix());
608 if (!IsAllowedType(VarType, AllowedTypeBits))
609 return;
599 auto& ResourceNameToIndex = ResourceNameToIndexArray[ShaderStageInd];
610600
611601 auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name});
612 VERIFY_EXPR(ResIter != ResourceNameToIndex.end());
602 VERIFY(ResIter != ResourceNameToIndex.end(), "Resource '", Attribs.Name,
603 "' is not found in ResourceNameToIndex map. This is a bug as the resource must have been processed by AllocateMemory and added to the map.");
604
605 const auto ShaderType = Resources.GetShaderType();
606 const auto VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix());
607
608 auto& ResLayout = Layouts[ShaderStageInd];
613609
614610 const VkResource* pResource = nullptr;
615611 if (ResIter->second == InvalidResourceIndex)
624620 {
625621 // Separate samplers are enumerated before separate images, so the sampler
626622 // assigned to this separate image must have already been created.
627 SamplerInd = FindAssignedSampler(ResLayout, Resources, Attribs, CurrResInd[ShaderInd][VarType], VarType);
623 SamplerInd = FindAssignedSampler(ResLayout, Resources, Attribs, CurrResInd[ShaderStageInd][VarType], VarType);
628624 }
629625
630626 VkSampler vkImmutableSampler = VK_NULL_HANDLE;
639635
640636 // We reserve enough space for the maximum number of immutable samplers that may be used in the stage,
641637 // but not all of them will necessarily be initialized.
642 auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++);
638 auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderStageInd]++);
643639 VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized. This is unexpected "
644640 "as all resources are deduplicated and should only be initialized once.");
645641 const auto& ImmutableSamplerDesc = ResourceLayoutDesc.ImmutableSamplers[SrcImmutableSamplerInd].Desc;
663659 dbgBindings_CacheOffsets[DescriptorSet] = std::make_pair(Binding, CacheOffset);
664660 #endif
665661
666 auto& ResInd = CurrResInd[ShaderInd][VarType];
662 auto& ResInd = CurrResInd[ShaderStageInd][VarType];
667663 ResIter->second = ResInd;
668664
669665 pResource = ::new (&ResLayout.GetResource(VarType, ResInd++)) VkResource //
670666 {
671667 ResLayout,
672 stringPools[ShaderInd].CopyString(Attribs.Name),
668 stringPools[ShaderStageInd].CopyString(Attribs.Name),
673669 Attribs.ArraySize,
674670 Attribs.Type,
675671 Attribs.GetResourceDimension(),
698694 // First process uniform buffers for ALL shader stages to make sure all UBs go first in every descriptor set
699695 for (size_t s = 0; s < ShaderStages.size(); ++s)
700696 {
701 auto& Shaders = ShaderStages[s].Shaders;
702 auto& Layout = Layouts[s];
703 auto& NameToIdx = ResourceNameToIndexArray[s];
697 auto& Shaders = ShaderStages[s].Shaders;
704698 for (size_t i = 0; i < Shaders.size(); ++i)
705699 {
706700 auto& SPIRV = ShaderStages[s].SPIRVs[i];
707701 auto& Resources = *Shaders[i]->GetShaderResources();
708702 for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n)
709703 {
710 const auto& UB = Resources.GetUB(n);
711 auto VarType = GetShaderVariableType(Resources.GetShaderType(), UB.Name, ResourceLayoutDesc);
712 if (IsAllowedType(VarType, AllowedTypeBits))
713 {
714 AddResource(static_cast<Uint32>(s), Layout, Resources, UB, NameToIdx, SPIRV);
715 }
704 const auto& UB = Resources.GetUB(n);
705 AddResource(static_cast<Uint32>(s), Resources, UB, SPIRV);
716706 }
717707 }
718708 }
720710 // Second, process all storage buffers in all shader stages
721711 for (size_t s = 0; s < ShaderStages.size(); ++s)
722712 {
723 auto& Shaders = ShaderStages[s].Shaders;
724 auto& Layout = Layouts[s];
725 auto& NameToIdx = ResourceNameToIndexArray[s];
713 auto& Shaders = ShaderStages[s].Shaders;
726714 for (size_t i = 0; i < Shaders.size(); ++i)
727715 {
728716 auto& Resources = *Shaders[i]->GetShaderResources();
729717 auto& SPIRV = ShaderStages[s].SPIRVs[i];
730718 for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n)
731719 {
732 const auto& SB = Resources.GetSB(n);
733 auto VarType = GetShaderVariableType(Resources.GetShaderType(), SB.Name, ResourceLayoutDesc);
734 if (IsAllowedType(VarType, AllowedTypeBits))
735 {
736 AddResource(static_cast<Uint32>(s), Layout, Resources, SB, NameToIdx, SPIRV);
737 }
720 const auto& SB = Resources.GetSB(n);
721 AddResource(static_cast<Uint32>(s), Resources, SB, SPIRV);
738722 }
739723 }
740724 }
742726 // Finally, process all other resource types
743727 for (size_t s = 0; s < ShaderStages.size(); ++s)
744728 {
745 auto& Layout = Layouts[s];
746 auto& Shaders = ShaderStages[s].Shaders;
747 auto& NameToIdx = ResourceNameToIndexArray[s];
729 auto& Shaders = ShaderStages[s].Shaders;
748730 for (size_t i = 0; i < Shaders.size(); ++i)
749731 {
750732 auto& Resources = *Shaders[i]->GetShaderResources();
764746 [&](const SPIRVShaderResourceAttribs& Img, Uint32)
765747 {
766748 VERIFY_EXPR(Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageImage || Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer);
767 AddResource(static_cast<Uint32>(s), Layout, Resources, Img, NameToIdx, SPIRV);
749 AddResource(static_cast<Uint32>(s), Resources, Img, SPIRV);
768750 },
769751 [&](const SPIRVShaderResourceAttribs& SmplImg, Uint32)
770752 {
771753 VERIFY_EXPR(SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer);
772 AddResource(static_cast<Uint32>(s), Layout, Resources, SmplImg, NameToIdx, SPIRV);
754 AddResource(static_cast<Uint32>(s), Resources, SmplImg, SPIRV);
773755 },
774756 [&](const SPIRVShaderResourceAttribs& AC, Uint32)
775757 {
776758 VERIFY_EXPR(AC.Type == SPIRVShaderResourceAttribs::ResourceType::AtomicCounter);
777 AddResource(static_cast<Uint32>(s), Layout, Resources, AC, NameToIdx, SPIRV);
759 AddResource(static_cast<Uint32>(s), Resources, AC, SPIRV);
778760 },
779761 [&](const SPIRVShaderResourceAttribs& SepSmpl, Uint32)
780762 {
781763 VERIFY_EXPR(SepSmpl.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler);
782 AddResource(static_cast<Uint32>(s), Layout, Resources, SepSmpl, NameToIdx, SPIRV);
764 AddResource(static_cast<Uint32>(s), Resources, SepSmpl, SPIRV);
783765 },
784766 [&](const SPIRVShaderResourceAttribs& SepImg, Uint32)
785767 {
786768 VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage || SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer);
787 AddResource(static_cast<Uint32>(s), Layout, Resources, SepImg, NameToIdx, SPIRV);
769 AddResource(static_cast<Uint32>(s), Resources, SepImg, SPIRV);
788770 },
789771 [&](const SPIRVShaderResourceAttribs& InputAtt, Uint32)
790772 {
791773 VERIFY_EXPR(InputAtt.Type == SPIRVShaderResourceAttribs::ResourceType::InputAttachment);
792 AddResource(static_cast<Uint32>(s), Layout, Resources, InputAtt, NameToIdx, SPIRV);
774 AddResource(static_cast<Uint32>(s), Resources, InputAtt, SPIRV);
793775 },
794776 [&](const SPIRVShaderResourceAttribs& AccelStruct, Uint32)
795777 {
796778 VERIFY_EXPR(AccelStruct.Type == SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure);
797 AddResource(static_cast<Uint32>(s), Layout, Resources, AccelStruct, NameToIdx, SPIRV);
779 AddResource(static_cast<Uint32>(s), Resources, AccelStruct, SPIRV);
798780 }
799781 );
800782 // clang-format on