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