Skip to content

Commit 41e6218

Browse files
Moved more of common logic to DeviceContextBase::SetPipelineState
1 parent 9014dee commit 41e6218

File tree

6 files changed

+82
-81
lines changed

6 files changed

+82
-81
lines changed

Graphics/GraphicsEngine/include/DeviceContextBase.hpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -465,7 +465,7 @@ class DeviceContextBase : public ObjectBase<typename EngineImplTraits::DeviceCon
465465

466466
inline bool SetStencilRef(Uint32 StencilRef, int Dummy);
467467

468-
inline void SetPipelineState(RefCntAutoPtr<PipelineStateImplType> pPipelineState, int /*Dummy*/);
468+
inline bool SetPipelineState(IPipelineState* pPipelineState, const INTERFACE_ID& IID_PSOImpl);
469469

470470
/// Clears all cached resources
471471
inline void ClearStateCache();
@@ -766,17 +766,36 @@ inline void DeviceContextBase<ImplementationTraits>::SetVertexBuffers(
766766
}
767767

768768
template <typename ImplementationTraits>
769-
inline void DeviceContextBase<ImplementationTraits>::SetPipelineState(
770-
RefCntAutoPtr<PipelineStateImplType> pPipelineState,
771-
int /*Dummy*/)
769+
inline bool DeviceContextBase<ImplementationTraits>::SetPipelineState(
770+
IPipelineState* pPipelineState,
771+
const INTERFACE_ID& IID_PSOImpl)
772772
{
773+
if (pPipelineState == nullptr)
774+
{
775+
DEV_ERROR("Pipeline state must not be null");
776+
return false;
777+
}
778+
773779
DVP_CHECK_QUEUE_TYPE_COMPATIBILITY(COMMAND_QUEUE_TYPE_COMPUTE, "SetPipelineState");
780+
774781
DEV_CHECK_ERR((pPipelineState->GetDesc().ImmediateContextMask & (Uint64{1} << GetExecutionCtxId())) != 0,
775782
"PSO '", pPipelineState->GetDesc().Name, "' can't be used in device context '", m_Desc.Name, "'.");
776-
DEV_CHECK_ERR(pPipelineState->GetStatus() == PIPELINE_STATE_STATUS_READY, "PSO '", pPipelineState->GetDesc().Name, "' is not ready. Use GetStatus() to check the pipeline status.");
777783

778-
m_pPipelineState = std::move(pPipelineState);
784+
// Check that the PSO is ready before querying the implementation.
785+
DEV_CHECK_ERR(pPipelineState->GetStatus() == PIPELINE_STATE_STATUS_READY, "PSO '", pPipelineState->GetDesc().Name,
786+
"' is not ready. Use GetStatus() to check the pipeline status.");
787+
788+
// Note that pPipelineStateImpl may not be the same as pPipelineState (for example, if pPipelineState
789+
// is a reloadable pipeline).
790+
RefCntAutoPtr<PipelineStateImplType> pPipelineStateImpl{pPipelineState, IID_PSOImpl};
791+
VERIFY(pPipelineStateImpl != nullptr, "Unknown pipeline state object implementation");
792+
if (PipelineStateImplType::IsSameObject(m_pPipelineState, pPipelineStateImpl))
793+
return false;
794+
795+
m_pPipelineState = std::move(pPipelineStateImpl);
779796
++m_Stats.CommandCounters.SetPipelineState;
797+
798+
return true;
780799
}
781800

782801
template <typename ImplementationTraits>
@@ -2200,7 +2219,7 @@ inline Uint32 GetPrimitiveCount(PRIMITIVE_TOPOLOGY Topology, Uint32 Elements)
22002219
UNEXPECTED("Undefined primitive topology");
22012220
return 0;
22022221

2203-
// clang-format off
2222+
// clang-format off
22042223
case PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return Elements / 3;
22052224
case PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return (std::max)(Elements, 2u) - 2;
22062225
case PRIMITIVE_TOPOLOGY_POINT_LIST: return Elements;

Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -80,16 +80,13 @@ void DeviceContextD3D11Impl::Begin(Uint32 ImmediateContextId)
8080

8181
void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
8282
{
83-
RefCntAutoPtr<PipelineStateD3D11Impl> pPipelineStateD3D11{pPipelineState, PipelineStateD3D11Impl::IID_InternalImpl};
84-
VERIFY(pPipelineState == nullptr || pPipelineStateD3D11 != nullptr, "Unknown pipeline state object implementation");
85-
if (PipelineStateD3D11Impl::IsSameObject(m_pPipelineState, pPipelineStateD3D11))
83+
if (!TDeviceContextBase::SetPipelineState(pPipelineState, PipelineStateD3D11Impl::IID_InternalImpl))
8684
return;
8785

88-
TDeviceContextBase::SetPipelineState(std::move(pPipelineStateD3D11), 0 /*Dummy*/);
89-
const auto& Desc = m_pPipelineState->GetDesc();
86+
const PipelineStateDesc& Desc = m_pPipelineState->GetDesc();
9087
if (Desc.PipelineType == PIPELINE_TYPE_COMPUTE)
9188
{
92-
auto* pd3d11CS = m_pPipelineState->GetD3D11ComputeShader();
89+
ID3D11ComputeShader* pd3d11CS = m_pPipelineState->GetD3D11ComputeShader();
9390
if (pd3d11CS == nullptr)
9491
{
9592
LOG_ERROR("Compute shader is not set in the pipeline");
@@ -118,13 +115,13 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
118115
COMMIT_SHADER(DS, DomainShader);
119116
#undef COMMIT_SHADER
120117

121-
const auto& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
118+
const GraphicsPipelineDesc& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
122119

123120
m_pd3d11DeviceContext->OMSetBlendState(m_pPipelineState->GetD3D11BlendState(), m_BlendFactors, GraphicsPipeline.SampleMask);
124121
m_pd3d11DeviceContext->RSSetState(m_pPipelineState->GetD3D11RasterizerState());
125122
m_pd3d11DeviceContext->OMSetDepthStencilState(m_pPipelineState->GetD3D11DepthStencilState(), m_StencilRef);
126123

127-
auto* pd3d11InputLayout = m_pPipelineState->GetD3D11InputLayout();
124+
ID3D11InputLayout* pd3d11InputLayout = m_pPipelineState->GetD3D11InputLayout();
128125
// It is safe to perform raw pointer comparison as the device context
129126
// keeps bound input layout alive
130127
if (m_CommittedD3D11InputLayout != pd3d11InputLayout)
@@ -133,7 +130,7 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
133130
m_CommittedD3D11InputLayout = pd3d11InputLayout;
134131
}
135132

136-
auto PrimTopology = GraphicsPipeline.PrimitiveTopology;
133+
PRIMITIVE_TOPOLOGY PrimTopology = GraphicsPipeline.PrimitiveTopology;
137134
if (m_CommittedPrimitiveTopology != PrimTopology)
138135
{
139136
m_CommittedPrimitiveTopology = PrimTopology;
@@ -149,7 +146,7 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState)
149146
Uint32 DvpCompatibleSRBCount = 0;
150147
PrepareCommittedResources(m_BindInfo, DvpCompatibleSRBCount);
151148

152-
const auto ActiveStages = m_pPipelineState->GetActiveShaderStages();
149+
const SHADER_TYPE ActiveStages = m_pPipelineState->GetActiveShaderStages();
153150
if (m_BindInfo.ActiveStages != ActiveStages)
154151
{
155152
m_BindInfo.ActiveStages = ActiveStages;

Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -264,16 +264,15 @@ void DeviceContextD3D12Impl::Begin(Uint32 ImmediateContextId)
264264

265265
void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState)
266266
{
267-
RefCntAutoPtr<PipelineStateD3D12Impl> pPipelineStateD3D12{pPipelineState, PipelineStateD3D12Impl::IID_InternalImpl};
268-
VERIFY(pPipelineState == nullptr || pPipelineStateD3D12 != nullptr, "Unknown pipeline state object implementation");
269-
if (PipelineStateD3D12Impl::IsSameObject(m_pPipelineState, pPipelineStateD3D12))
267+
RefCntAutoPtr<PipelineStateD3D12Impl> pOldPipeline = m_pPipelineState;
268+
if (!TDeviceContextBase::SetPipelineState(pPipelineState, PipelineStateD3D12Impl::IID_InternalImpl))
270269
return;
271270

272-
const auto& PSODesc = pPipelineStateD3D12->GetDesc();
271+
const PipelineStateDesc& PSODesc = m_pPipelineState->GetDesc();
273272

274273
bool CommitStates = false;
275274
bool CommitScissor = false;
276-
if (!m_pPipelineState)
275+
if (!pOldPipeline)
277276
{
278277
// If no pipeline state is bound, we are working with the fresh command
279278
// list. We have to commit the states set in the context that are not
@@ -282,22 +281,21 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState)
282281
}
283282
else
284283
{
285-
const auto& OldPSODesc = m_pPipelineState->GetDesc();
284+
const PipelineStateDesc& OldPSODesc = pOldPipeline->GetDesc();
286285
// Commit all graphics states when switching from compute pipeline
287286
// This is necessary because if the command list had been flushed
288287
// and the first PSO set on the command list was a compute pipeline,
289288
// the states would otherwise never be committed (since m_pPipelineState != nullptr)
290289
CommitStates = !OldPSODesc.IsAnyGraphicsPipeline();
291290
// We also need to update scissor rect if ScissorEnable state has changed
292291
if (OldPSODesc.IsAnyGraphicsPipeline() && PSODesc.IsAnyGraphicsPipeline())
293-
CommitScissor = m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable != pPipelineStateD3D12->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable;
292+
CommitScissor = pOldPipeline->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable != m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable;
293+
pOldPipeline.Release();
294294
}
295295

296-
TDeviceContextBase::SetPipelineState(std::move(pPipelineStateD3D12), 0 /*Dummy*/);
297-
298-
auto& CmdCtx = GetCmdContext();
299-
auto& RootInfo = GetRootTableInfo(PSODesc.PipelineType);
300-
auto* pd3d12RootSig = m_pPipelineState->GetD3D12RootSignature();
296+
CommandContext& CmdCtx = GetCmdContext();
297+
RootTableInfo& RootInfo = GetRootTableInfo(PSODesc.PipelineType);
298+
ID3D12RootSignature* pd3d12RootSig = m_pPipelineState->GetD3D12RootSignature();
301299

302300
if (RootInfo.pd3d12RootSig != pd3d12RootSig)
303301
{
@@ -316,15 +314,15 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState)
316314
case PIPELINE_TYPE_GRAPHICS:
317315
case PIPELINE_TYPE_MESH:
318316
{
319-
auto& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
320-
auto& GraphicsCtx = CmdCtx.AsGraphicsContext();
321-
auto* pd3d12PSO = m_pPipelineState->GetD3D12PipelineState();
317+
const GraphicsPipelineDesc& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
318+
GraphicsContext& GraphicsCtx = CmdCtx.AsGraphicsContext();
319+
ID3D12PipelineState* pd3d12PSO = m_pPipelineState->GetD3D12PipelineState();
322320
GraphicsCtx.SetPipelineState(pd3d12PSO);
323321
GraphicsCtx.SetGraphicsRootSignature(pd3d12RootSig);
324322

325323
if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS)
326324
{
327-
auto D3D12Topology = TopologyToD3D12Topology(GraphicsPipeline.PrimitiveTopology);
325+
D3D12_PRIMITIVE_TOPOLOGY D3D12Topology = TopologyToD3D12Topology(GraphicsPipeline.PrimitiveTopology);
328326
GraphicsCtx.SetPrimitiveTopology(D3D12Topology);
329327
}
330328

@@ -347,16 +345,16 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState)
347345
}
348346
case PIPELINE_TYPE_COMPUTE:
349347
{
350-
auto* pd3d12PSO = m_pPipelineState->GetD3D12PipelineState();
351-
auto& CompCtx = CmdCtx.AsComputeContext();
348+
ID3D12PipelineState* pd3d12PSO = m_pPipelineState->GetD3D12PipelineState();
349+
ComputeContext& CompCtx = CmdCtx.AsComputeContext();
352350
CompCtx.SetPipelineState(pd3d12PSO);
353351
CompCtx.SetComputeRootSignature(pd3d12RootSig);
354352
break;
355353
}
356354
case PIPELINE_TYPE_RAY_TRACING:
357355
{
358-
auto* pd3d12SO = m_pPipelineState->GetD3D12StateObject();
359-
auto& RTCtx = CmdCtx.AsGraphicsContext4();
356+
ID3D12StateObject* pd3d12SO = m_pPipelineState->GetD3D12StateObject();
357+
GraphicsContext4& RTCtx = CmdCtx.AsGraphicsContext4();
360358
RTCtx.SetRayTracingPipelineState(pd3d12SO);
361359
RTCtx.SetComputeRootSignature(pd3d12RootSig);
362360
break;

Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -87,25 +87,19 @@ void DeviceContextGLImpl::Begin(Uint32 ImmediateContextId)
8787

8888
void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
8989
{
90-
VERIFY_EXPR(pPipelineState != nullptr);
91-
92-
RefCntAutoPtr<PipelineStateGLImpl> pPipelineStateGLImpl{pPipelineState, PipelineStateGLImpl::IID_InternalImpl};
93-
VERIFY(pPipelineState == nullptr || pPipelineStateGLImpl != nullptr, "Unknown pipeline state object implementation");
94-
if (PipelineStateGLImpl::IsSameObject(m_pPipelineState, pPipelineStateGLImpl))
90+
if (!TDeviceContextBase::SetPipelineState(pPipelineState, PipelineStateGLImpl::IID_InternalImpl))
9591
return;
9692

97-
TDeviceContextBase::SetPipelineState(std::move(pPipelineStateGLImpl), 0 /*Dummy*/);
98-
99-
const auto& Desc = m_pPipelineState->GetDesc();
93+
const PipelineStateDesc& Desc = m_pPipelineState->GetDesc();
10094
if (Desc.PipelineType == PIPELINE_TYPE_COMPUTE)
10195
{
10296
}
10397
else if (Desc.PipelineType == PIPELINE_TYPE_GRAPHICS)
10498
{
105-
const auto& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
99+
const GraphicsPipelineDesc& GraphicsPipeline = m_pPipelineState->GetGraphicsPipelineDesc();
106100
// Set rasterizer state
107101
{
108-
const auto& RasterizerDesc = GraphicsPipeline.RasterizerDesc;
102+
const RasterizerStateDesc& RasterizerDesc = GraphicsPipeline.RasterizerDesc;
109103

110104
m_ContextState.SetFillMode(RasterizerDesc.FillMode);
111105
m_ContextState.SetCullMode(RasterizerDesc.CullMode);
@@ -126,13 +120,13 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
126120

127121
// Set blend state
128122
{
129-
const auto& BSDsc = GraphicsPipeline.BlendDesc;
123+
const BlendStateDesc& BSDsc = GraphicsPipeline.BlendDesc;
130124
m_ContextState.SetBlendState(BSDsc, GraphicsPipeline.SampleMask);
131125
}
132126

133127
// Set depth-stencil state
134128
{
135-
const auto& DepthStencilDesc = GraphicsPipeline.DepthStencilDesc;
129+
const DepthStencilStateDesc& DepthStencilDesc = GraphicsPipeline.DepthStencilDesc;
136130

137131
m_ContextState.EnableDepthTest(DepthStencilDesc.DepthEnable);
138132
m_ContextState.EnableDepthWrites(DepthStencilDesc.DepthWriteEnable);
@@ -141,13 +135,13 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState)
141135
m_ContextState.SetStencilWriteMask(DepthStencilDesc.StencilWriteMask);
142136

143137
{
144-
const auto& FrontFace = DepthStencilDesc.FrontFace;
138+
const StencilOpDesc& FrontFace = DepthStencilDesc.FrontFace;
145139
m_ContextState.SetStencilFunc(GL_FRONT, FrontFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask);
146140
m_ContextState.SetStencilOp(GL_FRONT, FrontFace.StencilFailOp, FrontFace.StencilDepthFailOp, FrontFace.StencilPassOp);
147141
}
148142

149143
{
150-
const auto& BackFace = DepthStencilDesc.BackFace;
144+
const StencilOpDesc& BackFace = DepthStencilDesc.BackFace;
151145
m_ContextState.SetStencilFunc(GL_BACK, BackFace.StencilFunc, m_StencilRef, DepthStencilDesc.StencilReadMask);
152146
m_ContextState.SetStencilOp(GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp);
153147
}

0 commit comments

Comments
 (0)