• 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     void releaseResources();
104 
hasWork()105     bool hasWork() const { return fHasWork; }
106 
107     void addFinishedCallback(sk_sp<GrRefCntedCallback> callback);
108 
109 private:
110     static const int kInitialTrackedResourcesCount = 32;
111 
112 protected:
113     GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
114                      gr_cp<ID3D12GraphicsCommandList> commandList);
115 
116     // Add ref-counted resource that will be tracked and released when this command buffer finishes
117     // execution
addResource(sk_sp<GrManagedResource> resource)118     void addResource(sk_sp<GrManagedResource> resource) {
119         SkASSERT(resource);
120         resource->notifyQueuedForWorkOnGpu();
121         fTrackedResources.push_back(std::move(resource));
122     }
123 
124     // Add ref-counted resource that will be tracked and released when this command buffer finishes
125     // execution. When it is released, it will signal that the resource can be recycled for reuse.
addRecycledResource(sk_sp<GrRecycledResource> resource)126     void addRecycledResource(sk_sp<GrRecycledResource> resource) {
127         resource->notifyQueuedForWorkOnGpu();
128         fTrackedRecycledResources.push_back(std::move(resource));
129     }
130 
131     void addingWork();
onReset()132     virtual void onReset() {}
133 
134     void submitResourceBarriers();
135 
136     gr_cp<ID3D12GraphicsCommandList> fCommandList;
137 
138     SkSTArray<kInitialTrackedResourcesCount, sk_sp<GrManagedResource>> fTrackedResources;
139     SkSTArray<kInitialTrackedResourcesCount, sk_sp<GrRecycledResource>> fTrackedRecycledResources;
140     SkSTArray<kInitialTrackedResourcesCount, sk_sp<const GrBuffer>> fTrackedGpuBuffers;
141 
142 
143     // When we create a command list it starts in an active recording state
144     SkDEBUGCODE(bool fIsActive = true;)
145     bool fHasWork = false;
146 
147 private:
callFinishedCallbacks()148     void callFinishedCallbacks() { fFinishedCallbacks.reset(); }
149 
150     gr_cp<ID3D12CommandAllocator> fAllocator;
151 
152     SkSTArray<4, D3D12_RESOURCE_BARRIER> fResourceBarriers;
153 
154     SkTArray<sk_sp<GrRefCntedCallback>> fFinishedCallbacks;
155 };
156 
157 class GrD3DDirectCommandList : public GrD3DCommandList {
158 public:
159     static std::unique_ptr<GrD3DDirectCommandList> Make(ID3D12Device* device);
160 
161     ~GrD3DDirectCommandList() override = default;
162 
163     void setPipelineState(const sk_sp<GrD3DPipeline>& pipeline);
164 
165     void setStencilRef(unsigned int stencilRef);
166     void setBlendFactor(const float blendFactor[4]);
167     void setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology);
168     void setScissorRects(unsigned int numRects, const D3D12_RECT* rects);
169     void setViewports(unsigned int numViewports, const D3D12_VIEWPORT* viewports);
170     void setCenteredSamplePositions(unsigned int numSamples);
171     void setDefaultSamplePositions();
172     void setGraphicsRootSignature(const sk_sp<GrD3DRootSignature>& rootSignature);
173     void setComputeRootSignature(const sk_sp<GrD3DRootSignature>& rootSignature);
174     void setVertexBuffers(unsigned int startSlot,
175                           sk_sp<const GrBuffer> vertexBuffer, size_t vertexStride,
176                           sk_sp<const GrBuffer> instanceBuffer, size_t instanceStride);
177     void setIndexBuffer(sk_sp<const GrBuffer> indexBuffer);
178     void drawInstanced(unsigned int vertexCount, unsigned int instanceCount,
179                        unsigned int startVertex, unsigned int startInstance);
180     void drawIndexedInstanced(unsigned int indexCount, unsigned int instanceCount,
181                               unsigned int startIndex, unsigned int baseVertex,
182                               unsigned int startInstance);
183     void executeIndirect(const sk_sp<GrD3DCommandSignature> commandSig, unsigned int maxCommandCnt,
184                          const GrD3DBuffer* argumentBuffer, size_t argumentBufferOffset);
185     void dispatch(unsigned int threadGroupCountX, unsigned int threadGroupCountY,
186                   unsigned int threadGroupCountZ = 1);
187 
188     void clearRenderTargetView(const GrD3DRenderTarget* renderTarget,
189                                std::array<float, 4> color,
190                                const D3D12_RECT* rect);
191     void clearDepthStencilView(const GrD3DAttachment*,
192                                uint8_t stencilClearValue,
193                                const D3D12_RECT* rect);
194     void setRenderTarget(const GrD3DRenderTarget* renderTarget);
195     void resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
196                                   unsigned int dstX, unsigned int dstY,
197                                   const GrD3DTextureResource* srcTexture,
198                                   D3D12_RECT* srcRect);
199 
200     void setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,
201                                            D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);
202     void setGraphicsRootDescriptorTable(unsigned int rootParameterIndex,
203                                         D3D12_GPU_DESCRIPTOR_HANDLE bufferLocation);
204     void setComputeRootConstantBufferView(unsigned int rootParameterIndex,
205                                           D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);
206     void setComputeRootDescriptorTable(unsigned int rootParameterIndex,
207                                        D3D12_GPU_DESCRIPTOR_HANDLE bufferLocation);
208     void setDescriptorHeaps(sk_sp<GrRecycledResource> srvCrvHeapResource,
209                             ID3D12DescriptorHeap* srvDescriptorHeap,
210                             sk_sp<GrRecycledResource> samplerHeapResource,
211                             ID3D12DescriptorHeap* samplerDescriptorHeap);
212 
213     void addSampledTextureRef(GrD3DTexture*);
214 
215 private:
216     GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
217                            gr_cp<ID3D12GraphicsCommandList> commandList);
218 
219     void onReset() override;
220 
221     const GrD3DPipeline* fCurrentPipeline = nullptr;
222     const GrD3DRootSignature* fCurrentGraphicsRootSignature = nullptr;
223     const GrD3DRootSignature* fCurrentComputeRootSignature = nullptr;
224     const GrBuffer* fCurrentVertexBuffer = nullptr;
225     size_t fCurrentVertexStride = 0;
226     const GrBuffer* fCurrentInstanceBuffer = nullptr;
227     size_t fCurrentInstanceStride = 0;
228     const GrBuffer* fCurrentIndexBuffer = nullptr;
229     bool fUsingCenteredSamples = false;
230 
231     D3D12_GPU_VIRTUAL_ADDRESS fCurrentGraphicsConstantBufferAddress = 0;
232     D3D12_GPU_VIRTUAL_ADDRESS fCurrentComputeConstantBufferAddress = 0;
233     D3D12_GPU_DESCRIPTOR_HANDLE fCurrentGraphicsRootDescTable[GrD3DRootSignature::kParamIndexCount];
234     D3D12_GPU_DESCRIPTOR_HANDLE fCurrentComputeRootDescTable[GrD3DRootSignature::kParamIndexCount];
235     const ID3D12DescriptorHeap* fCurrentSRVCRVDescriptorHeap = nullptr;
236     const ID3D12DescriptorHeap* fCurrentSamplerDescriptorHeap = nullptr;
237 };
238 
239 class GrD3DCopyCommandList : public GrD3DCommandList {
240 public:
241     static std::unique_ptr<GrD3DCopyCommandList> Make(ID3D12Device* device);
242 
243 private:
244     GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,
245                          gr_cp<ID3D12GraphicsCommandList> commandList);
246 };
247 #endif
248