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