• 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/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/GrD3DPipeline.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 
uavBarrier(sk_sp<GrManagedResource> resource,ID3D12Resource * uavResource)113 void GrD3DCommandList::uavBarrier(sk_sp<GrManagedResource> resource,
114                                   ID3D12Resource* uavResource) {
115     SkASSERT(fIsActive);
116     // D3D will apply barriers in order so we can just add onto the end
117     D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
118     newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
119     newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
120     newBarrier.UAV.pResource = uavResource;
121 
122     fHasWork = true;
123     if (resource) {
124         this->addResource(std::move(resource));
125     }
126 }
127 
aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,ID3D12Resource * beforeResource,sk_sp<GrManagedResource> afterManagedResource,ID3D12Resource * afterResource)128 void GrD3DCommandList::aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,
129                                        ID3D12Resource* beforeResource,
130                                        sk_sp<GrManagedResource> afterManagedResource,
131                                        ID3D12Resource* afterResource) {
132     SkASSERT(fIsActive);
133     // D3D will apply barriers in order so we can just add onto the end
134     D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
135     newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
136     newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
137     newBarrier.Aliasing.pResourceBefore = beforeResource;
138     newBarrier.Aliasing.pResourceAfter = afterResource;
139 
140     fHasWork = true;
141     // Aliasing barriers can accept a null pointer for one of the resources,
142     // but at this point we're not using that feature.
143     SkASSERT(beforeManagedResource);
144     this->addResource(std::move(beforeManagedResource));
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(ID3D12Device * device)270 std::unique_ptr<GrD3DDirectCommandList> GrD3DDirectCommandList::Make(ID3D12Device* device) {
271     gr_cp<ID3D12CommandAllocator> allocator;
272     GR_D3D_CALL_ERRCHECK(device->CreateCommandAllocator(
273                          D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)));
274 
275     gr_cp<ID3D12GraphicsCommandList> commandList;
276     GR_D3D_CALL_ERRCHECK(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
277                                                    allocator.get(), nullptr,
278                                                    IID_PPV_ARGS(&commandList)));
279 
280     auto grCL = new GrD3DDirectCommandList(std::move(allocator), std::move(commandList));
281     return std::unique_ptr<GrD3DDirectCommandList>(grCL);
282 }
283 
GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,gr_cp<ID3D12GraphicsCommandList> commandList)284 GrD3DDirectCommandList::GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
285                                                gr_cp<ID3D12GraphicsCommandList> commandList)
286     : GrD3DCommandList(std::move(allocator), std::move(commandList)) {
287     sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
288     sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
289 }
290 
onReset()291 void GrD3DDirectCommandList::onReset() {
292     fCurrentPipeline = nullptr;
293     fCurrentGraphicsRootSignature = nullptr;
294     fCurrentComputeRootSignature = nullptr;
295     fCurrentVertexBuffer = nullptr;
296     fCurrentVertexStride = 0;
297     fCurrentInstanceBuffer = nullptr;
298     fCurrentInstanceStride = 0;
299     fCurrentIndexBuffer = nullptr;
300     fCurrentGraphicsConstantBufferAddress = 0;
301     fCurrentComputeConstantBufferAddress = 0;
302     sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
303     sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
304     fCurrentSRVCRVDescriptorHeap = nullptr;
305     fCurrentSamplerDescriptorHeap = nullptr;
306 }
307 
setPipelineState(const sk_sp<GrD3DPipeline> & pipeline)308 void GrD3DDirectCommandList::setPipelineState(const sk_sp<GrD3DPipeline>& pipeline) {
309     SkASSERT(fIsActive);
310     if (pipeline.get() != fCurrentPipeline) {
311         fCommandList->SetPipelineState(pipeline->d3dPipelineState());
312         this->addResource(std::move(pipeline));
313         fCurrentPipeline = pipeline.get();
314         this->setDefaultSamplePositions();
315     }
316 }
317 
setStencilRef(unsigned int stencilRef)318 void GrD3DDirectCommandList::setStencilRef(unsigned int stencilRef) {
319     SkASSERT(fIsActive);
320     fCommandList->OMSetStencilRef(stencilRef);
321 }
322 
setBlendFactor(const float blendFactor[4])323 void GrD3DDirectCommandList::setBlendFactor(const float blendFactor[4]) {
324     SkASSERT(fIsActive);
325     fCommandList->OMSetBlendFactor(blendFactor);
326 }
327 
setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology)328 void GrD3DDirectCommandList::setPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitiveTopology) {
329     SkASSERT(fIsActive);
330     fCommandList->IASetPrimitiveTopology(primitiveTopology);
331 }
332 
setScissorRects(unsigned int numRects,const D3D12_RECT * rects)333 void GrD3DDirectCommandList::setScissorRects(unsigned int numRects, const D3D12_RECT* rects) {
334     SkASSERT(fIsActive);
335     fCommandList->RSSetScissorRects(numRects, rects);
336 }
337 
setViewports(unsigned int numViewports,const D3D12_VIEWPORT * viewports)338 void GrD3DDirectCommandList::setViewports(unsigned int numViewports,
339                                           const D3D12_VIEWPORT* viewports) {
340     SkASSERT(fIsActive);
341     fCommandList->RSSetViewports(numViewports, viewports);
342 }
343 
setCenteredSamplePositions(unsigned int numSamples)344 void GrD3DDirectCommandList::setCenteredSamplePositions(unsigned int numSamples) {
345     if (!fUsingCenteredSamples && numSamples > 1) {
346         gr_cp<ID3D12GraphicsCommandList1> commandList1;
347         GR_D3D_CALL_ERRCHECK(fCommandList->QueryInterface(IID_PPV_ARGS(&commandList1)));
348         static D3D12_SAMPLE_POSITION kCenteredSampleLocations[16] = {};
349         commandList1->SetSamplePositions(numSamples, 1, kCenteredSampleLocations);
350         fUsingCenteredSamples = true;
351     }
352 }
353 
setDefaultSamplePositions()354 void GrD3DDirectCommandList::setDefaultSamplePositions() {
355     if (fUsingCenteredSamples) {
356         gr_cp<ID3D12GraphicsCommandList1> commandList1;
357         GR_D3D_CALL_ERRCHECK(fCommandList->QueryInterface(IID_PPV_ARGS(&commandList1)));
358         commandList1->SetSamplePositions(0, 0, nullptr);
359         fUsingCenteredSamples = false;
360     }
361 }
362 
setGraphicsRootSignature(const sk_sp<GrD3DRootSignature> & rootSig)363 void GrD3DDirectCommandList::setGraphicsRootSignature(const sk_sp<GrD3DRootSignature>& rootSig) {
364     SkASSERT(fIsActive);
365     if (fCurrentGraphicsRootSignature != rootSig.get()) {
366         fCommandList->SetGraphicsRootSignature(rootSig->rootSignature());
367         this->addResource(rootSig);
368         fCurrentGraphicsRootSignature = rootSig.get();
369         // need to reset the current descriptor tables as well
370         sk_bzero(fCurrentGraphicsRootDescTable, sizeof(fCurrentGraphicsRootDescTable));
371     }
372 }
373 
setComputeRootSignature(const sk_sp<GrD3DRootSignature> & rootSig)374 void GrD3DDirectCommandList::setComputeRootSignature(const sk_sp<GrD3DRootSignature>& rootSig) {
375     SkASSERT(fIsActive);
376     if (fCurrentComputeRootSignature != rootSig.get()) {
377         fCommandList->SetComputeRootSignature(rootSig->rootSignature());
378         this->addResource(rootSig);
379         fCurrentComputeRootSignature = rootSig.get();
380         // need to reset the current descriptor tables as well
381         sk_bzero(fCurrentComputeRootDescTable, sizeof(fCurrentComputeRootDescTable));
382     }
383 }
384 
setVertexBuffers(unsigned int startSlot,sk_sp<const GrBuffer> vertexBuffer,size_t vertexStride,sk_sp<const GrBuffer> instanceBuffer,size_t instanceStride)385 void GrD3DDirectCommandList::setVertexBuffers(unsigned int startSlot,
386                                               sk_sp<const GrBuffer> vertexBuffer,
387                                               size_t vertexStride,
388                                               sk_sp<const GrBuffer> instanceBuffer,
389                                               size_t instanceStride) {
390     if (fCurrentVertexBuffer != vertexBuffer.get() ||
391         fCurrentVertexStride != vertexStride ||
392         fCurrentInstanceBuffer != instanceBuffer.get() ||
393         fCurrentInstanceStride != instanceStride) {
394 
395         fCurrentVertexBuffer = vertexBuffer.get();
396         fCurrentVertexStride = vertexStride;
397         fCurrentInstanceBuffer = instanceBuffer.get();
398         fCurrentInstanceStride = instanceStride;
399 
400         D3D12_VERTEX_BUFFER_VIEW views[2];
401         int numViews = 0;
402         if (vertexBuffer) {
403             auto* d3dBuffer = static_cast<const GrD3DBuffer*>(vertexBuffer.get());
404             views[numViews].BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
405             views[numViews].SizeInBytes = vertexBuffer->size();
406             views[numViews++].StrideInBytes = vertexStride;
407             this->addGrBuffer(std::move(vertexBuffer));
408         }
409         if (instanceBuffer) {
410             auto* d3dBuffer = static_cast<const GrD3DBuffer*>(instanceBuffer.get());
411             views[numViews].BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
412             views[numViews].SizeInBytes = instanceBuffer->size();
413             views[numViews++].StrideInBytes = instanceStride;
414             this->addGrBuffer(std::move(instanceBuffer));
415         }
416         fCommandList->IASetVertexBuffers(startSlot, numViews, views);
417     }
418 }
419 
setIndexBuffer(sk_sp<const GrBuffer> indexBuffer)420 void GrD3DDirectCommandList::setIndexBuffer(sk_sp<const GrBuffer> indexBuffer) {
421     if (fCurrentIndexBuffer != indexBuffer.get()) {
422         auto* d3dBuffer = static_cast<const GrD3DBuffer*>(indexBuffer.get());
423 
424         D3D12_INDEX_BUFFER_VIEW view = {};
425         view.BufferLocation = d3dBuffer->d3dResource()->GetGPUVirtualAddress();
426         view.SizeInBytes = indexBuffer->size();
427         view.Format = DXGI_FORMAT_R16_UINT;
428         fCommandList->IASetIndexBuffer(&view);
429 
430         fCurrentIndexBuffer = indexBuffer.get();
431         this->addGrBuffer(std::move(indexBuffer));
432     }
433 }
434 
drawInstanced(unsigned int vertexCount,unsigned int instanceCount,unsigned int startVertex,unsigned int startInstance)435 void GrD3DDirectCommandList::drawInstanced(unsigned int vertexCount, unsigned int instanceCount,
436                                            unsigned int startVertex, unsigned int startInstance) {
437     SkASSERT(fIsActive);
438     this->addingWork();
439     fCommandList->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
440 }
441 
drawIndexedInstanced(unsigned int indexCount,unsigned int instanceCount,unsigned int startIndex,unsigned int baseVertex,unsigned int startInstance)442 void GrD3DDirectCommandList::drawIndexedInstanced(unsigned int indexCount,
443                                                   unsigned int instanceCount,
444                                                   unsigned int startIndex,
445                                                   unsigned int baseVertex,
446                                                   unsigned int startInstance) {
447     SkASSERT(fIsActive);
448     this->addingWork();
449     fCommandList->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex,
450                                        startInstance);
451 }
452 
executeIndirect(const sk_sp<GrD3DCommandSignature> commandSignature,unsigned int maxCommandCount,const GrD3DBuffer * argumentBuffer,size_t argumentBufferOffset)453 void GrD3DDirectCommandList::executeIndirect(const sk_sp<GrD3DCommandSignature> commandSignature,
454                                              unsigned int maxCommandCount,
455                                              const GrD3DBuffer* argumentBuffer,
456                                              size_t argumentBufferOffset) {
457     SkASSERT(fIsActive);
458     this->addingWork();
459     this->addResource(commandSignature);
460     fCommandList->ExecuteIndirect(commandSignature->commandSignature(), maxCommandCount,
461                                   argumentBuffer->d3dResource(), argumentBufferOffset,
462                                   nullptr, 0);
463     this->addGrBuffer(sk_ref_sp<const GrBuffer>(argumentBuffer));
464 }
465 
466 
dispatch(unsigned int threadGroupCountX,unsigned int threadGroupCountY,unsigned int threadGroupCountZ)467 void GrD3DDirectCommandList::dispatch(unsigned int threadGroupCountX,
468                                       unsigned int threadGroupCountY,
469                                       unsigned int threadGroupCountZ) {
470     SkASSERT(fIsActive);
471     this->addingWork();
472     fCommandList->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
473 }
474 
clearRenderTargetView(const GrD3DRenderTarget * renderTarget,std::array<float,4> color,const D3D12_RECT * rect)475 void GrD3DDirectCommandList::clearRenderTargetView(const GrD3DRenderTarget* renderTarget,
476                                                    std::array<float, 4> color,
477                                                    const D3D12_RECT* rect) {
478     this->addingWork();
479     this->addResource(renderTarget->resource());
480     const GrD3DTextureResource* msaaTextureResource = renderTarget->msaaTextureResource();
481     if (msaaTextureResource && msaaTextureResource != renderTarget) {
482         this->addResource(msaaTextureResource->resource());
483     }
484     unsigned int numRects = rect ? 1 : 0;
485     fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(), color.data(),
486                                         numRects, rect);
487 }
488 
clearDepthStencilView(const GrD3DAttachment * stencil,uint8_t stencilClearValue,const D3D12_RECT * rect)489 void GrD3DDirectCommandList::clearDepthStencilView(const GrD3DAttachment* stencil,
490                                                    uint8_t stencilClearValue,
491                                                    const D3D12_RECT* rect) {
492     this->addingWork();
493     this->addResource(stencil->resource());
494     unsigned int numRects = rect ? 1 : 0;
495     fCommandList->ClearDepthStencilView(stencil->view(), D3D12_CLEAR_FLAG_STENCIL, 0,
496                                         stencilClearValue, numRects, rect);
497 }
498 
setRenderTarget(const GrD3DRenderTarget * renderTarget)499 void GrD3DDirectCommandList::setRenderTarget(const GrD3DRenderTarget* renderTarget) {
500     this->addingWork();
501     this->addResource(renderTarget->resource());
502     const GrD3DTextureResource* msaaTextureResource = renderTarget->msaaTextureResource();
503     if (msaaTextureResource && msaaTextureResource != renderTarget) {
504         this->addResource(msaaTextureResource->resource());
505     }
506     D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = renderTarget->colorRenderTargetView();
507 
508     D3D12_CPU_DESCRIPTOR_HANDLE dsDescriptor;
509     D3D12_CPU_DESCRIPTOR_HANDLE* dsDescriptorPtr = nullptr;
510     if (auto stencil = renderTarget->getStencilAttachment()) {
511         GrD3DAttachment* d3dStencil = static_cast<GrD3DAttachment*>(stencil);
512         this->addResource(d3dStencil->resource());
513         dsDescriptor = d3dStencil->view();
514         dsDescriptorPtr = &dsDescriptor;
515     }
516 
517     fCommandList->OMSetRenderTargets(1, &rtvDescriptor, false, dsDescriptorPtr);
518 }
519 
resolveSubresourceRegion(const GrD3DTextureResource * dstTexture,unsigned int dstX,unsigned int dstY,const GrD3DTextureResource * srcTexture,D3D12_RECT * srcRect)520 void GrD3DDirectCommandList::resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
521                                                       unsigned int dstX, unsigned int dstY,
522                                                       const GrD3DTextureResource* srcTexture,
523                                                       D3D12_RECT* srcRect) {
524     SkASSERT(dstTexture->dxgiFormat() == srcTexture->dxgiFormat());
525     SkASSERT(dstTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_DEST);
526     SkASSERT(srcTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
527     this->addingWork();
528     this->addResource(dstTexture->resource());
529     this->addResource(srcTexture->resource());
530 
531     gr_cp<ID3D12GraphicsCommandList1> commandList1;
532     HRESULT result = fCommandList->QueryInterface(IID_PPV_ARGS(&commandList1));
533     if (SUCCEEDED(result)) {
534         commandList1->ResolveSubresourceRegion(dstTexture->d3dResource(), 0, dstX, dstY,
535                                                srcTexture->d3dResource(), 0, srcRect,
536                                                srcTexture->dxgiFormat(),
537                                                D3D12_RESOLVE_MODE_AVERAGE);
538     } else {
539         fCommandList->ResolveSubresource(dstTexture->d3dResource(), 0, srcTexture->d3dResource(), 0,
540                                          srcTexture->dxgiFormat());
541     }
542 }
543 
setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)544 void GrD3DDirectCommandList::setGraphicsRootConstantBufferView(
545         unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
546     SkASSERT(rootParameterIndex ==
547                 (unsigned int) GrD3DRootSignature::ParamIndex::kConstantBufferView);
548     if (bufferLocation != fCurrentGraphicsConstantBufferAddress) {
549         fCommandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);
550         fCurrentGraphicsConstantBufferAddress = bufferLocation;
551     }
552 }
553 
setComputeRootConstantBufferView(unsigned int rootParameterIndex,D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)554 void GrD3DDirectCommandList::setComputeRootConstantBufferView(
555     unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
556     SkASSERT(rootParameterIndex ==
557              (unsigned int)GrD3DRootSignature::ParamIndex::kConstantBufferView);
558     if (bufferLocation != fCurrentComputeConstantBufferAddress) {
559         fCommandList->SetComputeRootConstantBufferView(rootParameterIndex, bufferLocation);
560         fCurrentComputeConstantBufferAddress = bufferLocation;
561     }
562 }
563 
setGraphicsRootDescriptorTable(unsigned int rootParameterIndex,D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor)564 void GrD3DDirectCommandList::setGraphicsRootDescriptorTable(
565         unsigned int rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor) {
566     SkASSERT(rootParameterIndex ==
567                     (unsigned int)GrD3DRootSignature::ParamIndex::kSamplerDescriptorTable ||
568              rootParameterIndex ==
569                     (unsigned int)GrD3DRootSignature::ParamIndex::kShaderViewDescriptorTable);
570     if (fCurrentGraphicsRootDescTable[rootParameterIndex].ptr != baseDescriptor.ptr) {
571         fCommandList->SetGraphicsRootDescriptorTable(rootParameterIndex, baseDescriptor);
572         fCurrentGraphicsRootDescTable[rootParameterIndex] = baseDescriptor;
573     }
574 }
575 
setComputeRootDescriptorTable(unsigned int rootParameterIndex,D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor)576 void GrD3DDirectCommandList::setComputeRootDescriptorTable(
577     unsigned int rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor) {
578     SkASSERT(rootParameterIndex ==
579              (unsigned int)GrD3DRootSignature::ParamIndex::kSamplerDescriptorTable ||
580              rootParameterIndex ==
581              (unsigned int)GrD3DRootSignature::ParamIndex::kShaderViewDescriptorTable);
582     if (fCurrentComputeRootDescTable[rootParameterIndex].ptr != baseDescriptor.ptr) {
583         fCommandList->SetComputeRootDescriptorTable(rootParameterIndex, baseDescriptor);
584         fCurrentComputeRootDescTable[rootParameterIndex] = baseDescriptor;
585     }
586 }
587 
setDescriptorHeaps(sk_sp<GrRecycledResource> srvCrvHeapResource,ID3D12DescriptorHeap * srvCrvDescriptorHeap,sk_sp<GrRecycledResource> samplerHeapResource,ID3D12DescriptorHeap * samplerDescriptorHeap)588 void GrD3DDirectCommandList::setDescriptorHeaps(sk_sp<GrRecycledResource> srvCrvHeapResource,
589                                                 ID3D12DescriptorHeap* srvCrvDescriptorHeap,
590                                                 sk_sp<GrRecycledResource> samplerHeapResource,
591                                                 ID3D12DescriptorHeap* samplerDescriptorHeap) {
592     if (srvCrvDescriptorHeap != fCurrentSRVCRVDescriptorHeap ||
593         samplerDescriptorHeap != fCurrentSamplerDescriptorHeap) {
594         ID3D12DescriptorHeap* heaps[2] = {
595             srvCrvDescriptorHeap,
596             samplerDescriptorHeap
597         };
598 
599         fCommandList->SetDescriptorHeaps(2, heaps);
600         this->addRecycledResource(std::move(srvCrvHeapResource));
601         this->addRecycledResource(std::move(samplerHeapResource));
602         fCurrentSRVCRVDescriptorHeap = srvCrvDescriptorHeap;
603         fCurrentSamplerDescriptorHeap = samplerDescriptorHeap;
604     }
605 }
606 
addSampledTextureRef(GrD3DTexture * texture)607 void GrD3DDirectCommandList::addSampledTextureRef(GrD3DTexture* texture) {
608     this->addResource(texture->resource());
609 }
610 
611 ////////////////////////////////////////////////////////////////////////////////////////////////////
612 
Make(ID3D12Device * device)613 std::unique_ptr<GrD3DCopyCommandList> GrD3DCopyCommandList::Make(ID3D12Device* device) {
614     gr_cp<ID3D12CommandAllocator> allocator;
615     GR_D3D_CALL_ERRCHECK(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
616                                                         IID_PPV_ARGS(&allocator)));
617 
618     gr_cp<ID3D12GraphicsCommandList> commandList;
619     GR_D3D_CALL_ERRCHECK(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, allocator.get(),
620                                                    nullptr, IID_PPV_ARGS(&commandList)));
621     auto grCL = new GrD3DCopyCommandList(std::move(allocator), std::move(commandList));
622     return std::unique_ptr<GrD3DCopyCommandList>(grCL);
623 }
624 
GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,gr_cp<ID3D12GraphicsCommandList> commandList)625 GrD3DCopyCommandList::GrD3DCopyCommandList(gr_cp<ID3D12CommandAllocator> allocator,
626                                            gr_cp<ID3D12GraphicsCommandList> commandList)
627     : GrD3DCommandList(std::move(allocator), std::move(commandList)) {
628 }
629