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