summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-02-04 06:59:50 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-02-04 06:59:50 +0000
commitce265923d110dd8728cfce296e35d6000d861cf0 (patch)
treeb3fc29b0ea169240f555b122a0eb9ac3881fe3a0 /Graphics
parentFixed minor formatting issue (diff)
downloadDiligentCore-ce265923d110dd8728cfce296e35d6000d861cf0.tar.gz
DiligentCore-ce265923d110dd8728cfce296e35d6000d861cf0.zip
Added rasterizer state, depth state and blend state validation and correction when creating a PSO
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.hpp102
-rw-r--r--Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp20
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp8
4 files changed, 121 insertions, 19 deletions
diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
index 0098ee37..ea00cc90 100644
--- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
+++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
@@ -85,6 +85,10 @@ public:
if (!PSODesc.IsComputePipeline)
{
+ CheckAndCorrectBlendStateDesc();
+ CheckRasterizerStateDesc();
+ CheckAndCorrectDepthStencilDesc();
+
const auto& InputLayout = PSODesc.GraphicsPipeline.InputLayout;
for (Uint32 i = 0; i < InputLayout.NumElements; ++i)
StringPoolSize += strlen(InputLayout.LayoutElements[i].HLSLSemantic) + 1;
@@ -385,6 +389,104 @@ protected:
IShader* m_ppShaders[5] = {}; ///< Array of pointers to the shaders used by this PSO
size_t m_ShaderResourceLayoutHash = 0; ///< Hash computed from the shader resource layout
+
+private:
+ void CheckRasterizerStateDesc() const
+ {
+ const auto& RSDesc = this->m_Desc.GraphicsPipeline.RasterizerDesc;
+ if (RSDesc.FillMode == FILL_MODE_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: RasterizerDesc.FillMode must not be FILL_MODE_UNDEFINED");
+ if (RSDesc.CullMode == CULL_MODE_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: RasterizerDesc.CullMode must not be CULL_MODE_UNDEFINED");
+ }
+
+ void CheckAndCorrectDepthStencilDesc()
+ {
+ auto& DSSDesc = this->m_Desc.GraphicsPipeline.DepthStencilDesc;
+ if (DSSDesc.DepthFunc == COMPARISON_FUNC_UNKNOWN)
+ {
+ if (DSSDesc.DepthEnable)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: DepthStencilDesc.DepthFunc must not be COMPARISON_FUNC_UNKNOWN when depth is enabled");
+ else
+ DSSDesc.DepthFunc = DepthStencilStateDesc{}.DepthFunc;
+ }
+
+ auto CheckAndCorrectStencilOpDesc = [&](StencilOpDesc& OpDesc, const char* FaceName) //
+ {
+ if (DSSDesc.StencilEnable)
+ {
+ if (OpDesc.StencilFailOp == STENCIL_OP_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: DepthStencilDesc.", FaceName, ".StencilFailOp must not be STENCIL_OP_UNDEFINED when stencil is enabled");
+ if (OpDesc.StencilDepthFailOp == STENCIL_OP_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: DepthStencilDesc.", FaceName, ".StencilDepthFailOp must not be STENCIL_OP_UNDEFINED when stencil is enabled");
+ if (OpDesc.StencilPassOp == STENCIL_OP_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: DepthStencilDesc.", FaceName, ".StencilPassOp must not be STENCIL_OP_UNDEFINED when stencil is enabled");
+ if (OpDesc.StencilFunc == COMPARISON_FUNC_UNKNOWN)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: DepthStencilDesc.", FaceName, ".StencilFunc must not be COMPARISON_FUNC_UNKNOWN when stencil is enabled");
+ }
+ else
+ {
+ if (OpDesc.StencilFailOp == STENCIL_OP_UNDEFINED)
+ OpDesc.StencilFailOp = StencilOpDesc{}.StencilFailOp;
+ if (OpDesc.StencilDepthFailOp == STENCIL_OP_UNDEFINED)
+ OpDesc.StencilDepthFailOp = StencilOpDesc{}.StencilDepthFailOp;
+ if (OpDesc.StencilPassOp == STENCIL_OP_UNDEFINED)
+ OpDesc.StencilPassOp = StencilOpDesc{}.StencilPassOp;
+ if (OpDesc.StencilFunc == COMPARISON_FUNC_UNKNOWN)
+ OpDesc.StencilFunc = StencilOpDesc{}.StencilFunc;
+ }
+ };
+ CheckAndCorrectStencilOpDesc(DSSDesc.FrontFace, "FrontFace");
+ CheckAndCorrectStencilOpDesc(DSSDesc.BackFace, "BackFace");
+ }
+
+ void CheckAndCorrectBlendStateDesc()
+ {
+ auto& BlendDesc = this->m_Desc.GraphicsPipeline.BlendDesc;
+ for (Uint32 rt = 0; rt < MAX_RENDER_TARGETS; ++rt)
+ {
+ auto& RTDesc = BlendDesc.RenderTargets[rt];
+ // clang-format off
+ const auto BlendEnable = RTDesc.BlendEnable && (rt == 0 || (BlendDesc.IndependentBlendEnable && rt > 0));
+ const auto LogicOpEnable = RTDesc.LogicOperationEnable && (rt == 0 || (BlendDesc.IndependentBlendEnable && rt > 0));
+ // clang-format on
+ if (BlendEnable)
+ {
+ if (RTDesc.SrcBlend == BLEND_FACTOR_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].SrcBlend must not be BLEND_FACTOR_UNDEFINED");
+ if (RTDesc.DestBlend == BLEND_FACTOR_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].DestBlend must not be BLEND_FACTOR_UNDEFINED");
+ if (RTDesc.BlendOp == BLEND_OPERATION_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].BlendOp must not be BLEND_OPERATION_UNDEFINED");
+
+ if (RTDesc.SrcBlendAlpha == BLEND_FACTOR_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].SrcBlendAlpha must not be BLEND_FACTOR_UNDEFINED");
+ if (RTDesc.DestBlendAlpha == BLEND_FACTOR_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].DestBlendAlpha must not be BLEND_FACTOR_UNDEFINED");
+ if (RTDesc.BlendOpAlpha == BLEND_OPERATION_UNDEFINED)
+ LOG_ERROR_AND_THROW("Description of graphics PSO '", this->m_Desc.Name, "' is invalid: BlendDesc.RenderTargets[", rt, "].BlendOpAlpha must not be BLEND_OPERATION_UNDEFINED");
+ }
+ else
+ {
+ if (RTDesc.SrcBlend == BLEND_FACTOR_UNDEFINED)
+ RTDesc.SrcBlend = RenderTargetBlendDesc{}.SrcBlend;
+ if (RTDesc.DestBlend == BLEND_FACTOR_UNDEFINED)
+ RTDesc.DestBlend = RenderTargetBlendDesc{}.DestBlend;
+ if (RTDesc.BlendOp == BLEND_OPERATION_UNDEFINED)
+ RTDesc.BlendOp = RenderTargetBlendDesc{}.BlendOp;
+
+ if (RTDesc.SrcBlendAlpha == BLEND_FACTOR_UNDEFINED)
+ RTDesc.SrcBlendAlpha = RenderTargetBlendDesc{}.SrcBlendAlpha;
+ if (RTDesc.DestBlendAlpha == BLEND_FACTOR_UNDEFINED)
+ RTDesc.DestBlendAlpha = RenderTargetBlendDesc{}.DestBlendAlpha;
+ if (RTDesc.BlendOpAlpha == BLEND_OPERATION_UNDEFINED)
+ RTDesc.BlendOpAlpha = RenderTargetBlendDesc{}.BlendOpAlpha;
+ }
+
+ if (!LogicOpEnable)
+ RTDesc.LogicOp = RenderTargetBlendDesc{}.LogicOp;
+ }
+ }
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
index 02f0dac8..f155c4fd 100644
--- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
@@ -50,9 +50,9 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
m_StaticSamplers (STD_ALLOCATOR_RAW_MEM(StaticSamplerInfo, GetRawAllocator(), "Allocator for vector<StaticSamplerInfo>"))
// clang-format on
{
- if (PipelineDesc.IsComputePipeline)
+ if (m_Desc.IsComputePipeline)
{
- auto* pCS = ValidatedCast<ShaderD3D11Impl>(PipelineDesc.ComputePipeline.pCS);
+ auto* pCS = ValidatedCast<ShaderD3D11Impl>(m_Desc.ComputePipeline.pCS);
m_pCS = pCS;
if (m_pCS == nullptr)
{
@@ -71,7 +71,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
#define INIT_SHADER(ShortName, ExpectedType) \
do \
{ \
- auto* pShader = ValidatedCast<ShaderD3D11Impl>(PipelineDesc.GraphicsPipeline.p##ShortName); \
+ auto* pShader = ValidatedCast<ShaderD3D11Impl>(m_Desc.GraphicsPipeline.p##ShortName); \
m_p##ShortName = pShader; \
if (m_p##ShortName && m_p##ShortName->GetDesc().ShaderType != ExpectedType) \
{ \
@@ -96,17 +96,17 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
auto* pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device();
D3D11_BLEND_DESC D3D11BSDesc = {};
- BlendStateDesc_To_D3D11_BLEND_DESC(PipelineDesc.GraphicsPipeline.BlendDesc, D3D11BSDesc);
+ BlendStateDesc_To_D3D11_BLEND_DESC(m_Desc.GraphicsPipeline.BlendDesc, D3D11BSDesc);
CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateBlendState(&D3D11BSDesc, &m_pd3d11BlendState),
"Failed to create D3D11 blend state object");
D3D11_RASTERIZER_DESC D3D11RSDesc = {};
- RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(PipelineDesc.GraphicsPipeline.RasterizerDesc, D3D11RSDesc);
+ RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(m_Desc.GraphicsPipeline.RasterizerDesc, D3D11RSDesc);
CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateRasterizerState(&D3D11RSDesc, &m_pd3d11RasterizerState),
"Failed to create D3D11 rasterizer state");
D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc = {};
- DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(PipelineDesc.GraphicsPipeline.DepthStencilDesc, D3D11DSSDesc);
+ DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(m_Desc.GraphicsPipeline.DepthStencilDesc, D3D11DSSDesc);
CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateDepthStencilState(&D3D11DSSDesc, &m_pd3d11DepthStencilState),
"Failed to create D3D11 depth stencil state");
@@ -129,7 +129,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
m_pStaticResourceLayouts = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", ShaderResourceLayoutD3D11, m_NumShaders);
m_pStaticResourceCaches = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheD3D11", ShaderResourceCacheD3D11, m_NumShaders);
- const auto& ResourceLayout = PipelineDesc.ResourceLayout;
+ const auto& ResourceLayout = m_Desc.ResourceLayout;
#ifdef DEVELOPMENT
{
@@ -187,7 +187,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
}
m_StaticSamplerOffsets[s + 1] = static_cast<Uint16>(StaticSamplers.size());
- if (PipelineDesc.SRBAllocationGranularity > 1)
+ if (m_Desc.SRBAllocationGranularity > 1)
{
const SHADER_RESOURCE_VARIABLE_TYPE SRBVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(ShaderResources, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes));
@@ -198,9 +198,9 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun
m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s);
}
- if (PipelineDesc.SRBAllocationGranularity > 1)
+ if (m_Desc.SRBAllocationGranularity > 1)
{
- m_SRBMemAllocator.Initialize(PipelineDesc.SRBAllocationGranularity, m_NumShaders, ShaderResLayoutDataSizes.data(), m_NumShaders, ShaderResCacheDataSizes.data());
+ m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, m_NumShaders, ShaderResLayoutDataSizes.data(), m_NumShaders, ShaderResCacheDataSizes.data());
}
m_StaticSamplers.reserve(StaticSamplers.size());
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index 6cfe1b1e..6213ce13 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -155,9 +155,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCoun
}
m_RootSig.Finalize(pd3d12Device);
- if (PipelineDesc.IsComputePipeline)
+ if (m_Desc.IsComputePipeline)
{
- auto& ComputePipeline = PipelineDesc.ComputePipeline;
+ auto& ComputePipeline = m_Desc.ComputePipeline;
if (ComputePipeline.pCS == nullptr)
LOG_ERROR_AND_THROW("Compute shader is not set in the pipeline desc");
@@ -189,7 +189,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCoun
}
else
{
- const auto& GraphicsPipeline = PipelineDesc.GraphicsPipeline;
+ const auto& GraphicsPipeline = m_Desc.GraphicsPipeline;
D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {};
@@ -281,7 +281,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCoun
m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
}
- if (PipelineDesc.SRBAllocationGranularity > 1)
+ if (m_Desc.SRBAllocationGranularity > 1)
{
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVarMgrDataSizes = {};
for (Uint32 s = 0; s < m_NumShaders; ++s)
@@ -297,7 +297,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCoun
}
auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize();
- m_SRBMemAllocator.Initialize(PipelineDesc.SRBAllocationGranularity, m_NumShaders, ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize);
+ m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, m_NumShaders, ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize);
}
m_ShaderResourceLayoutHash = m_RootSig.GetHash();
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 282c69e4..1d2339a4 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -179,15 +179,15 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters,
auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk(LogicalDevice);
auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk(ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources);
- pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, PipelineDesc.ResourceLayout, m_StaticResCaches[s]);
+ pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, m_Desc.ResourceLayout, m_StaticResCaches[s]);
new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache);
}
ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(),
- PipelineDesc.ResourceLayout, ShaderSPIRVs.data(), m_PipelineLayout);
+ m_Desc.ResourceLayout, ShaderSPIRVs.data(), m_PipelineLayout);
m_PipelineLayout.Finalize(LogicalDevice);
- if (PipelineDesc.SRBAllocationGranularity > 1)
+ if (m_Desc.SRBAllocationGranularity > 1)
{
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {};
for (Uint32 s = 0; s < m_NumShaders; ++s)
@@ -202,7 +202,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters,
auto DescriptorSetSizes = m_PipelineLayout.GetDescriptorSetSizes(NumSets);
auto CacheMemorySize = ShaderResourceCacheVk::GetRequiredMemorySize(NumSets, DescriptorSetSizes.data());
- m_SRBMemAllocator.Initialize(PipelineDesc.SRBAllocationGranularity, m_NumShaders, ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
+ m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, m_NumShaders, ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
}
// Create shader modules and initialize shader stages