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