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