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