Diligent Engine API Reference: D:/GitHub/DiligentEngine/DiligentCore/Graphics/GraphicsEngineD3D12/include/CommandContext.h Source File

Diligent Engine API Reference

CommandContext.h
1 /* Copyright 2015-2018 Egor Yusov
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12 *
13 * In no event and under no legal theory, whether in tort (including negligence),
14 * contract, or otherwise, unless required by applicable law (such as deliberate
15 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16 * liable for any damages, including any direct, indirect, special, incidental,
17 * or consequential damages of any character arising as a result of this License or
18 * out of the use or inability to use the software (including but not limited to damages
19 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20 * all other commercial damages or losses), even if such Contributor has been advised
21 * of the possibility of such damages.
22 */
23
24
25 #pragma once
26
27 #include <vector>
28
29 #include "D3D12ResourceBase.h"
30 #include "TextureViewD3D12.h"
31 #include "TextureD3D12.h"
32 #include "BufferD3D12.h"
33 #include "DescriptorHeap.h"
34
35 namespace Diligent
36 {
37
38
39 struct DWParam
40 {
41 DWParam( FLOAT f ) : Float(f) {}
42 DWParam( UINT u ) : Uint(u) {}
43 DWParam( INT i ) : Int(i) {}
44
45 void operator= ( FLOAT f ) { Float = f; }
46 void operator= ( UINT u ) { Uint = u; }
47 void operator= ( INT i ) { Int = i; }
48
49 union
50 {
51 FLOAT Float;
52 UINT Uint;
53 INT Int;
54 };
55 };
56
57
58 class CommandContext
59 {
60 public:
61
62 CommandContext( IMemoryAllocator &MemAllocator,
63 class CommandListManager& CmdListManager,
64 GPUDescriptorHeap GPUDescriptorHeaps[],
65 const Uint32 DynamicDescriptorAllocationChunkSize[]);
66
67 ~CommandContext(void);
68
69 // Submit the command buffer and reset it. This is encouraged to keep the GPU busy and reduce latency.
70 // Taking too long to build command lists and submit them can idle the GPU.
71 ID3D12GraphicsCommandList* Close(ID3D12CommandAllocator **ppAllocator);
72 void Reset( CommandListManager& CmdListManager );
73
74 class GraphicsContext& AsGraphicsContext();
75 class ComputeContext& AsComputeContext();
76
77 void ClearUAVFloat( ITextureViewD3D12 *pTexView, const float* Color );
78 void ClearUAVUint( ITextureViewD3D12 *pTexView, const UINT *Color );
79
80 void CopyResource(ID3D12Resource *pDstRes, ID3D12Resource *pSrcRes)
81 {
82 m_pCommandList->CopyResource(pDstRes, pSrcRes);
83 }
84
85 void TransitionResource(ITextureD3D12 *pTexture, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false);
86 void TransitionResource(IBufferD3D12 *pBuffer, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false);
87 //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false);
88 void FlushResourceBarriers();
89
90 struct ShaderDescriptorHeaps
91 {
92 ID3D12DescriptorHeap* pSrvCbvUavHeap;
93 ID3D12DescriptorHeap* pSamplerHeap;
94 ShaderDescriptorHeaps(ID3D12DescriptorHeap* _pSrvCbvUavHeap = nullptr, ID3D12DescriptorHeap* _pSamplerHeap = nullptr) :
95 pSrvCbvUavHeap(_pSrvCbvUavHeap),
96 pSamplerHeap(_pSamplerHeap)
97 {}
98 bool operator == (const ShaderDescriptorHeaps& rhs)const
99 {
100 return pSrvCbvUavHeap == rhs.pSrvCbvUavHeap && pSamplerHeap == rhs.pSamplerHeap;
101 }
102 operator bool()const
103 {
104 return pSrvCbvUavHeap != nullptr || pSamplerHeap != nullptr;
105 }
106 };
107 void SetDescriptorHeaps( ShaderDescriptorHeaps& Heaps );
108
109 void ExecuteIndirect(ID3D12CommandSignature *pCmdSignature, ID3D12Resource *pBuff, Uint64 ArgsOffset)
110 {
111 FlushResourceBarriers();
112 m_pCommandList->ExecuteIndirect(pCmdSignature, 1, pBuff, ArgsOffset, nullptr, 0);
113 }
114
115 void SetID(const Char* ID) { m_ID = ID; }
116 ID3D12GraphicsCommandList *GetCommandList(){return m_pCommandList;}
117
118 void DiscardDynamicDescriptors(Uint64 FenceValue);
119 DescriptorHeapAllocation AllocateDynamicGPUVisibleDescriptor( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1 );
120
121 void InsertUAVBarrier(D3D12ResourceBase& Resource, IDeviceObject &Object, bool FlushImmediate = false);
122
123 void SetPipelineState( ID3D12PipelineState* pPSO )
124 {
125 if (pPSO != m_pCurPipelineState)
126 {
127 m_pCommandList->SetPipelineState(m_pCurPipelineState = pPSO);
128 }
129 }
130
131 protected:
132 void TransitionResource(D3D12ResourceBase& Resource, IDeviceObject &Object, D3D12_RESOURCE_STATES NewState, bool FlushImmediate);
133 void InsertAliasBarrier(D3D12ResourceBase& Before, D3D12ResourceBase& After, IDeviceObject &BeforeObj, IDeviceObject &AfterObj, bool FlushImmediate = false);
134
135 CComPtr<ID3D12GraphicsCommandList> m_pCommandList;
136 CComPtr<ID3D12CommandAllocator> m_pCurrentAllocator;
137
138 ID3D12PipelineState* m_pCurPipelineState = nullptr;
139 ID3D12RootSignature* m_pCurGraphicsRootSignature = nullptr;
140 ID3D12RootSignature* m_pCurComputeRootSignature = nullptr;
141
142 static constexpr int MaxPendingBarriers = 16;
143 std::vector<D3D12_RESOURCE_BARRIER, STDAllocatorRawMem<D3D12_RESOURCE_BARRIER> > m_PendingResourceBarriers;
144 // We must make sure that all referenced objects are alive until barriers are executed
145 // Keeping reference to ID3D12Resource is not sufficient!
146 // TextureD3D12Impl::~TextureD3D12Impl() and BufferD3D12Impl::~BufferD3D12Impl()
147 // are responsible for putting the D3D12 resource in the release queue
148 std::vector< RefCntAutoPtr<IDeviceObject>, STDAllocatorRawMem<RefCntAutoPtr<IDeviceObject>> > m_PendingBarrierObjects;
149
150 ShaderDescriptorHeaps m_BoundDescriptorHeaps;
151
152 // Every context must use its own allocator that maintains individual list of retired descriptor heaps to
153 // avoid interference with other command contexts
154 // The heaps can only be discarded after the command list is submitted for execution
155 DynamicSuballocationsManager m_DynamicGPUDescriptorAllocator[2];
156
157 String m_ID;
158
159 D3D12_PRIMITIVE_TOPOLOGY m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
160 };
161
162
163 class GraphicsContext : public CommandContext
164 {
165 public:
166 void ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color );
167 void ClearDepthStencil( ITextureViewD3D12 *pDSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil );
168
169 void SetRootSignature( ID3D12RootSignature *pRootSig )
170 {
171 if (pRootSig != m_pCurGraphicsRootSignature)
172 {
173 m_pCommandList->SetGraphicsRootSignature(m_pCurGraphicsRootSignature = pRootSig);
174 }
175 }
176
177 void SetRenderTargets( UINT NumRTVs, ITextureViewD3D12** ppRTVs, ITextureViewD3D12* pDSV );
178
179 void SetViewports( UINT NumVPs, const D3D12_VIEWPORT* pVPs )
180 {
181 m_pCommandList->RSSetViewports(NumVPs, pVPs);
182 }
183
184 void SetScissorRects( UINT NumRects, const D3D12_RECT* pRects )
185 {
186 m_pCommandList->RSSetScissorRects(NumRects, pRects);
187 }
188
189 void SetStencilRef( UINT StencilRef )
190 {
191 m_pCommandList->OMSetStencilRef( StencilRef );
192 }
193
194 void SetBlendFactor( const float* BlendFactor )
195 {
196 m_pCommandList->OMSetBlendFactor( BlendFactor );
197 }
198
199 void SetPrimitiveTopology( D3D12_PRIMITIVE_TOPOLOGY Topology )
200 {
201 if(m_PrimitiveTopology != Topology)
202 {
203 m_PrimitiveTopology = Topology;
204 m_pCommandList->IASetPrimitiveTopology(Topology);
205 }
206 }
207
208 void SetConstants( UINT RootIndex, UINT NumConstants, const void* pConstants )
209 {
210 m_pCommandList->SetGraphicsRoot32BitConstants( RootIndex, NumConstants, pConstants, 0 );
211 }
212
213 void SetConstants( UINT RootIndex, DWParam X )
214 {
215 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 );
216 }
217
218 void SetConstants( UINT RootIndex, DWParam X, DWParam Y )
219 {
220 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 );
221 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 );
222 }
223
224 void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z )
225 {
226 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 );
227 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 );
228 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Z.Uint, 2 );
229 }
230
231 void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W )
232 {
233 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, X.Uint, 0 );
234 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Y.Uint, 1 );
235 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, Z.Uint, 2 );
236 m_pCommandList->SetGraphicsRoot32BitConstant( RootIndex, W.Uint, 3 );
237 }
238
239 void SetConstantBuffer( UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV )
240 {
241 m_pCommandList->SetGraphicsRootConstantBufferView(RootIndex, CBV);
242 }
243
244 void SetDescriptorTable( UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle )
245 {
246 m_pCommandList->SetGraphicsRootDescriptorTable( RootIndex, FirstHandle );
247 }
248
249 void SetIndexBuffer( const D3D12_INDEX_BUFFER_VIEW& IBView )
250 {
251 m_pCommandList->IASetIndexBuffer(&IBView);
252 }
253
254 void SetVertexBuffers( UINT StartSlot, UINT Count, const D3D12_VERTEX_BUFFER_VIEW VBViews[] )
255 {
256 m_pCommandList->IASetVertexBuffers(StartSlot, Count, VBViews);
257 }
258
259 void Draw(UINT VertexCountPerInstance, UINT InstanceCount,
260 UINT StartVertexLocation, UINT StartInstanceLocation)
261 {
262 FlushResourceBarriers();
263 m_pCommandList->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation);
264 }
265
266 void DrawIndexed(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation,
267 INT BaseVertexLocation, UINT StartInstanceLocation)
268 {
269 FlushResourceBarriers();
270 m_pCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation);
271 }
272 };
273
274 class ComputeContext : public CommandContext
275 {
276 public:
277
278 void SetRootSignature( ID3D12RootSignature *pRootSig )
279 {
280 if (pRootSig != m_pCurComputeRootSignature)
281 {
282 m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig);
283 }
284 }
285
286 void SetConstants( UINT RootIndex, UINT NumConstants, const void* pConstants )
287 {
288 m_pCommandList->SetComputeRoot32BitConstants( RootIndex, NumConstants, pConstants, 0 );
289 }
290
291 void SetConstants( UINT RootIndex, DWParam X )
292 {
293 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 );
294 }
295
296 void SetConstants( UINT RootIndex, DWParam X, DWParam Y )
297 {
298 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 );
299 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 );
300 }
301
302 void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z )
303 {
304 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 );
305 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 );
306 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Z.Uint, 2 );
307 }
308
309 void SetConstants( UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W )
310 {
311 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, X.Uint, 0 );
312 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Y.Uint, 1 );
313 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, Z.Uint, 2 );
314 m_pCommandList->SetComputeRoot32BitConstant( RootIndex, W.Uint, 3 );
315 }
316
317
318 void SetConstantBuffer( UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV )
319 {
320 m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV);
321 }
322
323 void SetDescriptorTable( UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle )
324 {
325 m_pCommandList->SetComputeRootDescriptorTable( RootIndex, FirstHandle );
326 }
327
328 void Dispatch( size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1 )
329 {
330 FlushResourceBarriers();
331 m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ);
332 }
333 };
334
335 inline GraphicsContext& CommandContext::AsGraphicsContext()
336 {
337 return static_cast<GraphicsContext&>(*this);
338 }
339
340 inline ComputeContext& CommandContext::AsComputeContext()
341 {
342 return static_cast<ComputeContext&>(*this);
343 }
344
345 inline void CommandContext::SetDescriptorHeaps( ShaderDescriptorHeaps& Heaps )
346 {
347 #ifdef _DEBUG
348 VERIFY(Heaps.pSrvCbvUavHeap != nullptr || Heaps.pSamplerHeap != nullptr, "At least one heap is expected to be set");
349 VERIFY(Heaps.pSrvCbvUavHeap == nullptr || Heaps.pSrvCbvUavHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, "Invalid heap type provided in pSrvCbvUavHeap");
350 VERIFY(Heaps.pSamplerHeap == nullptr || Heaps.pSamplerHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type provided in pSamplerHeap");
351 #endif
352
353 if (!(Heaps == m_BoundDescriptorHeaps))
354 {
355 m_BoundDescriptorHeaps = Heaps;
356
357 ID3D12DescriptorHeap **ppHeaps = reinterpret_cast<ID3D12DescriptorHeap**>(&Heaps);
358 UINT NumHeaps = (ppHeaps[0] != nullptr ? 1 : 0) + (ppHeaps[1] != nullptr ? 1 : 0);
359 if(ppHeaps[0] == nullptr)
360 ++ppHeaps;
361
362 m_pCommandList->SetDescriptorHeaps(NumHeaps, ppHeaps);
363 }
364 }
365
366 }
Diligent
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34