• 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 #include "src/gpu/d3d/GrD3DCommandList.h"
9 
10 #include "src/core/SkTraceEvent.h"
11 #include "src/gpu/GrScissorState.h"
12 #include "src/gpu/d3d/GrD3DAttachment.h"
13 #include "src/gpu/d3d/GrD3DBuffer.h"
14 #include "src/gpu/d3d/GrD3DCommandSignature.h"
15 #include "src/gpu/d3d/GrD3DGpu.h"
16 #include "src/gpu/d3d/GrD3DPipeline.h"
17 #include "src/gpu/d3d/GrD3DRenderTarget.h"
18 #include "src/gpu/d3d/GrD3DTexture.h"
19 #include "src/gpu/d3d/GrD3DTextureResource.h"
20 #include "src/gpu/d3d/GrD3DUtil.h"
21 
GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,gr_cp<ID3D12GraphicsCommandList> commandList)22 GrD3DCommandList::GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
23                                    gr_cp<ID3D12GraphicsCommandList> commandList)
24     : fCommandList(std::move(commandList))
25     , fAllocator(std::move(allocator)) {
26 }
27 
close()28 bool GrD3DCommandList::close() {
29     SkASSERT(fIsActive);
30     this->submitResourceBarriers();
31     HRESULT hr = fCommandList->Close();
32     SkDEBUGCODE(fIsActive = false;)
33     return SUCCEEDED(hr);
34 }
35 
submit(ID3D12CommandQueue * queue)36 GrD3DCommandList::SubmitResult GrD3DCommandList::submit(ID3D12CommandQueue* queue) {
37     SkASSERT(fIsActive);
38     if (!this->hasWork()) {
39         this->callFinishedCallbacks();
40         return SubmitResult::kNoWork;
41     }
42 
43     if (!this->close()) {
44         return SubmitResult::kFailure;
45     }
46     SkASSERT(!fIsActive);
47     ID3D12CommandList* ppCommandLists[] = { fCommandList.get() };
48     queue->ExecuteCommandLists(1, ppCommandLists);
49 
50     return SubmitResult::kSuccess;
51 }
52 
reset()53 void GrD3DCommandList::reset() {
54     SkASSERT(!fIsActive);
55     GR_D3D_CALL_ERRCHECK(fAllocator->Reset());
56     GR_D3D_CALL_ERRCHECK(fCommandList->Reset(fAllocator.get(), nullptr));
57     this->onReset();
58 
59     this->releaseResources();
60 
61     SkDEBUGCODE(fIsActive = true;)
62     fHasWork = false;
63 }
64 
releaseResources()65 void GrD3DCommandList::releaseResources() {
66     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
67     if (fTrackedResources.count() == 0 && fTrackedRecycledResources.count() == 0) {
68         return;
69     }
70     SkASSERT(!fIsActive);
71     for (int i = 0; i < fTrackedRecycledResources.count(); ++i) {
72         auto resource = fTrackedRecycledResources[i].release();
73         resource->recycle();
74     }
75 
76     fTrackedResources.reset();
77     fTrackedRecycledResources.reset();
78     fTrackedGpuBuffers.reset();
79 
80     this->callFinishedCallbacks();
81 }
82 
addFinishedCallback(sk_sp<GrRefCntedCallback> callback)83 void GrD3DCommandList::addFinishedCallback(sk_sp<GrRefCntedCallback> callback) {
84     fFinishedCallbacks.push_back(std::move(callback));
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 // GraphicsCommandList commands
89 ////////////////////////////////////////////////////////////////////////////////
90 
resourceBarrier(sk_sp<GrManagedResource> resource,int numBarriers,const D3D12_RESOURCE_TRANSITION_BARRIER * barriers)91 void GrD3DCommandList::resourceBarrier(sk_sp<GrManagedResource> resource,
92                                        int numBarriers,
93                                        const D3D12_RESOURCE_TRANSITION_BARRIER* barriers) {
94     SkASSERT(fIsActive);
95     SkASSERT(barriers);
96     for (int i = 0; i < numBarriers; ++i) {
97         // D3D will apply barriers in order so we can just add onto the end
98         D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
99         newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
100         newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
101         newBarrier.Transition = barriers[i];
102     }
103 
104     fHasWork = true;
105     if (resource) {
106         this->addResource(std::move(resource));
107     }
108 }
109 
uavBarrier(sk_sp<GrManagedResource> resource,ID3D12Resource * uavResource)110 void GrD3DCommandList::uavBarrier(sk_sp<GrManagedResource> resource,
111                                   ID3D12Resource* uavResource) {
112     SkASSERT(fIsActive);
113     // D3D will apply barriers in order so we can just add onto the end
114     D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
115     newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
116     newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
117     newBarrier.UAV.pResource = uavResource;
118 
119     fHasWork = true;
120     if (resource) {
121         this->addResource(std::move(resource));
122     }
123 }
124 
aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,ID3D12Resource * beforeResource,sk_sp<GrManagedResource> afterManagedResource,ID3D12Resource * afterResource)125 void GrD3DCommandList::aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,
126                                        ID3D12Resource* beforeResource,
127                                        sk_sp<GrManagedResource> afterManagedResource,
128                                        ID3D12Resource* afterResource) {
129     SkASSERT(fIsActive);
130     // D3D will apply barriers in order so we can just add onto the end
131     D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
132     newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
133     newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
134     newBarrier.Aliasing.pResourceBefore = beforeResource;
135     newBarrier.Aliasing.pResourceAfter = afterResource;
136 
137     fHasWork = true;
138     if (beforeResource) {
139         SkASSERT(beforeManagedResource);
140         this->addResource(std::move(beforeManagedResource));
141     }
142     // Aliasing barriers can accept a null pointer for the second resource,
143     // but at this point we're not using that feature.
144     SkASSERT(afterResource);
145     SkASSERT(afterManagedResource);
146     this->addResource(std::move(afterManagedResource));
147 }
148 
submitResourceBarriers()149 void GrD3DCommandList::submitResourceBarriers() {
150     SkASSERT(fIsActive);
151 
152     if (fResourceBarriers.count()) {
153         fCommandList->ResourceBarrier(fResourceBarriers.count(), fResourceBarriers.begin());
154         fResourceBarriers.reset();
155     }
156     SkASSERT(!fResourceBarriers.count());
157 }
158 
copyBufferToTexture(ID3D12Resource * srcBuffer,const GrD3DTextureResource * dstTexture,uint32_t subresourceCount,D3D12_PLACED_SUBRESOURCE_FOOTPRINT * bufferFootprints,int left,int top)159 void GrD3DCommandList::copyBufferToTexture(ID3D12Resource* srcBuffer,
160                                            const GrD3DTextureResource* dstTexture,
161                                            uint32_t subresourceCount,
162                                            D3D12_PLACED_SUBRESOURCE_FOOTPRINT* bufferFootprints,
163                                            int left, int top) {
164     SkASSERT(fIsActive);
165     SkASSERT(subresourceCount == 1 || (left == 0 && top == 0));
166 
167     this->addingWork();
168     this->addResource(dstTexture->resource());
169 
170     for (uint32_t subresource = 0; subresource < subresourceCount; ++subresource) {
171         D3D12_TEXTURE_COPY_LOCATION src = {};
172         src.pResource = srcBuffer;
173         src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
174         src.PlacedFootprint = bufferFootprints[subresource];
175 
176         D3D12_TEXTURE_COPY_LOCATION dst = {};
177         dst.pResource = dstTexture->d3dResource();
178         dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
179         dst.SubresourceIndex = subresource;
180 
181         fCommandList->CopyTextureRegion(&dst, left, top, 0, &src, nullptr);
182     }
183 }
184 
copyTextureRegionToTexture(sk_sp<GrManagedResource> dst,const D3D12_TEXTURE_COPY_LOCATION * dstLocation,UINT dstX,UINT dstY,sk_sp<GrManagedResource> src,const D3D12_TEXTURE_COPY_LOCATION * srcLocation,const D3D12_BOX * srcBox)185 void GrD3DCommandList::copyTextureRegionToTexture(sk_sp<GrManagedResource> dst,
186                                                   const D3D12_TEXTURE_COPY_LOCATION* dstLocation,
187                                                   UINT dstX, UINT dstY,
188                                                   sk_sp<GrManagedResource> src,
189                                                   const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
190                                                   const D3D12_BOX* srcBox) {
191     SkASSERT(fIsActive);
192     SkASSERT(dst);
193     this->addingWork();
194     this->addResource(dst);
195     this->addResource(std::move(src));
196     fCommandList->CopyTextureRegion(dstLocation, dstX, dstY, 0, srcLocation, srcBox);
197 }
198 
copyTextureRegionToBuffer(sk_sp<const GrBuffer> dst,const D3D12_TEXTURE_COPY_LOCATION * dstLocation,UINT dstX,UINT dstY,sk_sp<GrManagedResource> src,const D3D12_TEXTURE_COPY_LOCATION * srcLocation,const D3D12_BOX * srcBox)199 void GrD3DCommandList::copyTextureRegionToBuffer(sk_sp<const GrBuffer> dst,
200                                                  const D3D12_TEXTURE_COPY_LOCATION* dstLocation,
201                                                  UINT dstX,
202                                                  UINT dstY,
203                                                  sk_sp<GrManagedResource> src,
204                                                  const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
205                                                  const D3D12_BOX* srcBox) {
206     SkASSERT(fIsActive);
207     SkASSERT(dst);
208     this->addingWork();
209     this->addGrBuffer(std::move(dst));
210     this->addResource(std::move(src));
211     fCommandList->CopyTextureRegion(dstLocation, dstX, dstY, 0, srcLocation, srcBox);
212 }
213 
214 
copyTextureToTexture(const GrD3DTexture * dst,const GrD3DTexture * src,UINT subresourceIndex)215 void GrD3DCommandList::copyTextureToTexture(const GrD3DTexture* dst, const GrD3DTexture* src,
216                                             UINT subresourceIndex) {
217     SkASSERT(fIsActive);
218     SkASSERT(src);
219     SkASSERT(dst);
220     SkASSERT(src->width() == dst->width() && src->height() == dst->height());
221 
222     this->addingWork();
223     ID3D12Resource* dstTexture = dst->d3dResource();
224     ID3D12Resource* srcTexture = src->d3dResource();
225     if (subresourceIndex == (UINT)-1) {
226         fCommandList->CopyResource(dstTexture, srcTexture);
227     } else {
228         SkASSERT(subresourceIndex < src->mipLevels() &&
229                  subresourceIndex < dst->mipLevels());
230         D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
231         srcLoc.pResource = srcTexture;
232         srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
233         srcLoc.SubresourceIndex = subresourceIndex;
234 
235         D3D12_TEXTURE_COPY_LOCATION dstLoc = {};
236         dstLoc.pResource = dstTexture;
237         dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
238         dstLoc.SubresourceIndex = subresourceIndex;
239 
240         fCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
241     }
242     this->addResource(dst->resource());
243     this->addResource(src->resource());
244 }
245 
copyBufferToBuffer(sk_sp<GrD3DBuffer> dst,uint64_t dstOffset,ID3D12Resource * srcBuffer,uint64_t srcOffset,uint64_t numBytes)246 void GrD3DCommandList::copyBufferToBuffer(sk_sp<GrD3DBuffer> dst, uint64_t dstOffset,
247                                           ID3D12Resource* srcBuffer, uint64_t srcOffset,
248                                           uint64_t numBytes) {
249     SkASSERT(fIsActive);
250 
251     this->addingWork();
252     ID3D12Resource* dstBuffer = dst->d3dResource();
253     uint64_t dstSize = dstBuffer->GetDesc().Width;
254     uint64_t srcSize = srcBuffer->GetDesc().Width;
255     if (dstSize == srcSize && srcSize == numBytes) {
256         fCommandList->CopyResource(dstBuffer, srcBuffer);
257     } else {
258         fCommandList->CopyBufferRegion(dstBuffer, dstOffset, srcBuffer, srcOffset, numBytes);
259     }
260     this->addGrBuffer(std::move(dst));
261 }
262 
addingWork()263 void GrD3DCommandList::addingWork() {
264     this->submitResourceBarriers();
265     fHasWork = true;
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////////////////////////
269 
Make(GrD3DGpu * gpu)270 std::unique_ptr<GrD3DDirectCommandList> GrD3DDirectCommandList::Make(GrD3DGpu* gpu) {
271     ID3D12Device* device = gpu->device();
272     gr_cp<ID3D12CommandAllocator> allocator;
273     GR_D3D_CALL_ERRCHECK(device->CreateCommandAllocator(
274                          D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)));
275 
276     gr_cp<ID3D12GraphicsCommandList> commandList;
277     GR_D3D_CALL_ERRCHECK(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
278                                                    allocator.get(), nullptr,
279                                                    IID_PPV_ARGS(&commandList)));
280 
281     auto grCL = new GrD3DDirectCommandList(std::move(allocator), std::move(commandList),
282                                            gpu->d3dCaps().resolveSubresourceRegionSupport());
283     return std::unique_ptr<GrD3DDirectCommandList>(grCL);
284 }
285 
GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,gr_cp<ID3D12GraphicsCommandList> commandList,bool resolveSubregionSupported)286 GrD3DDirectCommandList::GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
287                                                gr_cp<ID3D12GraphicsCommandList> commandList,
288                                                bool resolveSubregionSupported)
289     : GrD3DCommandList(std::move(allocator), std::move(commandList))
290     , fResolveSubregionSupported(resolveSubregionSupported) {
291     sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
292     sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
293 }
294 
onReset()295 void GrD3DDirectCommandList::onReset() {
296     fCurrentPipeline = nullptr;
297     fCurrentGraphicsRootSignature = nullptr;
298     fCurrentComputeRootSignature = nullptr;
299     fCurrentVertexBuffer = nullptr;
300     fCurrentVertexStride = 0;
301     fCurrentInstanceBuffer = nullptr;
302     fCurrentInstanceStride = 0;
303     fCurrentIndexBuffer = nullptr;
304     fCurrentGraphicsConstantBufferAddress = 0;
305     fCurrentComputeConstantBufferAddress = 0;
306     sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
307     sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
308     fCurrentSRVCRVDescriptorHeap = nullptr;
309     fCurrentSamplerDescriptorHeap = nullptr;
310 }
311 
setPipelineState(const sk_sp<GrD3DPipeline> & pipeline)312 void GrD3DDirectCommandList::setPipelineState(const sk_sp<GrD3DPipeline>& pipeline) {
313     SkASSERT(fIsActive);
314     if (pipeline.get() != fCurrentPipeline) {
315         fCommandList->SetPipelineState(pipeline->d3dPipelineState());
316         this->addResource(std::move(pipeline));
317         fCurrentPipeline = pipeline.get();
318     }
319 }
320 
setStencilRef(unsigned int stencilRef)321 void GrD3DDirectCommandList::setStencilRef(unsigned int stencilRef) {
322     SkASSERT(fIsActive);
323     fCommandList->OMSetStencilRef(stencilRef);
324 }
325 
setBlendFactor(const float blendFactor[4])326 void GrD3DDirectCommandList::setBlendFactor(const float blendFactor[4]) {
327     SkASSERT(fIsActive);
328     fCommandList->OMSetBlendFactor(blendFactor);
329 }
330 
setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology)331 void GrD3DDirectCommandList::setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology) {
332     SkASSERT(fIsActive);
333     fCommandList->IASetPrimitiveTopology(primitiveTopology);
334 }
335 
setScissorRects(unsigned int numRects,const D3D12_RECT * rects)336 void GrD3DDirectCommandList::setScissorRects(unsigned int numRects, const D3D12_RECT* rects) {
337     SkASSERT(fIsActive);
338     fCommandList->RSSetScissorRects(numRects, rects);
339 }
340 
setViewports(unsigned int numViewports,const D3D12_VIEWPORT * viewports)341 void GrD3DDirectCommandList::setViewports(unsigned int numViewports,
342                                           const D3D12_VIEWPORT* viewports) {
343     SkASSERT(fIsActive);
344     fCommandList->RSSetViewports(numViewports, viewports);
345 }
346 
setGraphicsRootSignature(const sk_sp<GrD3DRootSignature> & rootSig)347 void GrD3DDirectCommandList::setGraphicsRootSignature(const sk_sp<GrD3DRootSignature>& rootSig) {
348     SkASSERT(fIsActive);
349     if (fCurrentGraphicsRootSignature != rootSig.get()) {
350         fCommandList->SetGraphicsRootSignature(rootSig->rootSignature());
351         this->addResource(rootSig);
352         fCurrentGraphicsRootSignature = rootSig.get();
353         // need to reset the current descriptor tables as well
354         sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
355     }
356 }
357 
setComputeRootSignature(const sk_sp<GrD3DRootSignature> & rootSig)358 void GrD3DDirectCommandList::setComputeRootSignature(const sk_sp<GrD3DRootSignature>& rootSig) {
359     SkASSERT(fIsActive);
360     if (fCurrentComputeRootSignature != rootSig.get()) {
361         fCommandList->SetComputeRootSignature(rootSig->rootSignature());
362         this->addResource(rootSig);
363         fCurrentComputeRootSignature = rootSig.get();
364         // need to reset the current descriptor tables as well
365         sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
366     }
367 }
368 
setVertexBuffers(unsigned int startSlot,sk_sp<const GrBuffer> vertexBuffer,size_t vertexStride,sk_sp<const GrBuffer> instanceBuffer,size_t instanceStride)369 void GrD3DDirectCommandList::setVertexBuffers(unsigned int startSlot,
370                                               sk_sp<const GrBuffer> vertexBuffer,
371                                               size_t vertexStride,
372                                               sk_sp<const GrBuffer> instanceBuffer,
373                                               size_t instanceStride) {
374     if (fCurrentVertexBuffer != vertexBuffer.get() ||
375         fCurrentVertexStride != vertexStride ||
376         fCurrentInstanceBuffer != instanceBuffer.get() ||
377         fCurrentInstanceStride != instanceStride) {
378 
379         fCurrentVertexBuffer = vertexBuffer.get();
380         fCurrentVertexStride = vertexStride;
381         fCurrentInstanceBuffer = instanceBuffer.get();
382         fCurrentInstanceStride = instanceStride;
383 
384         D3D12_VERTEX_BUFFER_VIEW views[2];
385         int numViews = 0;
386         if (vertexBuffer) {
387             auto* d3dBuffer = static_cast<const GrD3DBuffer*>(vertexBuffer.get());
388             views[numViews].BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
389             views[numViews].SizeInBytes = vertexBuffer->size();
390             views[numViews++].StrideInBytes = vertexStride;
391             this->addGrBuffer(std::move(vertexBuffer));
392         }
393         if (instanceBuffer) {
394             auto* d3dBuffer = static_cast<const GrD3DBuffer*>(instanceBuffer.get());
395             views[numViews].BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
396             views[numViews].SizeInBytes = instanceBuffer->size();
397             views[numViews++].StrideInBytes = instanceStride;
398             this->addGrBuffer(std::move(instanceBuffer));
399         }
400         fCommandList->IASetVertexBuffers(startSlot, numViews, views);
401     }
402 }
403 
setIndexBuffer(sk_sp<const GrBuffer> indexBuffer)404 void GrD3DDirectCommandList::setIndexBuffer(sk_sp<const GrBuffer> indexBuffer) {
405     if (fCurrentIndexBuffer != indexBuffer.get()) {
406         auto* d3dBuffer = static_cast<const GrD3DBuffer*>(indexBuffer.get());
407 
408         D3D12_INDEX_BUFFER_VIEW view = {};
409         view.BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
410         view.SizeInBytes = indexBuffer->size();
411         view.Format = DXGI_FORMAT_R16_UINT;
412         fCommandList->IASetIndexBuffer(&view);
413 
414         fCurrentIndexBuffer = indexBuffer.get();
415         this->addGrBuffer(std::move(indexBuffer));
416     }
417 }
418 
drawInstanced(unsigned int vertexCount,unsigned int instanceCount,unsigned int startVertex,unsigned int startInstance)419 void GrD3DDirectCommandList::drawInstanced(unsigned int vertexCount, unsigned int instanceCount,
420                                            unsigned int startVertex, unsigned int startInstance) {
421     SkASSERT(fIsActive);
422     this->addingWork();
423     fCommandList->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
424 }
425 
drawIndexedInstanced(unsigned int indexCount,unsigned int instanceCount,unsigned int startIndex,unsigned int baseVertex,unsigned int startInstance)426 void GrD3DDirectCommandList::drawIndexedInstanced(unsigned int indexCount,
427                                                   unsigned int instanceCount,
428                                                   unsigned int startIndex,
429                                                   unsigned int baseVertex,
430                                                   unsigned int startInstance) {
431     SkASSERT(fIsActive);
432     this->addingWork();
433     fCommandList->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex,
434                                        startInstance);
435 }
436 
executeIndirect(const sk_sp<GrD3DCommandSignature> commandSignature,unsigned int maxCommandCount,const GrD3DBuffer * argumentBuffer,size_t argumentBufferOffset)437 void GrD3DDirectCommandList::executeIndirect(const sk_sp<GrD3DCommandSignature> commandSignature,
438                                              unsigned int maxCommandCount,
439                                              const GrD3DBuffer* argumentBuffer,
440                                              size_t argumentBufferOffset) {
441     SkASSERT(fIsActive);
442     this->addingWork();
443     this->addResource(commandSignature);
444     fCommandList->ExecuteIndirect(commandSignature->commandSignature(), maxCommandCount,
445                                   argumentBuffer->d3dResource(), argumentBufferOffset,
446                                   nullptr, 0);
447     this->addGrBuffer(sk_ref_sp<const GrBuffer>(argumentBuffer));
448 }
449 
450 
dispatch(unsigned int threadGroupCountX,unsigned int threadGroupCountY,unsigned int threadGroupCountZ)451 void GrD3DDirectCommandList::dispatch(unsigned int threadGroupCountX,
452                                       unsigned int threadGroupCountY,
453                                       unsigned int threadGroupCountZ) {
454     SkASSERT(fIsActive);
455     this->addingWork();
456     fCommandList->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
457 }
458 
clearRenderTargetView(const GrD3DRenderTarget * renderTarget,std::array<float,4> color,const D3D12_RECT * rect)459 void GrD3DDirectCommandList::clearRenderTargetView(const GrD3DRenderTarget* renderTarget,
460                                                    std::array<float, 4> color,
461                                                    const D3D12_RECT* rect) {
462     this->addingWork();
463     this->addResource(renderTarget->resource());
464     const GrD3DTextureResource* msaaTextureResource = renderTarget->msaaTextureResource();
465     if (msaaTextureResource && msaaTextureResource != renderTarget) {
466         this->addResource(msaaTextureResource->resource());
467     }
468     unsigned int numRects = rect ? 1 : 0;
469     fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(), color.data(),
470                                         numRects, rect);
471 }
472 
clearDepthStencilView(const GrD3DAttachment * stencil,uint8_t stencilClearValue,const D3D12_RECT * rect)473 void GrD3DDirectCommandList::clearDepthStencilView(const GrD3DAttachment* stencil,
474                                                    uint8_t stencilClearValue,
475                                                    const D3D12_RECT* rect) {
476     this->addingWork();
477     this->addResource(stencil->resource());
478     unsigned int numRects = rect ? 1 : 0;
479     fCommandList->ClearDepthStencilView(stencil->view(), D3D12_CLEAR_FLAG_STENCIL, 0,
480                                         stencilClearValue, numRects, rect);
481 }
482 
setRenderTarget(const GrD3DRenderTarget * renderTarget)483 void GrD3DDirectCommandList::setRenderTarget(const GrD3DRenderTarget* renderTarget) {
484     this->addingWork();
485     this->addResource(renderTarget->resource());
486     const GrD3DTextureResource* msaaTextureResource = renderTarget->msaaTextureResource();
487     if (msaaTextureResource && msaaTextureResource != renderTarget) {
488         this->addResource(msaaTextureResource->resource());
489     }
490     D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = renderTarget->colorRenderTargetView();
491 
492     D3D12_CPU_DESCRIPTOR_HANDLE dsDescriptor;
493     D3D12_CPU_DESCRIPTOR_HANDLE* dsDescriptorPtr = nullptr;
494     if (auto stencil = renderTarget->getStencilAttachment()) {
495         GrD3DAttachment* d3dStencil = static_cast<GrD3DAttachment*>(stencil);
496         this->addResource(d3dStencil->resource());
497         dsDescriptor = d3dStencil->view();
498         dsDescriptorPtr = &dsDescriptor;
499     }
500 
501     fCommandList->OMSetRenderTargets(1, &rtvDescriptor, false, dsDescriptorPtr);
502 }
503 
resolveSubresourceRegion(const GrD3DTextureResource * dstTexture,unsigned int dstX,unsigned int dstY,const GrD3DTextureResource * srcTexture,D3D12_RECT * srcRect)504 void GrD3DDirectCommandList::resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
505                                                       unsigned int dstX, unsigned int dstY,
506                                                       const GrD3DTextureResource* srcTexture,
507                                                       D3D12_RECT* srcRect) {
508     SkASSERT(dstTexture->dxgiFormat() == srcTexture->dxgiFormat());
509     SkASSERT(dstTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_DEST);
510     SkASSERT(srcTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
511     this->addingWork();
512     this->addResource(dstTexture->resource());
513     this->addResource(srcTexture->resource());
514 
515     if (fResolveSubregionSupported) {
516         gr_cp<ID3D12GraphicsCommandList1> commandList1;
517         HRESULT result = fCommandList->QueryInterface(IID_PPV_ARGS(&commandList1));
518         if (SUCCEEDED(result)) {
519             commandList1->ResolveSubresourceRegion(dstTexture->d3dResource(), 0, dstX, dstY,
520                                                    srcTexture->d3dResource(), 0, srcRect,
521                                                    srcTexture->dxgiFormat(),
522                                                    D3D12_RESOLVE_MODE_AVERAGE);
523             return;
524         }
525     }
526 
527     fCommandList->ResolveSubresource(dstTexture->d3dResource(), 0, srcTexture->d3dResource(), 0,
528                                      srcTexture->dxgiFormat());
529 }
530 
setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)531 void GrD3DDirectCommandList::setGraphicsRootConstantBufferView(
532         unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
533     SkASSERT(rootParameterIndex ==
534                 (unsigned int) GrD3DRootSignature::ParamIndex::kConstantBufferView);
535     if (bufferLocation != fCurrentGraphicsConstantBufferAddress) {
536         fCommandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);
537         fCurrentGraphicsConstantBufferAddress = bufferLocation;
538     }
539 }
540 
setComputeRootConstantBufferView(unsigned int rootParameterIndex,D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)541 void GrD3DDirectCommandList::setComputeRootConstantBufferView(
542     unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
543     SkASSERT(rootParameterIndex ==
544              (unsigned int)GrD3DRootSignature::ParamIndex::kConstantBufferView);
545     if (bufferLocation != fCurrentComputeConstantBufferAddress) {
546         fCommandList->SetComputeRootConstantBufferView(rootParameterIndex, bufferLocation);
547         fCurrentComputeConstantBufferAddress = bufferLocation;
548     }
549 }
550 
setGraphicsRootDescriptorTable(unsigned int rootParameterIndex,D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor)551 void GrD3DDirectCommandList::setGraphicsRootDescriptorTable(
552         unsigned int rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor) {
553     SkASSERT(rootParameterIndex ==
554                     (unsigned int)GrD3DRootSignature::ParamIndex::kSamplerDescriptorTable ||
555              rootParameterIndex ==
556                     (unsigned int)GrD3DRootSignature::ParamIndex::kShaderViewDescriptorTable);
557     if (fCurrentGraphicsRootDescTable[rootParameterIndex].ptr != baseDescriptor.ptr) {
558         fCommandList->SetGraphicsRootDescriptorTable(rootParameterIndex, baseDescriptor);
559         fCurrentGraphicsRootDescTable[rootParameterIndex] = baseDescriptor;
560     }
561 }
562 
setComputeRootDescriptorTable(unsigned int rootParameterIndex,D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor)563 void GrD3DDirectCommandList::setComputeRootDescriptorTable(
564     unsigned int rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor) {
565     SkASSERT(rootParameterIndex ==
566              (unsigned int)GrD3DRootSignature::ParamIndex::kSamplerDescriptorTable ||
567              rootParameterIndex ==
568              (unsigned int)GrD3DRootSignature::ParamIndex::kShaderViewDescriptorTable);
569     if (fCurrentComputeRootDescTable[rootParameterIndex].ptr != baseDescriptor.ptr) {
570         fCommandList->SetComputeRootDescriptorTable(rootParameterIndex, baseDescriptor);
571         fCurrentComputeRootDescTable[rootParameterIndex] = baseDescriptor;
572     }
573 }
574 
575 // We don't need to add these resources to the command list.
576 // They're added when we first allocate from a heap in a given submit.
setDescriptorHeaps(ID3D12DescriptorHeap * srvCrvDescriptorHeap,ID3D12DescriptorHeap * samplerDescriptorHeap)577 void GrD3DDirectCommandList::setDescriptorHeaps(ID3D12DescriptorHeap* srvCrvDescriptorHeap,
578                                                 ID3D12DescriptorHeap* samplerDescriptorHeap) {
579     if (srvCrvDescriptorHeap != fCurrentSRVCRVDescriptorHeap ||
580         samplerDescriptorHeap != fCurrentSamplerDescriptorHeap) {
581         ID3D12DescriptorHeap* heaps[2] = {
582             srvCrvDescriptorHeap,
583             samplerDescriptorHeap
584         };
585 
586         fCommandList->SetDescriptorHeaps(2, heaps);
587         fCurrentSRVCRVDescriptorHeap = srvCrvDescriptorHeap;
588         fCurrentSamplerDescriptorHeap = samplerDescriptorHeap;
589     }
590 }
591 
addSampledTextureRef(GrD3DTexture * texture)592 void GrD3DDirectCommandList::addSampledTextureRef(GrD3DTexture* texture) {
593     this->addResource(texture->resource());
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////////////////////////
597 
Make(GrD3DGpu * gpu)598 std::unique_ptr<GrD3DCopyCommandList> GrD3DCopyCommandList::Make(GrD3DGpu* gpu) {
599     ID3D12Device* device = gpu->device();
600     gr_cp<ID3D12CommandAllocator> allocator;
601     GR_D3D_CALL_ERRCHECK(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
602                                                         IID_PPV_ARGS(&allocator)));
603 
604     gr_cp<ID3D12GraphicsCommandList> commandList;
605     GR_D3D_CALL_ERRCHECK(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, allocator.get(),
606                                                    nullptr, IID_PPV_ARGS(&commandList)));
607     auto grCL = new GrD3DCopyCommandList(std::move(allocator), std::move(commandList));
608     return std::unique_ptr<GrD3DCopyCommandList>(grCL);
609 }
610 
GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,gr_cp<ID3D12GraphicsCommandList> commandList)611 GrD3DCopyCommandList::GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,
612                                            gr_cp<ID3D12GraphicsCommandList> commandList)
613     : GrD3DCommandList(std::move(allocator), std::move(commandList)) {
614 }
615