From 4105e457524fe3d08efded6e59e8e2a7fa68a115 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Tue, 24 Mar 2020 16:08:39 -0400 Subject: [PATCH] Add support for tracking resources on d3d command list. Change-Id: I9f1db0d099d2071af0028a3c1e563671b4b2b18c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/278860 Reviewed-by: Jim Van Verth Commit-Queue: Greg Daniel --- src/gpu/d3d/GrD3DCommandList.cpp | 38 ++++++++++++++++++++++++++++---- src/gpu/d3d/GrD3DCommandList.h | 37 ++++++++++++++++++++++++++++++- src/gpu/vk/GrVkCommandBuffer.cpp | 1 - src/gpu/vk/GrVkCommandBuffer.h | 3 --- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/gpu/d3d/GrD3DCommandList.cpp b/src/gpu/d3d/GrD3DCommandList.cpp index c57ace7c7f..be62ac5de9 100644 --- a/src/gpu/d3d/GrD3DCommandList.cpp +++ b/src/gpu/d3d/GrD3DCommandList.cpp @@ -11,25 +11,55 @@ GrD3DCommandList::GrD3DCommandList(gr_cp allocator, gr_cp commandList) - : fAllocator(std::move(allocator)) - , fCommandList(std::move(commandList)) { + : fCommandList(std::move(commandList)) + , fAllocator(std::move(allocator)) { } void GrD3DCommandList::close() { + SkASSERT(fIsActive); SkDEBUGCODE(HRESULT hr = ) fCommandList->Close(); SkASSERT(SUCCEEDED(hr)); + SkDEBUGCODE(fIsActive = false;) } void GrD3DCommandList::submit(ID3D12CommandQueue* queue) { + SkASSERT(!fIsActive); ID3D12CommandList* ppCommandLists[] = { fCommandList.Get() }; queue->ExecuteCommandLists(1, ppCommandLists); - SkDEBUGCODE(HRESULT hr = ) fCommandList->Reset(fAllocator.Get(), nullptr); - SkASSERT(SUCCEEDED(hr)); } void GrD3DCommandList::reset() { + SkASSERT(!fIsActive); SkDEBUGCODE(HRESULT hr = ) fAllocator->Reset(); SkASSERT(SUCCEEDED(hr)); + SkDEBUGCODE(hr = ) fCommandList->Reset(fAllocator.Get(), nullptr); + SkASSERT(SUCCEEDED(hr)); + + SkDEBUGCODE(fIsActive = true;) +} + +void GrD3DCommandList::releaseResources() { + TRACE_EVENT0("skia.gpu", TRACE_FUNC); + SkASSERT(!fIsActive); + for (int i = 0; i < fTrackedResources.count(); ++i) { + fTrackedResources[i]->notifyFinishedWithWorkOnGpu(); + fTrackedResources[i]->unref(); + } + for (int i = 0; i < fTrackedRecycledResources.count(); ++i) { + fTrackedRecycledResources[i]->notifyFinishedWithWorkOnGpu(); + fTrackedRecycledResources[i]->recycle(); + } + + if (++fNumResets > kNumRewindResetsBeforeFullReset) { + fTrackedResources.reset(); + fTrackedRecycledResources.reset(); + fTrackedResources.setReserve(kInitialTrackedResourcesCount); + fTrackedRecycledResources.setReserve(kInitialTrackedResourcesCount); + fNumResets = 0; + } else { + fTrackedResources.rewind(); + fTrackedRecycledResources.rewind(); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/d3d/GrD3DCommandList.h b/src/gpu/d3d/GrD3DCommandList.h index 22639d78fd..4aa1ab496f 100644 --- a/src/gpu/d3d/GrD3DCommandList.h +++ b/src/gpu/d3d/GrD3DCommandList.h @@ -9,6 +9,7 @@ #define GrD3DCommandList_DEFINED #include "include/gpu/GrTypes.h" +#include "src/gpu/GrManagedResource.h" #include "src/gpu/d3d/GrD3D12.h" #include @@ -23,13 +24,47 @@ public: void reset(); + // Add ref-counted resource that will be tracked and released when this command buffer finishes + // execution + void addResource(const GrManagedResource* resource) { + SkASSERT(resource); + resource->ref(); + resource->notifyQueuedForWorkOnGpu(); + fTrackedResources.append(1, &resource); + } + + // Add ref-counted resource that will be tracked and released when this command buffer finishes + // execution. When it is released, it will signal that the resource can be recycled for reuse. + void addRecycledResource(const GrRecycledResource* resource) { + resource->ref(); + resource->notifyQueuedForWorkOnGpu(); + fTrackedRecycledResources.append(1, &resource); + } + + void releaseResources(); + protected: GrD3DCommandList(gr_cp allocator, gr_cp commandList); + gr_cp fCommandList; + + SkTDArray fTrackedResources; + SkTDArray fTrackedRecycledResources; + + // When we create a command list it starts in an active recording state + SkDEBUGCODE(bool fIsActive = true;) + private: gr_cp fAllocator; - gr_cp fCommandList; + + static const int kInitialTrackedResourcesCount = 32; + // When resetting the command buffer, we remove the tracked resources from their arrays, and + // we prefer to not free all the memory every time so usually we just rewind. However, to avoid + // all arrays growing to the max size, after so many resets we'll do a full reset of the tracked + // resource arrays. + static const int kNumRewindResetsBeforeFullReset = 8; + int fNumResets = 0; }; class GrD3DDirectCommandList : public GrD3DCommandList { diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp index 9806f1aec4..c4f1d30ea5 100644 --- a/src/gpu/vk/GrVkCommandBuffer.cpp +++ b/src/gpu/vk/GrVkCommandBuffer.cpp @@ -56,7 +56,6 @@ void GrVkCommandBuffer::freeGPUData(const GrGpu* gpu, VkCommandPool cmdPool) con void GrVkCommandBuffer::releaseResources() { TRACE_EVENT0("skia.gpu", TRACE_FUNC); - SkDEBUGCODE(fResourcesReleased = true;) SkASSERT(!fIsActive); for (int i = 0; i < fTrackedResources.count(); ++i) { fTrackedResources[i]->notifyFinishedWithWorkOnGpu(); diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h index 4d8d6eaee0..e4e78618f6 100644 --- a/src/gpu/vk/GrVkCommandBuffer.h +++ b/src/gpu/vk/GrVkCommandBuffer.h @@ -170,9 +170,6 @@ private: VkRect2D fCachedScissor; float fCachedBlendConstant[4]; -#ifdef SK_DEBUG - mutable bool fResourcesReleased = false; -#endif // Tracking of memory barriers so that we can submit them all in a batch together. SkSTArray<4, VkBufferMemoryBarrier> fBufferBarriers; SkSTArray<1, VkImageMemoryBarrier> fImageBarriers;