• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrD3DCommandList_DEFINED
9 #define GrD3DCommandList_DEFINED
10 
11 #include "include/gpu/ganesh/GrTypes.h"
12 #include "include/gpu/ganesh/d3d/GrD3DTypes.h"
13 #include "include/private/base/SkTArray.h"
14 #include "src/gpu/ganesh/GrManagedResource.h"
15 #include "src/gpu/ganesh/GrRingBuffer.h"
16 #include "src/gpu/ganesh/d3d/GrD3DRootSignature.h"
17 
18 #include <memory>
19 
20 class GrD3DGpu;
21 class GrD3DBuffer;
22 class GrD3DCommandSignature;
23 class GrD3DConstantRingBuffer;
24 class GrD3DPipeline;
25 class GrD3DRenderTarget;
26 class GrD3DRootSignature;
27 class GrD3DAttachment;
28 class GrD3DTexture;
29 class GrD3DTextureResource;
30 
31 class GrScissorState;
32 
33 class GrD3DCommandList {
34 public:
~GrD3DCommandList()35     virtual ~GrD3DCommandList() {
36         this->releaseResources();
37     }
38 
39     enum class SubmitResult {
40         kNoWork,
41         kSuccess,
42         kFailure,
43     };
44     SubmitResult submit(ID3D12CommandQueue* queue);
45 
46     bool close();
47     void reset();
48 
49     ////////////////////////////////////////////////////////////////////////////
50     // GraphicsCommandList commands
51     ////////////////////////////////////////////////////////////////////////////
52 
53     // All barriers should reference subresources of managedResource
54     void resourceBarrier(sk_sp<GrManagedResource> managedResource,
55                          int numBarriers,
56                          const D3D12_RESOURCE_TRANSITION_BARRIER* barriers);
57 
58     void uavBarrier(sk_sp<GrManagedResource> managedResource,
59                     ID3D12Resource* uavResource);
60 
61     void aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,
62                          ID3D12Resource* beforeResource,
63                          sk_sp<GrManagedResource> afterManagedResource,
64                          ID3D12Resource* afterResource);
65 
66     // Helper method that calls copyTextureRegion multiple times, once for each subresource
67     // The srcBuffer comes from a staging buffer so we don't need to take any refs to it. Instead,
68     // we ref the whole buffer during sumbit.
69     void copyBufferToTexture(ID3D12Resource* srcBuffer,
70                              const GrD3DTextureResource* dstTexture,
71                              uint32_t subresourceCount,
72                              D3D12_PLACED_SUBRESOURCE_FOOTPRINT* bufferFootprints,
73                              int left, int top);
74 
75     void copyTextureRegionToTexture(sk_sp<GrManagedResource> dst,
76                                     const D3D12_TEXTURE_COPY_LOCATION* dstLocation,
77                                     UINT dstX, UINT dstY,
78                                     sk_sp<GrManagedResource> src,
79                                     const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
80                                     const D3D12_BOX* srcBox);
81 
82      void copyTextureRegionToBuffer(sk_sp<const GrBuffer> dst,
83                                     const D3D12_TEXTURE_COPY_LOCATION* dstLocation,
84                                     UINT dstX,
85                                     UINT dstY,
86                                     sk_sp<GrManagedResource> src,
87                                     const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
88                                     const D3D12_BOX* srcBox);
89 
90      void copyTextureToTexture(const GrD3DTexture* dst,
91                                const GrD3DTexture* src,
92                                UINT subresourceIndex = -1);
93 
94     // We don't take a ref to the src buffer because we assume the src buffer is coming from a
95     // staging buffer which will get ref'd during submit.
96     void copyBufferToBuffer(sk_sp<GrD3DBuffer> dstBuffer, uint64_t dstOffset,
97                             ID3D12Resource* srcBuffer, uint64_t srcOffset,
98                             uint64_t numBytes);
99 
addGrBuffer(sk_sp<const GrBuffer> buffer)100     void addGrBuffer(sk_sp<const GrBuffer> buffer) {
101         fTrackedGpuBuffers.push_back(std::move(buffer));
102     }
103 
104     // Add ref-counted resource that will be tracked and released when this command buffer finishes
105     // execution. When it is released, it will signal that the resource can be recycled for reuse.
addRecycledResource(sk_sp<GrRecycledResource> resource)106     void addRecycledResource(sk_sp<GrRecycledResource> resource) {
107         fTrackedRecycledResources.push_back(std::move(resource));
108     }
109 
110     void releaseResources();
111 
hasWork()112     bool hasWork() const { return fHasWork; }
113 
114     void addFinishedCallback(sk_sp<skgpu::RefCntedCallback> callback);
115 
116 private:
117     static const int kInitialTrackedResourcesCount = 32;
118 
119 protected:
120     GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
121                      gr_cp<ID3D12GraphicsCommandList> commandList);
122 
123     // Add ref-counted resource that will be tracked and released when this command buffer finishes
124     // execution
addResource(sk_sp<GrManagedResource> resource)125     void addResource(sk_sp<GrManagedResource> resource) {
126         SkASSERT(resource);
127         fTrackedResources.push_back(std::move(resource));
128     }
129 
130     void addingWork();
onReset()131     virtual void onReset() {}
132 
133     void submitResourceBarriers();
134 
135     gr_cp<ID3D12GraphicsCommandList> fCommandList;
136 
137     template<typename T>
138     using TrackedResourceArray = skia_private::STArray<kInitialTrackedResourcesCount, T>;
139     TrackedResourceArray<sk_sp<GrManagedResource>> fTrackedResources;
140     TrackedResourceArray<sk_sp<GrRecycledResource>> fTrackedRecycledResources;
141     TrackedResourceArray<sk_sp<const GrBuffer>> fTrackedGpuBuffers;
142 
143 
144     // When we create a command list it starts in an active recording state
145     SkDEBUGCODE(bool fIsActive = true;)
146     bool fHasWork = false;
147 
148 private:
callFinishedCallbacks()149     void callFinishedCallbacks() { fFinishedCallbacks.clear(); }
150 
151     gr_cp<ID3D12CommandAllocator> fAllocator;
152 
153     skia_private::STArray<4, D3D12_RESOURCE_BARRIER> fResourceBarriers;
154 
155     skia_private::TArray<sk_sp<skgpu::RefCntedCallback>> fFinishedCallbacks;
156 };
157 
158 class GrD3DDirectCommandList : public GrD3DCommandList {
159 public:
160     static std::unique_ptr<GrD3DDirectCommandList> Make(GrD3DGpu* gpu);
161 
162     ~GrD3DDirectCommandList() override = default;
163 
164     void setPipelineState(const sk_sp<GrD3DPipeline>& pipeline);
165 
166     void setStencilRef(unsigned int stencilRef);
167     void setBlendFactor(const float blendFactor[4]);
168     void setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology);
169     void setScissorRects(unsigned int numRects, const D3D12_RECT* rects);
170     void setViewports(unsigned int numViewports, const D3D12_VIEWPORT* viewports);
171     void setGraphicsRootSignature(const sk_sp<GrD3DRootSignature>& rootSignature);
172     void setComputeRootSignature(const sk_sp<GrD3DRootSignature>& rootSignature);
173     void setVertexBuffers(unsigned int startSlot,
174                           sk_sp<const GrBuffer> vertexBuffer, size_t vertexStride,
175                           sk_sp<const GrBuffer> instanceBuffer, size_t instanceStride);
176     void setIndexBuffer(sk_sp<const GrBuffer> indexBuffer);
177     void drawInstanced(unsigned int vertexCount, unsigned int instanceCount,
178                        unsigned int startVertex, unsigned int startInstance);
179     void drawIndexedInstanced(unsigned int indexCount, unsigned int instanceCount,
180                               unsigned int startIndex, unsigned int baseVertex,
181                               unsigned int startInstance);
182     void executeIndirect(const sk_sp<GrD3DCommandSignature> commandSig, unsigned int maxCommandCnt,
183                          const GrD3DBuffer* argumentBuffer, size_t argumentBufferOffset);
184     void dispatch(unsigned int threadGroupCountX, unsigned int threadGroupCountY,
185                   unsigned int threadGroupCountZ = 1);
186 
187     void clearRenderTargetView(const GrD3DRenderTarget* renderTarget,
188                                std::array<float, 4> color,
189                                const D3D12_RECT* rect);
190     void clearDepthStencilView(const GrD3DAttachment*,
191                                uint8_t stencilClearValue,
192                                const D3D12_RECT* rect);
193     void setRenderTarget(const GrD3DRenderTarget* renderTarget);
194     void resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
195                                   unsigned int dstX, unsigned int dstY,
196                                   const GrD3DTextureResource* srcTexture,
197                                   D3D12_RECT* srcRect);
198 
199     void setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,
200                                            D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);
201     void setGraphicsRootDescriptorTable(unsigned int rootParameterIndex,
202                                         D3D12_GPU_DESCRIPTOR_HANDLE bufferLocation);
203     void setComputeRootConstantBufferView(unsigned int rootParameterIndex,
204                                           D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);
205     void setComputeRootDescriptorTable(unsigned int rootParameterIndex,
206                                        D3D12_GPU_DESCRIPTOR_HANDLE bufferLocation);
207     void setDescriptorHeaps(ID3D12DescriptorHeap* srvDescriptorHeap,
208                             ID3D12DescriptorHeap* samplerDescriptorHeap);
209 
210     void addSampledTextureRef(GrD3DTexture*);
211 
212 private:
213     GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
214                            gr_cp<ID3D12GraphicsCommandList> commandList,
215                            bool resolveSubregionSupported);
216 
217     void onReset() override;
218 
219     const GrD3DPipeline* fCurrentPipeline = nullptr;
220     const GrD3DRootSignature* fCurrentGraphicsRootSignature = nullptr;
221     const GrD3DRootSignature* fCurrentComputeRootSignature = nullptr;
222     const GrBuffer* fCurrentVertexBuffer = nullptr;
223     size_t fCurrentVertexStride = 0;
224     const GrBuffer* fCurrentInstanceBuffer = nullptr;
225     size_t fCurrentInstanceStride = 0;
226     const GrBuffer* fCurrentIndexBuffer = nullptr;
227 
228     D3D12_GPU_VIRTUAL_ADDRESS fCurrentGraphicsConstantBufferAddress = 0;
229     D3D12_GPU_VIRTUAL_ADDRESS fCurrentComputeConstantBufferAddress = 0;
230     D3D12_GPU_DESCRIPTOR_HANDLE fCurrentGraphicsRootDescTable[GrD3DRootSignature::kParamIndexCount];
231     D3D12_GPU_DESCRIPTOR_HANDLE fCurrentComputeRootDescTable[GrD3DRootSignature::kParamIndexCount];
232     const ID3D12DescriptorHeap* fCurrentSRVCRVDescriptorHeap = nullptr;
233     const ID3D12DescriptorHeap* fCurrentSamplerDescriptorHeap = nullptr;
234 
235     bool fResolveSubregionSupported;
236 };
237 
238 class GrD3DCopyCommandList : public GrD3DCommandList {
239 public:
240     static std::unique_ptr<GrD3DCopyCommandList> Make(GrD3DGpu* gpu);
241 
242 private:
243     GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,
244                          gr_cp<ID3D12GraphicsCommandList> commandList);
245 };
246 #endif
247