summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-03-07 18:11:56 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:16 +0000
commit176e4de5f14b5332d58f02dc6088ea751189ebba (patch)
treeb2ff0c4bbb60a71c170fa0877bcb93ede42694a7 /Graphics
parentUnified resource signature handling by pipeline state in D3D12, Vk and GL (diff)
downloadDiligentCore-176e4de5f14b5332d58f02dc6088ea751189ebba.tar.gz
DiligentCore-176e4de5f14b5332d58f02dc6088ea751189ebba.zip
Reworked non-separable programs in GL; added more PSO and PRS validation
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.hpp23
-rw-r--r--Graphics/GraphicsEngine/src/PipelineResourceSignatureBase.cpp33
-rw-r--r--Graphics/GraphicsEngine/src/PipelineStateBase.cpp111
-rw-r--r--Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp8
-rw-r--r--Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp35
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp53
9 files changed, 164 insertions, 114 deletions
diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
index dcdd82d9..e8743e0f 100644
--- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
+++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
@@ -48,9 +48,19 @@
namespace Diligent
{
-void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false);
-void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false);
-void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, Uint32 MaxRecursion, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false);
+// Validates graphics pipeline create attributes and throws an exception in case of an error.
+void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false);
+
+// Validates compute pipeline create attributes and throws an exception in case of an error.
+void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false);
+
+// Validates ray-tracing pipeline create attributes and throws an exception in case of an error.
+void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice,
+ Uint32 MaxRecursion,
+ const RayTracingPipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false);
/// Validates that pipeline resource description 'ResDesc' is compatible with the actual resource
/// attributes and throws an exception in case of an error.
@@ -138,7 +148,7 @@ public:
{
try
{
- ValidateGraphicsPipelineCreateInfo(GraphicsPipelineCI);
+ ValidateGraphicsPipelineCreateInfo(GraphicsPipelineCI, pDevice->GetDeviceCaps().Features);
}
catch (...)
{
@@ -162,7 +172,7 @@ public:
{
try
{
- ValidateComputePipelineCreateInfo(ComputePipelineCI);
+ ValidateComputePipelineCreateInfo(ComputePipelineCI, pDevice->GetDeviceCaps().Features);
}
catch (...)
{
@@ -186,7 +196,8 @@ public:
{
try
{
- ValidateRayTracingPipelineCreateInfo(pDevice, pDevice->GetProperties().MaxRayTracingRecursionDepth, RayTracingPipelineCI);
+ ValidateRayTracingPipelineCreateInfo(pDevice, pDevice->GetProperties().MaxRayTracingRecursionDepth,
+ RayTracingPipelineCI, pDevice->GetDeviceCaps().Features);
}
catch (...)
{
diff --git a/Graphics/GraphicsEngine/src/PipelineResourceSignatureBase.cpp b/Graphics/GraphicsEngine/src/PipelineResourceSignatureBase.cpp
index ae41e2ba..46eb61e6 100644
--- a/Graphics/GraphicsEngine/src/PipelineResourceSignatureBase.cpp
+++ b/Graphics/GraphicsEngine/src/PipelineResourceSignatureBase.cpp
@@ -64,16 +64,16 @@ void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc&
const auto& Res = Desc.Resources[i];
if (Res.Name == nullptr)
- LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be null");
+ LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be null.");
if (Res.Name[0] == '\0')
- LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be empty");
+ LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].Name must not be empty.");
if (Res.ShaderStages == SHADER_TYPE_UNKNOWN)
- LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN");
+ LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
if (Res.ArraySize == 0)
- LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ArraySize must not be 0");
+ LOG_PRS_ERROR_AND_THROW("Desc.Resources[", i, "].ArraySize must not be 0.");
auto& UsedStages = ResourceShaderStages[Res.Name];
if ((UsedStages & Res.ShaderStages) != 0)
@@ -82,6 +82,15 @@ void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc&
"' specify overlapping shader stages. There may be multiple resources with the same name in different shader stages, "
"but the stages must not overlap.");
}
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED && UsedStages != SHADER_TYPE_UNKNOWN)
+ {
+ LOG_PRS_ERROR_AND_THROW("This device does not support separable programs, but there are separate resources with the name '",
+ Res.Name, "' in shader stages ",
+ GetShaderStagesString(Res.ShaderStages), " and ",
+ GetShaderStagesString(UsedStages),
+ ". When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct resource names for each stage or define a single resource for all stages.");
+ }
UsedStages |= Res.ShaderStages;
if ((Res.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0 && !Features.ShaderResourceRuntimeArray)
@@ -174,10 +183,13 @@ void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc&
{
const auto& SamDesc = Desc.ImmutableSamplers[i];
if (SamDesc.SamplerOrTextureName == nullptr)
- LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null");
+ LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null.");
if (SamDesc.SamplerOrTextureName[0] == '\0')
- LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty");
+ LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty.");
+
+ if (SamDesc.ShaderStages == SHADER_TYPE_UNKNOWN)
+ LOG_PRS_ERROR_AND_THROW("Desc.ImmutableSamplers[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
auto& UsedStages = ImtblSamShaderStages[SamDesc.SamplerOrTextureName];
if ((UsedStages & SamDesc.ShaderStages) != 0)
@@ -186,6 +198,15 @@ void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc&
"' specify overlapping shader stages. There may be multiple immutable samplers with the same name in different shader stages, "
"but the stages must not overlap.");
}
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED && UsedStages != SHADER_TYPE_UNKNOWN)
+ {
+ LOG_PRS_ERROR_AND_THROW("This device does not support separable programs, but there are separate immutable samplers with the name '",
+ SamDesc.SamplerOrTextureName, "' in shader stages ",
+ GetShaderStagesString(SamDesc.ShaderStages), " and ",
+ GetShaderStagesString(UsedStages),
+ ". When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct immutable sampler names for each stage or define a single sampler for all stages.");
+ }
UsedStages |= SamDesc.ShaderStages;
}
}
diff --git a/Graphics/GraphicsEngine/src/PipelineStateBase.cpp b/Graphics/GraphicsEngine/src/PipelineStateBase.cpp
index 4c095669..c7cb1427 100644
--- a/Graphics/GraphicsEngine/src/PipelineStateBase.cpp
+++ b/Graphics/GraphicsEngine/src/PipelineStateBase.cpp
@@ -30,7 +30,6 @@
#include <unordered_set>
#include <unordered_map>
#include <array>
-#include <vector>
#include "HashUtils.hpp"
#include "StringTools.hpp"
@@ -160,7 +159,8 @@ void CorrectBlendStateDesc(GraphicsPipelineDesc& GraphicsPipeline) noexcept
}
-void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInfo) noexcept(false)
+void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false)
{
const auto& PSODesc = CreateInfo.PSODesc;
@@ -191,8 +191,8 @@ void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInf
}
- std::unordered_map<HashMapStringKey, std::vector<std::pair<SHADER_TYPE, const IPipelineResourceSignature*>>, HashMapStringKey::Hasher> AllResources;
- std::unordered_map<HashMapStringKey, std::vector<std::pair<SHADER_TYPE, const IPipelineResourceSignature*>>, HashMapStringKey::Hasher> AllImtblSamplers;
+ std::unordered_multimap<HashMapStringKey, std::pair<SHADER_TYPE, const IPipelineResourceSignature*>, HashMapStringKey::Hasher> AllResources;
+ std::unordered_multimap<HashMapStringKey, std::pair<SHADER_TYPE, const IPipelineResourceSignature*>, HashMapStringKey::Hasher> AllImtblSamplers;
std::array<const IPipelineResourceSignature*, MAX_RESOURCE_SIGNATURES> ppSignatures = {};
for (Uint32 i = 0; i < CreateInfo.ResourceSignaturesCount; ++i)
@@ -216,10 +216,13 @@ void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInf
for (Uint32 res = 0; res < SignDesc.NumResources; ++res)
{
const auto& ResDesc = SignDesc.Resources[res];
+ VERIFY(ResDesc.Name != nullptr && ResDesc.Name[0] != '\0', "Resource name can't be null or empty. This should've been caught by ValidatePipelineResourceSignatureDesc()");
+ VERIFY(ResDesc.ShaderStages != SHADER_TYPE_UNKNOWN, "Shader stages can't be UNKNOWN. This should've been caught by ValidatePipelineResourceSignatureDesc()");
- auto& StageSignatures = AllResources[ResDesc.Name];
- for (auto& StageSig : StageSignatures)
+ auto range = AllResources.equal_range(ResDesc.Name);
+ for (auto it = range.first; it != range.second; ++it)
{
+ const auto& StageSig = it->second;
if ((StageSig.first & ResDesc.ShaderStages) != 0)
{
VERIFY(StageSig.second != pSignature, "Overlapping resources in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
@@ -228,17 +231,31 @@ void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInf
"' and '", StageSig.second->GetDesc().Name,
"') in the same shader stage. Every shader resource in the PSO must be unambiguously defined by only one resource signature.");
}
+
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
+ {
+ VERIFY_EXPR(StageSig.first != SHADER_TYPE_UNKNOWN);
+ VERIFY(StageSig.second != pSignature, "Resources with the same name in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
+
+ LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but shader resource '", ResDesc.Name, "' is found in more than one resource signature ('",
+ SignDesc.Name, "' and '", StageSig.second->GetDesc().Name,
+ "') in different stages. When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct resource names for each stage or define a single resource for all stages.");
+ }
}
- StageSignatures.emplace_back(ResDesc.ShaderStages, pSignature);
+ AllResources.emplace(ResDesc.Name, std::make_pair(ResDesc.ShaderStages, pSignature));
}
for (Uint32 res = 0; res < SignDesc.NumImmutableSamplers; ++res)
{
const auto& SamDesc = SignDesc.ImmutableSamplers[res];
+ VERIFY(SamDesc.SamplerOrTextureName != nullptr && SamDesc.SamplerOrTextureName[0] != '\0', "Sampler name can't be null or empty. This should've been caught by ValidatePipelineResourceSignatureDesc()");
+ VERIFY(SamDesc.ShaderStages != SHADER_TYPE_UNKNOWN, "Shader stage can't be UNKNOWN. This should've been caught by ValidatePipelineResourceSignatureDesc()");
- auto& StageSignatures = AllImtblSamplers[SamDesc.SamplerOrTextureName];
- for (auto& StageSig : StageSignatures)
+ auto range = AllImtblSamplers.equal_range(SamDesc.SamplerOrTextureName);
+ for (auto it = range.first; it != range.second; ++it)
{
+ const auto& StageSig = it->second;
if ((StageSig.first & SamDesc.ShaderStages) != 0)
{
VERIFY(StageSig.second != pSignature, "Overlapping immutable samplers in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
@@ -247,13 +264,24 @@ void ValidatePipelineResourceSignatures(const PipelineStateCreateInfo& CreateInf
"' and '", StageSig.second->GetDesc().Name,
"') in the same stage. Every immutable sampler in the PSO must be unambiguously defined by only one resource signature.");
}
+
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
+ {
+ VERIFY_EXPR(StageSig.first != SHADER_TYPE_UNKNOWN);
+ VERIFY(StageSig.second != pSignature, "Immutable samplers with the same name in one signature should've been caught by ValidatePipelineResourceSignatureDesc()");
+
+ LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but immutable sampler '", SamDesc.SamplerOrTextureName, "' is found in more than one resource signature ('",
+ SignDesc.Name, "' and '", StageSig.second->GetDesc().Name,
+ "') in different stages. When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct resource names for each stage or define a single immutable sampler for all stages.");
+ }
}
- StageSignatures.emplace_back(SamDesc.ShaderStages, pSignature);
+ AllImtblSamplers.emplace(SamDesc.SamplerOrTextureName, std::make_pair(SamDesc.ShaderStages, pSignature));
}
}
}
-void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexcept(false)
+void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc, const DeviceFeatures& Features) noexcept(false)
{
const auto& Layout = PSODesc.ResourceLayout;
{
@@ -262,6 +290,15 @@ void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexce
{
const auto& Var = Layout.Variables[i];
+ if (Var.Name == nullptr)
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].Name must not be null.");
+
+ if (Var.Name[0] == '\0')
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].Name must not be empty.");
+
+ if (Var.ShaderStages == SHADER_TYPE_UNKNOWN)
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.Variables[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
+
auto range = UniqueVariables.equal_range(Var.Name);
for (auto it = range.first; it != range.second; ++it)
{
@@ -271,6 +308,16 @@ void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexce
" and ", GetShaderStagesString(it->second),
"). Multiple variables with the same name are allowed, but shader stages they use must not overlap.");
}
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
+ {
+ VERIFY_EXPR(it->second != SHADER_TYPE_UNKNOWN);
+ LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but there are separate resources with the name '",
+ Var.Name, "' in shader stages ",
+ GetShaderStagesString(Var.ShaderStages), " and ",
+ GetShaderStagesString(it->second),
+ ". When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct resource names for each stage or define a single resource for all stages.");
+ }
}
UniqueVariables.emplace(Var.Name, Var.ShaderStages);
}
@@ -281,6 +328,15 @@ void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexce
{
const auto& Sam = Layout.ImmutableSamplers[i];
+ if (Sam.SamplerOrTextureName == nullptr)
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].SamplerOrTextureName must not be null.");
+
+ if (Sam.SamplerOrTextureName[0] == '\0')
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].SamplerOrTextureName must not be empty.");
+
+ if (Sam.ShaderStages == SHADER_TYPE_UNKNOWN)
+ LOG_PSO_ERROR_AND_THROW("ResourceLayout.ImmutableSamplers[", i, "].ShaderStages must not be SHADER_TYPE_UNKNOWN.");
+
auto range = UniqueSamplers.equal_range(Sam.SamplerOrTextureName);
for (auto it = range.first; it != range.second; ++it)
{
@@ -290,6 +346,16 @@ void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexce
" and ", GetShaderStagesString(it->second),
"). Multiple immutable samplers with the same name are allowed, but shader stages they use must not overlap.");
}
+ if (Features.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
+ {
+ VERIFY_EXPR(it->second != SHADER_TYPE_UNKNOWN);
+ LOG_PSO_ERROR_AND_THROW("This device does not support separable programs, but there are separate immutable samplers with the name '",
+ Sam.SamplerOrTextureName, "' in shader stages ",
+ GetShaderStagesString(Sam.ShaderStages), " and ",
+ GetShaderStagesString(it->second),
+ ". When separable programs are not supported, every resource is always shared between all stages. "
+ "Use distinct immutable sampler names for each stage or define a single sampler for all stages.");
+ }
}
UniqueSamplers.emplace(Sam.SamplerOrTextureName, Sam.ShaderStages);
}
@@ -304,20 +370,21 @@ void ValidatePipelineResourceLayoutDesc(const PipelineStateDesc& PSODesc) noexce
LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(Shader->GetDesc().ShaderType), " is not a valid type for ", ShaderName, " shader"); \
}
-void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false)
+void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false)
{
const auto& PSODesc = CreateInfo.PSODesc;
if (PSODesc.PipelineType != PIPELINE_TYPE_GRAPHICS && PSODesc.PipelineType != PIPELINE_TYPE_MESH)
LOG_PSO_ERROR_AND_THROW("Pipeline type must be GRAPHICS or MESH.");
- ValidatePipelineResourceSignatures(CreateInfo);
+ ValidatePipelineResourceSignatures(CreateInfo, Features);
const auto& GraphicsPipeline = CreateInfo.GraphicsPipeline;
ValidateBlendStateDesc(PSODesc, GraphicsPipeline);
ValidateRasterizerStateDesc(PSODesc, GraphicsPipeline);
ValidateDepthStencilDesc(PSODesc, GraphicsPipeline);
- ValidatePipelineResourceLayoutDesc(PSODesc);
+ ValidatePipelineResourceLayoutDesc(PSODesc, Features);
if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS)
@@ -384,14 +451,15 @@ void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& C
}
}
-void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false)
+void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false)
{
const auto& PSODesc = CreateInfo.PSODesc;
if (PSODesc.PipelineType != PIPELINE_TYPE_COMPUTE)
LOG_PSO_ERROR_AND_THROW("Pipeline type must be COMPUTE.");
- ValidatePipelineResourceSignatures(CreateInfo);
- ValidatePipelineResourceLayoutDesc(PSODesc);
+ ValidatePipelineResourceSignatures(CreateInfo, Features);
+ ValidatePipelineResourceLayoutDesc(PSODesc, Features);
if (CreateInfo.pCS == nullptr)
LOG_PSO_ERROR_AND_THROW("Compute shader must not be null.");
@@ -399,14 +467,17 @@ void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& Cre
VALIDATE_SHADER_TYPE(CreateInfo.pCS, SHADER_TYPE_COMPUTE, "compute")
}
-void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice, Uint32 MaxRecursion, const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
+void ValidateRayTracingPipelineCreateInfo(IRenderDevice* pDevice,
+ Uint32 MaxRecursion,
+ const RayTracingPipelineStateCreateInfo& CreateInfo,
+ const DeviceFeatures& Features) noexcept(false)
{
const auto& PSODesc = CreateInfo.PSODesc;
if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING)
LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING.");
- ValidatePipelineResourceSignatures(CreateInfo);
- ValidatePipelineResourceLayoutDesc(PSODesc);
+ ValidatePipelineResourceSignatures(CreateInfo, Features);
+ ValidatePipelineResourceLayoutDesc(PSODesc, Features);
if (pDevice->GetDeviceCaps().DevType == RENDER_DEVICE_TYPE_D3D12)
{
diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp
index 03f52354..aac0bf87 100644
--- a/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp
@@ -58,7 +58,8 @@ D3D12DynamicPage::D3D12DynamicPage(ID3D12Device* pd3d12Device, Uint64 Size)
ResourceDesc.Width = Size;
auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, &ResourceDesc,
- DefaultUsage, nullptr, __uuidof(m_pd3d12Buffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Buffer)));
+ DefaultUsage, nullptr, __uuidof(m_pd3d12Buffer),
+ reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Buffer)));
if (FAILED(hr))
{
LOG_D3D_ERROR(hr, "Failed to create dynamic page");
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
index 7d913990..088a052e 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
@@ -63,7 +63,7 @@ inline bool ResourcesCompatible(const PipelineResourceSignatureD3D12Impl::Resour
// clang-format on
}
-void ValidateD3D12PipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc) noexcept(false)
+void ValidatePipelineResourceSignatureDescD3D12(const PipelineResourceSignatureDesc& Desc) noexcept(false)
{
{
std::unordered_multimap<HashMapStringKey, SHADER_TYPE, HashMapStringKey::Hasher> ResNameToShaderStages;
@@ -113,7 +113,7 @@ void ValidateD3D12PipelineResourceSignatureDesc(const PipelineResourceSignatureD
else
{
LOG_ERROR_AND_THROW("Pipeline resource signature '", (Desc.Name != nullptr ? Desc.Name : ""),
- "' defines immutable sampler with the name '", Name, "' in shader stages ",
+ "' defines separate immutable samplers with the name '", Name, "' in shader stages ",
GetShaderStagesString(multi_stage_it->second), " and ",
GetShaderStagesString(it->second),
". In Direct3D12 backend, only one immutable sampler in the group of samplers with the same name can be shared between more than "
@@ -135,10 +135,10 @@ PipelineResourceSignatureD3D12Impl::PipelineResourceSignatureD3D12Impl(IReferenc
TPipelineResourceSignatureBase{pRefCounters, pDevice, Desc, bIsDeviceInternal},
m_SRBMemAllocator{GetRawAllocator()}
{
- ValidateD3D12PipelineResourceSignatureDesc(Desc);
-
try
{
+ ValidatePipelineResourceSignatureDescD3D12(Desc);
+
auto& RawAllocator{GetRawAllocator()};
auto MemPool = ReserveSpace(RawAllocator, Desc,
[&Desc](FixedLinearAllocator& MemPool) //
diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
index ce8b702f..9958d158 100644
--- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp
@@ -229,7 +229,8 @@ TextureD3D12Impl::TextureD3D12Impl(IReferenceCounters* pRefCounters,
CComPtr<ID3D12Resource> UploadBuffer;
hr = pd3d12Device->CreateCommittedResource(&UploadHeapProps, D3D12_HEAP_FLAG_NONE,
&BufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
- nullptr, __uuidof(UploadBuffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer)));
+ nullptr, __uuidof(UploadBuffer),
+ reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&UploadBuffer)));
if (FAILED(hr))
LOG_ERROR_AND_THROW("Failed to create committed resource in an upload heap");
@@ -333,7 +334,8 @@ TextureD3D12Impl::TextureD3D12Impl(IReferenceCounters* pRefCounters,
// on some ARM systems, to marshal data between the CPU and GPU through memory addresses with write-back behavior.
// https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12resource-map
auto hr = pd3d12Device->CreateCommittedResource(&StaginHeapProps, D3D12_HEAP_FLAG_NONE, &BufferDesc, D3D12State,
- nullptr, __uuidof(m_pd3d12Resource), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
+ nullptr, __uuidof(m_pd3d12Resource),
+ reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12Resource)));
if (FAILED(hr))
LOG_ERROR_AND_THROW("Failed to create staging buffer");
diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
index f4a4cefb..9c37301f 100644
--- a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp
@@ -190,12 +190,6 @@ public:
#endif
private:
- PipelineResourceSignatureGLImpl(IReferenceCounters* pRefCounters,
- RenderDeviceGLImpl* pDevice,
- const PipelineResourceSignatureDesc& Desc,
- bool bIsDeviceInternal,
- int Internal);
-
// Copies static resources from the static resource cache to the destination cache
void CopyStaticResources(ShaderResourceCacheGL& ResourceCache) const;
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp
index 60cae558..1373c446 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp
@@ -33,6 +33,7 @@
namespace Diligent
{
+
namespace
{
@@ -46,32 +47,6 @@ inline bool ResourcesCompatible(const PipelineResourceSignatureGLImpl::ResourceA
// clang-format on
}
-struct PatchedPipelineResourceSignatureDesc : PipelineResourceSignatureDesc
-{
- std::vector<ImmutableSamplerDesc> m_ImmutableSamplers;
-
- PatchedPipelineResourceSignatureDesc(RenderDeviceGLImpl* pDeviceGL, const PipelineResourceSignatureDesc& Desc) :
- PipelineResourceSignatureDesc{Desc}
- {
- if (NumImmutableSamplers > 0 && ImmutableSamplers != nullptr && !pDeviceGL->GetDeviceCaps().Features.SeparablePrograms)
- {
- m_ImmutableSamplers.resize(NumImmutableSamplers);
-
- SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
- for (Uint32 r = 0; r < NumResources; ++r)
- ActiveStages |= Resources[r].ShaderStages;
-
- for (Uint32 s = 0; s < NumImmutableSamplers; ++s)
- {
- m_ImmutableSamplers[s] = ImmutableSamplers[s];
- m_ImmutableSamplers[s].ShaderStages |= ActiveStages;
- }
-
- ImmutableSamplers = m_ImmutableSamplers.data();
- }
- }
-};
-
} // namespace
@@ -117,14 +92,6 @@ PipelineResourceSignatureGLImpl::PipelineResourceSignatureGLImpl(IReferenceCount
RenderDeviceGLImpl* pDeviceGL,
const PipelineResourceSignatureDesc& Desc,
bool bIsDeviceInternal) :
- PipelineResourceSignatureGLImpl{pRefCounters, pDeviceGL, PatchedPipelineResourceSignatureDesc{pDeviceGL, Desc}, bIsDeviceInternal, 0}
-{}
-
-PipelineResourceSignatureGLImpl::PipelineResourceSignatureGLImpl(IReferenceCounters* pRefCounters,
- RenderDeviceGLImpl* pDeviceGL,
- const PipelineResourceSignatureDesc& Desc,
- bool bIsDeviceInternal,
- int) :
TPipelineResourceSignatureBase{pRefCounters, pDeviceGL, Desc, bIsDeviceInternal},
m_SRBMemAllocator{GetRawAllocator()}
{
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index 334b20d7..cc1d115d 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -48,9 +48,8 @@ RefCntAutoPtr<PipelineResourceSignatureGLImpl> PipelineStateGLImpl::CreateDefaul
{
std::vector<PipelineResourceDesc> Resources;
- const auto& LayoutDesc = CreateInfo.PSODesc.ResourceLayout;
- const auto DefaultVarType = LayoutDesc.DefaultVariableType;
- ShaderResourcesGL ProgramResources;
+ const auto& LayoutDesc = CreateInfo.PSODesc.ResourceLayout;
+ const auto DefaultVarType = LayoutDesc.DefaultVariableType;
struct UniqueResource
{
@@ -83,42 +82,25 @@ RefCntAutoPtr<PipelineResourceSignatureGLImpl> PipelineStateGLImpl::CreateDefaul
ResDesc.VarType = DefaultVarType;
ResDesc.Flags = Flags;
- if (m_IsProgramPipelineSupported)
+ const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, ResDesc.ShaderStages, nullptr);
+ if (VarIndex != InvalidPipelineResourceLayoutVariableIndex)
{
- const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, ResDesc.ShaderStages, nullptr);
- if (VarIndex != InvalidPipelineResourceLayoutVariableIndex)
- {
- const auto& Var = LayoutDesc.Variables[VarIndex];
- ResDesc.ShaderStages = Var.ShaderStages;
- ResDesc.VarType = Var.Type;
- }
+ const auto& Var = LayoutDesc.Variables[VarIndex];
+ ResDesc.ShaderStages = Var.ShaderStages;
+ ResDesc.VarType = Var.Type;
+ }
- auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ResDesc.ShaderStages});
- if (IterAndAssigned.second)
- {
- Resources.push_back(ResDesc);
- }
- else
- {
- DEV_CHECK_ERR(IterAndAssigned.first->Attribs.ResourceType == Attribs.ResourceType,
- "Shader variable '", Attribs.Name,
- "' exists in multiple shaders from the same shader stage, but its type is not consistent between "
- "shaders. All variables with the same name from the same shader stage must have the same type.");
- }
+ auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ResDesc.ShaderStages});
+ if (IterAndAssigned.second)
+ {
+ Resources.push_back(ResDesc);
}
else
{
- for (Uint32 i = 0; i < LayoutDesc.NumVariables; ++i)
- {
- const auto& Var = LayoutDesc.Variables[i];
- if ((Var.ShaderStages & Attribs.ShaderStages) != 0 &&
- std::strcmp(Attribs.Name, Var.Name) == 0)
- {
- ResDesc.VarType = Var.Type;
- break;
- }
- }
- Resources.push_back(ResDesc);
+ DEV_CHECK_ERR(IterAndAssigned.first->Attribs.ResourceType == Attribs.ResourceType,
+ "Shader variable '", Attribs.Name,
+ "' exists in multiple shaders from the same shader stage, but its type is not consistent between "
+ "shaders. All variables with the same name from the same shader stage must have the same type.");
}
};
const auto HandleUB = [&](const ShaderResourcesGL::UniformBufferInfo& Attribs) {
@@ -134,6 +116,7 @@ RefCntAutoPtr<PipelineResourceSignatureGLImpl> PipelineStateGLImpl::CreateDefaul
HandleResource(Attribs, PIPELINE_RESOURCE_FLAG_UNKNOWN);
};
+ ShaderResourcesGL ProgramResources;
if (m_IsProgramPipelineSupported)
{
for (size_t i = 0; i < ShaderStages.size(); ++i)
@@ -325,7 +308,7 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters*
ShaderCI.Source = "void main(){}";
ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
ShaderCI.Desc.Name = "Dummy fragment shader";
- pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS)));
+ pDeviceGL->CreateShader(ShaderCI, pTempPS.DblPtr<IShader>());
Shaders.emplace_back(pTempPS);
}