@@ -89,31 +89,6 @@ namespace Diligent
89
89
90
90
IMPLEMENT_QUERY_INTERFACE ( DeviceContextD3D12Impl, IID_DeviceContextD3D12, TDeviceContextBase )
91
91
92
- const LONG MaxD3D12TexDim = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
93
- const Uint32 MaxD3D12ScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
94
- static const RECT MaxD3D12TexSizeRects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] =
95
- {
96
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
97
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
98
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
99
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
100
-
101
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
102
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
103
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
104
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
105
-
106
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
107
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
108
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
109
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
110
-
111
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
112
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
113
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim},
114
- {0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim}
115
- };
116
-
117
92
void DeviceContextD3D12Impl::SetPipelineState(IPipelineState *pPipelineState)
118
93
{
119
94
// Never flush deferred context!
@@ -122,18 +97,36 @@ namespace Diligent
122
97
Flush (true );
123
98
}
124
99
125
- // If no pipeline state is bound, we are working with the fresh command
126
- // list. We have to commit the states set in the context that are not
127
- // committed by the draw command (render targets, viewports, scissor rects, etc.)
128
- bool CommitStates = !m_pPipelineState;
100
+ auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState);
101
+ const auto &PSODesc = pPipelineStateD3D12->GetDesc ();
102
+
103
+ bool CommitStates = false ;
104
+ bool CommitScissor = false ;
105
+ if (!m_pPipelineState)
106
+ {
107
+ // If no pipeline state is bound, we are working with the fresh command
108
+ // list. We have to commit the states set in the context that are not
109
+ // committed by the draw command (render targets, viewports, scissor rects, etc.)
110
+ CommitStates = true ;
111
+ }
112
+ else
113
+ {
114
+ const auto & OldPSODesc = m_pPipelineState->GetDesc ();
115
+ // Commit all graphics states when switching from compute pipeline
116
+ // This is necessary because if the command list had been flushed
117
+ // and the first PSO set on the command list was a compute pipeline,
118
+ // the states would otherwise never be committed (since m_pPipelineState != nullptr)
119
+ CommitStates = OldPSODesc.IsComputePipeline ;
120
+ // We also need to update scissor rect if ScissorEnable state has changed
121
+ CommitScissor = OldPSODesc.GraphicsPipeline .RasterizerDesc .ScissorEnable != PSODesc.GraphicsPipeline .RasterizerDesc .ScissorEnable ;
122
+ }
129
123
130
124
TDeviceContextBase::SetPipelineState ( pPipelineState );
131
- auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState);
132
125
133
126
auto *pCmdCtx = RequestCmdContext ();
134
- const auto &Desc = pPipelineStateD3D12-> GetDesc ();
127
+
135
128
auto *pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState ();
136
- if (Desc .IsComputePipeline )
129
+ if (PSODesc .IsComputePipeline )
137
130
{
138
131
pCmdCtx->AsComputeContext ().SetPipelineState (pd3d12PSO);
139
132
}
@@ -142,33 +135,18 @@ namespace Diligent
142
135
auto &GraphicsCtx = pCmdCtx->AsGraphicsContext ();
143
136
GraphicsCtx.SetPipelineState (pd3d12PSO);
144
137
145
- if (CommitStates)
138
+ if (CommitStates)
146
139
{
147
- if (Desc.GraphicsPipeline .RasterizerDesc .ScissorEnable )
148
- {
149
- // Commit currently set scissor rectangles
150
- D3D12_RECT d3d12ScissorRects[MaxD3D12ScissorRects]; // Do not waste time initializing array with zeroes
151
- for ( Uint32 sr = 0 ; sr < m_NumScissorRects; ++sr )
152
- {
153
- d3d12ScissorRects[sr].left = m_ScissorRects[sr].left ;
154
- d3d12ScissorRects[sr].top = m_ScissorRects[sr].top ;
155
- d3d12ScissorRects[sr].right = m_ScissorRects[sr].right ;
156
- d3d12ScissorRects[sr].bottom = m_ScissorRects[sr].bottom ;
157
- }
158
- GraphicsCtx.SetScissorRects (m_NumScissorRects, d3d12ScissorRects);
159
- }
160
- else
161
- {
162
- // Disable scissor rectangles
163
- static_assert (_countof (MaxD3D12TexSizeRects) == MaxD3D12ScissorRects, " Unexpected array size" );
164
- GraphicsCtx.SetScissorRects (MaxD3D12ScissorRects, MaxD3D12TexSizeRects);
165
- }
166
-
167
140
GraphicsCtx.SetStencilRef (m_StencilRef);
168
141
GraphicsCtx.SetBlendFactor (m_BlendFactors);
169
142
CommitRenderTargets ();
170
143
CommitViewports ();
171
144
}
145
+
146
+ if (CommitStates || CommitScissor)
147
+ {
148
+ CommitScissorRects (GraphicsCtx, PSODesc.GraphicsPipeline .RasterizerDesc .ScissorEnable );
149
+ }
172
150
}
173
151
m_pCommittedResourceCache = nullptr ;
174
152
}
@@ -516,7 +494,7 @@ namespace Diligent
516
494
}
517
495
}
518
496
519
- static const float Zero[4 ] = { 0 .f , 0 .f , 0 .f , 0 .f };
497
+ static constexpr float Zero[4 ] = { 0 .f , 0 .f , 0 .f , 0 .f };
520
498
if ( RGBA == nullptr )
521
499
RGBA = Zero;
522
500
@@ -586,7 +564,7 @@ namespace Diligent
586
564
587
565
void DeviceContextD3D12Impl::CommitViewports ()
588
566
{
589
- const Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
567
+ constexpr Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
590
568
D3D12_VIEWPORT d3d12Viewports[MaxViewports]; // Do not waste time initializing array to zero
591
569
592
570
for ( Uint32 vp = 0 ; vp < m_NumViewports; ++vp )
@@ -605,7 +583,7 @@ namespace Diligent
605
583
606
584
void DeviceContextD3D12Impl::SetViewports ( Uint32 NumViewports, const Viewport *pViewports, Uint32 RTWidth, Uint32 RTHeight )
607
585
{
608
- const Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
586
+ constexpr Uint32 MaxViewports = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
609
587
VERIFY ( NumViewports < MaxViewports, " Too many viewports are being set" );
610
588
NumViewports = std::min ( NumViewports, MaxViewports );
611
589
@@ -615,6 +593,55 @@ namespace Diligent
615
593
CommitViewports ();
616
594
}
617
595
596
+
597
+ constexpr LONG MaxD3D12TexDim = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
598
+ constexpr Uint32 MaxD3D12ScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
599
+ static constexpr RECT MaxD3D12TexSizeRects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] =
600
+ {
601
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
602
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
603
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
604
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
605
+
606
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
607
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
608
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
609
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
610
+
611
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
612
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
613
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
614
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
615
+
616
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
617
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
618
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim },
619
+ { 0 ,0 , MaxD3D12TexDim,MaxD3D12TexDim }
620
+ };
621
+
622
+ void DeviceContextD3D12Impl::CommitScissorRects (GraphicsContext &GraphCtx, bool ScissorEnable)
623
+ {
624
+ if (ScissorEnable)
625
+ {
626
+ // Commit currently set scissor rectangles
627
+ D3D12_RECT d3d12ScissorRects[MaxD3D12ScissorRects]; // Do not waste time initializing array with zeroes
628
+ for (Uint32 sr = 0 ; sr < m_NumScissorRects; ++sr)
629
+ {
630
+ d3d12ScissorRects[sr].left = m_ScissorRects[sr].left ;
631
+ d3d12ScissorRects[sr].top = m_ScissorRects[sr].top ;
632
+ d3d12ScissorRects[sr].right = m_ScissorRects[sr].right ;
633
+ d3d12ScissorRects[sr].bottom = m_ScissorRects[sr].bottom ;
634
+ }
635
+ GraphCtx.SetScissorRects (m_NumScissorRects, d3d12ScissorRects);
636
+ }
637
+ else
638
+ {
639
+ // Disable scissor rectangles
640
+ static_assert (_countof (MaxD3D12TexSizeRects) == MaxD3D12ScissorRects, " Unexpected array size" );
641
+ GraphCtx.SetScissorRects (MaxD3D12ScissorRects, MaxD3D12TexSizeRects);
642
+ }
643
+ }
644
+
618
645
void DeviceContextD3D12Impl::SetScissorRects ( Uint32 NumRects, const Rect *pRects, Uint32 RTWidth, Uint32 RTHeight )
619
646
{
620
647
const Uint32 MaxScissorRects = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
@@ -624,18 +651,17 @@ namespace Diligent
624
651
TDeviceContextBase::SetScissorRects (NumRects, pRects, RTWidth, RTHeight);
625
652
626
653
// Only commit scissor rects if scissor test is enabled in the rasterizer state.
627
- if ( !m_pPipelineState || m_pPipelineState->GetDesc ().GraphicsPipeline .RasterizerDesc .ScissorEnable )
654
+ // If scissor is currently disabled, or no PSO is bound, scissor rects will be committed by
655
+ // the SetPipelineState() when a PSO with enabled scissor test is set.
656
+ if ( m_pPipelineState )
628
657
{
629
- D3D12_RECT d3d12ScissorRects[MaxScissorRects];
630
- VERIFY ( NumRects == m_NumScissorRects, " Unexpected number of scissor rects" );
631
- for ( Uint32 sr = 0 ; sr < NumRects; ++sr )
658
+ const auto &PSODesc = m_pPipelineState->GetDesc ();
659
+ if (!PSODesc.IsComputePipeline && PSODesc.GraphicsPipeline .RasterizerDesc .ScissorEnable )
632
660
{
633
- d3d12ScissorRects[sr].left = m_ScissorRects[sr].left ;
634
- d3d12ScissorRects[sr].top = m_ScissorRects[sr].top ;
635
- d3d12ScissorRects[sr].right = m_ScissorRects[sr].right ;
636
- d3d12ScissorRects[sr].bottom = m_ScissorRects[sr].bottom ;
661
+ VERIFY (NumRects == m_NumScissorRects, " Unexpected number of scissor rects" );
662
+ auto &Ctx = RequestCmdContext ()->AsGraphicsContext ();
663
+ CommitScissorRects (Ctx, true );
637
664
}
638
- RequestCmdContext ()->AsGraphicsContext ().SetScissorRects (NumRects, d3d12ScissorRects);
639
665
}
640
666
}
641
667
0 commit comments