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