diff options
| author | azhirnov <zh1dron@gmail.com> | 2021-02-15 18:04:57 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:31:37 +0000 |
| commit | 0327ded011e0e46fc2821ba10f4b89e00c8bdb64 (patch) | |
| tree | 8020e83853e2ca6a084db6e503074db5f2f84d4b /Graphics/GraphicsEngineD3D12 | |
| parent | PipelineResourceSignatureD3D12Impl: fixed issue with binding combined samplers (diff) | |
| download | DiligentCore-0327ded011e0e46fc2821ba10f4b89e00c8bdb64.tar.gz DiligentCore-0327ded011e0e46fc2821ba10f4b89e00c8bdb64.zip | |
fixed some bugs in dx12 resource signature
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
6 files changed, 166 insertions, 67 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index bbfb6611..d9707c22 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -114,6 +114,18 @@ private: void Destruct(); + struct ResourceInfo + { + PipelineResourceSignatureD3D12Impl* Signature = nullptr; + PipelineResourceDesc const* ResDesc = nullptr; + + explicit operator bool() const + { + return Signature != nullptr && ResDesc != nullptr; + } + }; + ResourceInfo GetResourceInfo(const char* Name, SHADER_TYPE Stage) const; + private: CComPtr<ID3D12DeviceChild> m_pd3d12PSO; RefCntAutoPtr<RootSignatureD3D12> m_RootSig; diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index a2ef646c..37e2d486 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -118,17 +118,23 @@ public: bool IsShaderRecord(const D3DShaderResourceAttribs& CB); - ID3D12RootSignature* Create(ID3D12Device* pDevice, Uint32 RegisterSpace); + bool Create(ID3D12Device* pDevice, Uint32 RegisterSpace); - bool IsDefined() const { return m_ShaderRecordSize > 0 && m_pName != nullptr; } - const char* GetName() const { return m_pName; } - Uint32 GetShaderRegister() const { return 0; } - Uint32 GetRegisterSpace() const { return m_RegisterSpace; } + ID3D12RootSignature* GetD3D12RootSignature() const { return m_pd3d12RootSignature; } + bool IsDefined() const { return m_ShaderRecordSize > 0 && m_pName != nullptr; } + const char* GetName() const { return m_pName; } + Uint32 GetShaderRegister() const { return 0; } + + Uint32 GetRegisterSpace() const + { + VERIFY_EXPR(m_RegisterSpace != ~0U); + return m_RegisterSpace; + } private: const char* m_pName = nullptr; const Uint32 m_ShaderRecordSize = 0; - Uint32 m_RegisterSpace = 0; + Uint32 m_RegisterSpace = ~0u; CComPtr<ID3D12RootSignature> m_pd3d12RootSignature; }; diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp index fd6dddf1..7cab8a5d 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp @@ -260,27 +260,14 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout() SrcImmutableSamplerInd = ResourceToImmutableSamplerInd[AssignedSamplerInd]; } - const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(ResDesc.ResourceType); - Uint32 Register = 0; - Uint32 Space = 0; - if ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0) - { - // All run-time sized arrays are allocated in separate spaces. - Space = NextRTSizedArraySpace++; - Register = 0; - } - else - { - // Normal resources go into space 0. - Space = 0; - Register = NumResources[DescriptorRangeType]; - NumResources[DescriptorRangeType] += ResDesc.ArraySize; - } - - Uint32 SRBRootIndex = ResourceAttribs::InvalidSRBRootIndex; - Uint32 SRBOffsetFromTableStart = ResourceAttribs::InvalidOffset; - Uint32 SigRootIndex = ResourceAttribs::InvalidSigRootIndex; - Uint32 SigOffsetFromTableStart = ResourceAttribs::InvalidOffset; + const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(ResDesc.ResourceType); + const bool IsRTSizedArray = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0; + Uint32 Register = 0; + Uint32 Space = 0; + Uint32 SRBRootIndex = ResourceAttribs::InvalidSRBRootIndex; + Uint32 SRBOffsetFromTableStart = ResourceAttribs::InvalidOffset; + Uint32 SigRootIndex = ResourceAttribs::InvalidSigRootIndex; + Uint32 SigOffsetFromTableStart = ResourceAttribs::InvalidOffset; if (ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC) { @@ -298,6 +285,20 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout() // Do not allocate resource slot for immutable samplers that are also defined as resource if (!(ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && SrcImmutableSamplerInd >= 0)) { + if (IsRTSizedArray) + { + // All run-time sized arrays are allocated in separate spaces. + Space = NextRTSizedArraySpace++; + Register = 0; + } + else + { + // Normal resources go into space 0. + Space = 0; + Register = NumResources[DescriptorRangeType]; + NumResources[DescriptorRangeType] += ResDesc.ArraySize; + } + const auto UseDynamicOffset = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0; const auto IsFormattedBuffer = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0; @@ -322,8 +323,8 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout() } ParamsBuilder.AllocateResourceSlot(ResDesc.ShaderStages, ResDesc.VarType, d3d12RootParamType, - DescriptorRangeType, ResDesc.ArraySize, Register, Space, SRBRootIndex, - SRBOffsetFromTableStart); + DescriptorRangeType, ResDesc.ArraySize, Register, Space, + SRBRootIndex, SRBOffsetFromTableStart); } else { @@ -708,14 +709,14 @@ void PipelineResourceSignatureD3D12Impl::InitializeStaticSRBResources(ShaderReso for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) { - const auto& ResDesc = GetResourceDesc(r); - const auto& Attr = GetResourceAttribs(r); + const auto& ResDesc = GetResourceDesc(r); + const auto& Attr = GetResourceAttribs(r); + const bool IsSampler = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER); VERIFY_EXPR(ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC); - if (Attr.IsImmutableSamplerAssigned()) + if (IsSampler && Attr.IsImmutableSamplerAssigned()) continue; - const bool IsSampler = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER); const auto HeapType = IsSampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; const auto DstRootIndex = Attr.RootIndex(DstCacheType); const auto& SrcRootTable = SrcResourceCache.GetRootTable(Attr.RootIndex(SrcCacheType)); @@ -769,7 +770,7 @@ void PipelineResourceSignatureD3D12Impl::InitializeStaticSRBResources(ShaderReso VERIFY_EXPR(ShdrVisibleHeapCPUDescriptorHandle.ptr != 0 || DstRes.Type == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER); // Root views are not assigned space in the GPU-visible descriptor heap allocation - if (ShdrVisibleHeapCPUDescriptorHandle.ptr != 0 && SrcRes.CPUDescriptorHandle.ptr != 0) + if (ShdrVisibleHeapCPUDescriptorHandle.ptr != 0) { VERIFY_EXPR(SrcRes.CPUDescriptorHandle.ptr != 0); d3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, SrcRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); @@ -1301,10 +1302,6 @@ void BindResourceHelper::CacheCB(IDeviceObject* pBuffer) const GetD3D12Device()->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } - else - { - VERIFY(dbgParamType == D3D12_ROOT_PARAMETER_TYPE_CBV || dbgIsDynamic, "Descriptor in root table can be used only in dynamic tables."); - } auto& BoundDynamicCBsCounter = ResourceCache.GetBoundDynamicCBsCounter(); if (DstRes.pObject != nullptr && DstRes.pObject.RawPtr<const BufferD3D12Impl>()->GetDesc().Usage == USAGE_DYNAMIC) diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 149b0678..908965f8 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -302,13 +302,25 @@ void GetShaderResourceTypeAndFlags(const D3DShaderResourceAttribs& Attribs, OutType = SHADER_RESOURCE_TYPE_TEXTURE_SRV; break; case D3D_SIT_TEXTURE: - OutType = (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV); + if (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) + { + OutType = SHADER_RESOURCE_TYPE_BUFFER_SRV; + OutFlags = PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER; + } + else + OutType = SHADER_RESOURCE_TYPE_TEXTURE_SRV; break; case D3D_SIT_SAMPLER: OutType = SHADER_RESOURCE_TYPE_SAMPLER; break; case D3D_SIT_UAV_RWTYPED: - OutType = (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV); + if (Attribs.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) + { + OutType = SHADER_RESOURCE_TYPE_BUFFER_UAV; + OutFlags = PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER; + } + else + OutType = SHADER_RESOURCE_TYPE_TEXTURE_UAV; break; case D3D_SIT_STRUCTURED: case D3D_SIT_BYTEADDRESS: @@ -507,6 +519,30 @@ void PipelineStateD3D12Impl::CreateDefaultResourceSignature(const PipelineStateC } } +PipelineStateD3D12Impl::ResourceInfo PipelineStateD3D12Impl::GetResourceInfo(const char* Name, SHADER_TYPE Stage) const +{ + ResourceInfo Info; + for (Uint32 sign = 0, SignCount = GetSignatureCount(); sign < SignCount && !Info; ++sign) + { + auto* const pSignature = GetSignature(sign); + if (pSignature == nullptr) + continue; + + for (Uint32 r = 0, ResCount = pSignature->GetTotalResourceCount(); r < ResCount; ++r) + { + const auto& ResDesc = pSignature->GetResourceDesc(r); + + if ((ResDesc.ShaderStages & Stage) != 0 && strcmp(ResDesc.Name, Name) == 0) + { + Info.Signature = pSignature; + Info.ResDesc = &ResDesc; + break; + } + } + } + return Info; +} + void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignatureD3D12* pLocalRootSig) @@ -565,6 +601,12 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr if (!m_RootSig) LOG_ERROR_AND_THROW("Failed to create root signature"); + if (pLocalRootSig != nullptr && pLocalRootSig->IsDefined()) + { + if (!pLocalRootSig->Create(GetDevice()->GetD3D12Device(), m_RootSig->GetTotalSpaces())) + LOG_ERROR_AND_THROW("Failed to create local root signature"); + } + // Verify that pipeline layout is compatible with shader resources and // remap resource bindings. auto* compiler = GetDevice()->GetDxCompiler(); @@ -638,16 +680,19 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr auto* pShader = Shaders[i]; auto& pBytecode = ByteCodes[i]; CComPtr<ID3DBlob> pBlob; + Uint32 VerMajor, VerMinor; + + pShader->GetShaderResources()->GetShaderModel(VerMajor, VerMinor); + const bool IsSM51orAbove = ((VerMajor == 5 && VerMinor >= 1) || VerMajor >= 6); - if (HasImtblSampArray) + if (HasImtblSampArray && IsSM51orAbove) { - Uint32 VerMajor, VerMinor; - pShader->GetShaderResources()->GetShaderModel(VerMajor, VerMinor); + LOG_ERROR_AND_THROW("One of resource signatures uses immutable sampler array that is not allowed in shader model 5.1 and above."); + } - if ((VerMajor == 5 && VerMinor >= 1) || VerMajor >= 6) - { - LOG_ERROR_AND_THROW("One of resource signatures uses immutable sampler array that is not allowed in shader model 5.1 and above."); - } + if (m_RootSig->GetTotalSpaces() > 1 && !IsSM51orAbove) + { + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' compiled with shader model 5.0 or below that is not compatible with register spaces that is used in DirectX 12."); } if (IsDXILBytecode(pBytecode->GetBufferPointer(), pBytecode->GetBufferSize())) @@ -668,33 +713,70 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr } pBytecode = pBlob; - // AZ TODO -#if 0 //def DILIGENT_DEVELOPMENT +#ifdef DILIGENT_DEVELOPMENT const auto& pShaderResources = pShader->GetShaderResources(); m_ShaderResources.emplace_back(pShaderResources); - + // Check compatibility between shader resources and resource signature. - const auto HandleResource = [&](const D3DShaderResourceAttribs& Res, Uint32) // + const auto HandleResource = [&](const D3DShaderResourceAttribs& Attribs, Uint32) // { - if (pLocalRootSig != nullptr && pLocalRootSig->IsShaderRecord(Res)) + if (pLocalRootSig != nullptr && pLocalRootSig->IsShaderRecord(Attribs)) + return; + + if (Attribs.GetInputType() == D3D_SIT_SAMPLER) return; - ResourceInfo Info = {}; - if (!m_RootSig->GetResource(Res.Name, Info)) + auto Info = GetResourceInfo(Attribs.Name, ShaderType); + if (!Info) { - // error + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name, + "' that is not present in any pipeline resource signature that is used to create pipeline state '", + m_Desc.Name, "'."); } - if (Res.BindCount == 0) + SHADER_RESOURCE_TYPE Type; + PIPELINE_RESOURCE_FLAGS Flags; + GetShaderResourceTypeAndFlags(Attribs, Type, Flags); + if (Type != Info.ResDesc->ResourceType) { - if ((Info.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0) + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name, + "' and type '", GetShaderResourceTypeLiteralName(Type), "' that is not compatible with type '", + GetShaderResourceTypeLiteralName(Info.ResDesc->ResourceType), "' in pipeline resource signature '", Info.Signature->GetDesc().Name, "'."); + } + + if ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != (Info.ResDesc->Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) + { + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", Attribs.Name, + "' that is", ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"), + " labeled as formatted buffer, while the same resource specified by the pipeline resource signature '", + Info.Signature->GetDesc().Name, "' is", ((Info.ResDesc->Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"), + " labeled as such."); + } + + if (Attribs.BindCount == 0) + { + if ((Info.ResDesc->Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0) { - // error + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name, + "' that is runtime-sized array, but in resource signature '", Info.Signature->GetDesc().Name, + "' resource defined without PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY flag."); } } - else if (Info.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) + else { - // warning + if (Info.ResDesc->ArraySize < Attribs.BindCount) + { + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", Attribs.Name, + "' whose array size (", Attribs.BindCount, ") is greater than the array size (", + Info.ResDesc->ArraySize, ") specified by the pipeline resource signature '", Info.Signature->GetDesc().Name, "'."); + } + + if (Info.ResDesc->Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) + { + LOG_WARNING_MESSAGE("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Attribs.Name, + "' that defined in resource signature '", Info.Signature->GetDesc().Name, + "' with flag PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY, but resource is not a runtime-sized array."); + } } }; pShaderResources->ProcessResources(HandleResource, HandleResource, HandleResource, HandleResource, HandleResource, HandleResource, HandleResource); @@ -988,7 +1070,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig->GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); - D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device, m_RootSig->GetTotalSpaces())}; + D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.GetD3D12RootSignature()}; if (LocalRoot.pLocalRootSignature) Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot}); diff --git a/Graphics/GraphicsEngineD3D12/src/RootParamsManager.cpp b/Graphics/GraphicsEngineD3D12/src/RootParamsManager.cpp index 7cd54a41..540bea67 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootParamsManager.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootParamsManager.cpp @@ -407,7 +407,9 @@ void RootParamsBuilder::InitializeMgr(IMemoryAllocator& MemAllocator, RootParams { const auto& SrcView = m_RootViews[rv]; const auto& d3d12RootParam = SrcView.d3d12RootParam; - VERIFY(d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV, + VERIFY((d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || + d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || + d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV), "Unexpected parameter type: SBV, SRV or UAV is expected"); new (pRootViews + rv) RootParameter{SrcView.Group, SrcView.RootIndex, d3d12RootParam}; } diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index a794f4fe..b4f0e486 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -248,14 +248,14 @@ bool LocalRootSignatureD3D12::IsShaderRecord(const D3DShaderResourceAttribs& CB) return false; } -ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice, Uint32 RegisterSpace) +bool LocalRootSignatureD3D12::Create(ID3D12Device* pDevice, Uint32 RegisterSpace) { if (m_ShaderRecordSize == 0) - return nullptr; + return false; - m_RegisterSpace = RegisterSpace; + VERIFY(m_RegisterSpace == ~0u || m_pd3d12RootSignature == nullptr, "This root signature is already created"); - VERIFY(m_pd3d12RootSignature == nullptr, "This root signature is already created"); + m_RegisterSpace = RegisterSpace; D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {}; D3D12_ROOT_PARAMETER d3d12Params = {}; @@ -277,7 +277,7 @@ ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice, Uint hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_pd3d12RootSignature)); CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D12 local root signature"); - return m_pd3d12RootSignature; + return true; } |
