diff options
author | Greg Daniel <egdaniel@google.com> | 2018-06-19 15:22:01 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-20 13:37:28 +0000 |
commit | 7d918fde03d44011e7aac067227f88c4ba4cc3b8 (patch) | |
tree | 5f185edf442e4afff5c16bec75df4ad65d560082 | |
parent | 53418da8c64773fed8c927404a8f7e78e93e1c95 (diff) |
Don't destroy VkPipelineLayouts until after command buffer recording.
Bug: skia:
Change-Id: I70be1dc6b29db9a9152e008293a7d0a276384011
Reviewed-on: https://skia-review.googlesource.com/135867
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | gn/gpu.gni | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.cpp | 30 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.h | 17 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCopyManager.cpp | 25 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCopyManager.h | 3 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineLayout.cpp | 14 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineLayout.h | 38 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineState.cpp | 20 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineState.h | 3 |
9 files changed, 125 insertions, 27 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni index 40d7495afb..7e5dd625da 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -582,6 +582,8 @@ skia_vk_sources = [ "$_src/gpu/vk/GrVkMemory.h", "$_src/gpu/vk/GrVkPipeline.cpp", "$_src/gpu/vk/GrVkPipeline.h", + "$_src/gpu/vk/GrVkPipelineLayout.cpp", + "$_src/gpu/vk/GrVkPipelineLayout.h", "$_src/gpu/vk/GrVkPipelineState.cpp", "$_src/gpu/vk/GrVkPipelineState.h", "$_src/gpu/vk/GrVkPipelineStateBuilder.cpp", diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp index 2b6dde2f4b..caff3caba1 100644 --- a/src/gpu/vk/GrVkCommandBuffer.cpp +++ b/src/gpu/vk/GrVkCommandBuffer.cpp @@ -16,6 +16,7 @@ #include "GrVkPipelineState.h" #include "GrVkRenderPass.h" #include "GrVkRenderTarget.h" +#include "GrVkPipelineLayout.h" #include "GrVkPipelineState.h" #include "GrVkTransferBuffer.h" #include "GrVkUtil.h" @@ -49,6 +50,10 @@ void GrVkCommandBuffer::freeGPUData(const GrVkGpu* gpu) const { fTrackedRecycledResources[i]->recycle(const_cast<GrVkGpu*>(gpu)); } + for (int i = 0; i < fTrackedRecordingResources.count(); ++i) { + fTrackedRecordingResources[i]->unref(gpu); + } + GR_VK_CALL(gpu->vkInterface(), FreeCommandBuffers(gpu->device(), gpu->cmdPool(), 1, &fCmdBuffer)); @@ -64,6 +69,10 @@ void GrVkCommandBuffer::abandonGPUData() const { // We don't recycle resources when abandoning them. fTrackedRecycledResources[i]->unrefAndAbandon(); } + + for (int i = 0; i < fTrackedRecordingResources.count(); ++i) { + fTrackedRecordingResources[i]->unrefAndAbandon(); + } } void GrVkCommandBuffer::reset(GrVkGpu* gpu) { @@ -75,15 +84,22 @@ void GrVkCommandBuffer::reset(GrVkGpu* gpu) { fTrackedRecycledResources[i]->recycle(const_cast<GrVkGpu*>(gpu)); } + for (int i = 0; i < fTrackedRecordingResources.count(); ++i) { + fTrackedRecordingResources[i]->unref(gpu); + } + if (++fNumResets > kNumRewindResetsBeforeFullReset) { fTrackedResources.reset(); fTrackedRecycledResources.reset(); + fTrackedRecordingResources.reset(); fTrackedResources.setReserve(kInitialTrackedResourcesCount); fTrackedRecycledResources.setReserve(kInitialTrackedResourcesCount); + fTrackedRecordingResources.setReserve(kInitialTrackedResourcesCount); fNumResets = 0; } else { fTrackedResources.rewind(); fTrackedRecycledResources.rewind(); + fTrackedRecordingResources.rewind(); } @@ -211,7 +227,7 @@ void GrVkCommandBuffer::clearAttachments(const GrVkGpu* gpu, void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu, GrVkPipelineState* pipelineState, - VkPipelineLayout layout, + GrVkPipelineLayout* layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* descriptorSets, @@ -220,19 +236,20 @@ void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu, SkASSERT(fIsActive); GR_VK_CALL(gpu->vkInterface(), CmdBindDescriptorSets(fCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, + layout->layout(), firstSet, setCount, descriptorSets, dynamicOffsetCount, dynamicOffsets)); + this->addRecordingResource(layout); pipelineState->addUniformResources(*this); } void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu, const SkTArray<const GrVkRecycledResource*>& recycled, const SkTArray<const GrVkResource*>& resources, - VkPipelineLayout layout, + GrVkPipelineLayout* layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* descriptorSets, @@ -241,12 +258,13 @@ void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu, SkASSERT(fIsActive); GR_VK_CALL(gpu->vkInterface(), CmdBindDescriptorSets(fCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - layout, + layout->layout(), firstSet, setCount, descriptorSets, dynamicOffsetCount, dynamicOffsets)); + this->addRecordingResource(layout); for (int i = 0; i < recycled.count(); ++i) { this->addRecycledResource(recycled[i]); } @@ -378,6 +396,10 @@ void GrVkPrimaryCommandBuffer::end(const GrVkGpu* gpu) { SkASSERT(fIsActive); SkASSERT(!fActiveRenderPass); GR_VK_CALL_ERRCHECK(gpu->vkInterface(), EndCommandBuffer(fCmdBuffer)); + for (int i = 0; i < fTrackedRecordingResources.count(); ++i) { + fTrackedRecordingResources[i]->unref(gpu); + } + fTrackedRecordingResources.rewind(); this->invalidateState(); fIsActive = false; } diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h index 362d457773..cb2875ddf4 100644 --- a/src/gpu/vk/GrVkCommandBuffer.h +++ b/src/gpu/vk/GrVkCommandBuffer.h @@ -53,7 +53,7 @@ public: void bindDescriptorSets(const GrVkGpu* gpu, GrVkPipelineState*, - VkPipelineLayout layout, + GrVkPipelineLayout* layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* descriptorSets, @@ -63,7 +63,7 @@ public: void bindDescriptorSets(const GrVkGpu* gpu, const SkTArray<const GrVkRecycledResource*>&, const SkTArray<const GrVkResource*>&, - VkPipelineLayout layout, + GrVkPipelineLayout* layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* descriptorSets, @@ -102,8 +102,8 @@ public: uint32_t firstVertex, uint32_t firstInstance) const; - // Add ref-counted resource that will be tracked and released when this - // command buffer finishes execution + // Add ref-counted resource that will be tracked and released when this command buffer finishes + // execution void addResource(const GrVkResource* resource) { resource->ref(); fTrackedResources.append(1, &resource); @@ -116,6 +116,13 @@ public: fTrackedRecycledResources.append(1, &resource); } + // Add ref-counted resource that will be tracked and released when this command buffer finishes + // recording. + void addRecordingResource(const GrVkResource* resource) { + resource->ref(); + fTrackedRecordingResources.append(1, &resource); + } + void reset(GrVkGpu* gpu); protected: @@ -126,11 +133,13 @@ protected: , fNumResets(0) { fTrackedResources.setReserve(kInitialTrackedResourcesCount); fTrackedRecycledResources.setReserve(kInitialTrackedResourcesCount); + fTrackedRecordingResources.setReserve(kInitialTrackedResourcesCount); this->invalidateState(); } SkTDArray<const GrVkResource*> fTrackedResources; SkTDArray<const GrVkRecycledResource*> fTrackedRecycledResources; + SkTDArray<const GrVkResource*> fTrackedRecordingResources; // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add // new commands to the buffer; diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp index 28ca8b411c..9af85db94c 100644 --- a/src/gpu/vk/GrVkCopyManager.cpp +++ b/src/gpu/vk/GrVkCopyManager.cpp @@ -17,6 +17,7 @@ #include "GrVkDescriptorSet.h" #include "GrVkGpu.h" #include "GrVkImageView.h" +#include "GrVkPipelineLayout.h" #include "GrVkRenderTarget.h" #include "GrVkResourceProvider.h" #include "GrVkSampler.h" @@ -30,7 +31,7 @@ GrVkCopyManager::GrVkCopyManager() : fVertShaderModule(VK_NULL_HANDLE) , fFragShaderModule(VK_NULL_HANDLE) - , fPipelineLayout(VK_NULL_HANDLE) {} + , fPipelineLayout(nullptr) {} GrVkCopyManager::~GrVkCopyManager() {} @@ -114,15 +115,18 @@ bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) { layoutCreateInfo.pushConstantRangeCount = 0; layoutCreateInfo.pPushConstantRanges = nullptr; + VkPipelineLayout pipelineLayout; VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->device(), &layoutCreateInfo, nullptr, - &fPipelineLayout)); + &pipelineLayout)); if (err) { this->destroyResources(gpu); return false; } + fPipelineLayout = new GrVkPipelineLayout(pipelineLayout); + static const float vdata[] = { 0, 0, 0, 1, @@ -169,7 +173,7 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu, if (VK_NULL_HANDLE == fVertShaderModule) { SkASSERT(VK_NULL_HANDLE == fFragShaderModule && - VK_NULL_HANDLE == fPipelineLayout && + nullptr == fPipelineLayout && nullptr == fVertexBuffer.get() && nullptr == fUniformBuffer.get()); if (!this->createCopyProgram(gpu)) { @@ -177,12 +181,13 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu, return false; } } + SkASSERT(fPipelineLayout); GrVkResourceProvider& resourceProv = gpu->resourceProvider(); GrVkCopyPipeline* pipeline = resourceProv.findOrCreateCopyPipeline(rt, fShaderStageInfo, - fPipelineLayout); + fPipelineLayout->layout()); if (!pipeline) { return false; } @@ -412,10 +417,9 @@ void GrVkCopyManager::destroyResources(GrVkGpu* gpu) { fFragShaderModule = VK_NULL_HANDLE; } - if (VK_NULL_HANDLE != fPipelineLayout) { - GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPipelineLayout, - nullptr)); - fPipelineLayout = VK_NULL_HANDLE; + if (fPipelineLayout) { + fPipelineLayout->unref(gpu); + fPipelineLayout = nullptr; } if (fUniformBuffer) { @@ -427,7 +431,10 @@ void GrVkCopyManager::destroyResources(GrVkGpu* gpu) { void GrVkCopyManager::abandonResources() { fVertShaderModule = VK_NULL_HANDLE; fFragShaderModule = VK_NULL_HANDLE; - fPipelineLayout = VK_NULL_HANDLE; + if (fPipelineLayout) { + fPipelineLayout->unrefAndAbandon(); + fPipelineLayout = nullptr; + } if (fUniformBuffer) { fUniformBuffer->abandon(); diff --git a/src/gpu/vk/GrVkCopyManager.h b/src/gpu/vk/GrVkCopyManager.h index f36cc302b4..4b47895dd2 100644 --- a/src/gpu/vk/GrVkCopyManager.h +++ b/src/gpu/vk/GrVkCopyManager.h @@ -16,6 +16,7 @@ class GrSurface; class GrVkCopyPipeline; class GrVkGpu; +class GrVkPipelineLayout; class GrVkUniformBuffer; class GrVkVertexBuffer; struct SkIPoint; @@ -45,7 +46,7 @@ private: VkPipelineShaderStageCreateInfo fShaderStageInfo[2]; GrVkDescriptorSetManager::Handle fSamplerDSHandle; - VkPipelineLayout fPipelineLayout; + GrVkPipelineLayout* fPipelineLayout; sk_sp<GrVkVertexBuffer> fVertexBuffer; std::unique_ptr<GrVkUniformBuffer> fUniformBuffer; diff --git a/src/gpu/vk/GrVkPipelineLayout.cpp b/src/gpu/vk/GrVkPipelineLayout.cpp new file mode 100644 index 0000000000..7deb5acef9 --- /dev/null +++ b/src/gpu/vk/GrVkPipelineLayout.cpp @@ -0,0 +1,14 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrVkPipelineLayout.h" +#include "GrVkGpu.h" +#include "GrVkUtil.h" + +void GrVkPipelineLayout::freeGPUData(const GrVkGpu* gpu) const { + GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPipelineLayout, nullptr)); +} diff --git a/src/gpu/vk/GrVkPipelineLayout.h b/src/gpu/vk/GrVkPipelineLayout.h new file mode 100644 index 0000000000..7ab3242ebe --- /dev/null +++ b/src/gpu/vk/GrVkPipelineLayout.h @@ -0,0 +1,38 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrVkPipelineLayout_DEFINED +#define GrVkPipelineLayout_DEFINED + +#include "GrTypes.h" +#include "GrVkResource.h" +#include "vk/GrVkDefines.h" + +class GrVkPipelineLayout : public GrVkResource { +public: + GrVkPipelineLayout(VkPipelineLayout layout) : fPipelineLayout(layout) {} + + VkPipelineLayout layout() const { return fPipelineLayout; } + +#ifdef SK_TRACE_VK_RESOURCES + void dumpInfo() const override { + SkDebugf("GrVkPipelineLayout: %d (%d refs)\n", fPipelineLayout, this->getRefCnt()); + } +#endif + +private: + GrVkPipelineLayout(const GrVkPipelineLayout&); + GrVkPipelineLayout& operator=(const GrVkPipelineLayout&); + + void freeGPUData(const GrVkGpu* gpu) const override; + + VkPipelineLayout fPipelineLayout; + + typedef GrVkResource INHERITED; +}; + +#endif diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index 993f57d9e4..84aa68248c 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -19,6 +19,7 @@ #include "GrVkImageView.h" #include "GrVkMemory.h" #include "GrVkPipeline.h" +#include "GrVkPipelineLayout.h" #include "GrVkSampler.h" #include "GrVkTexelBuffer.h" #include "GrVkTexture.h" @@ -45,7 +46,7 @@ GrVkPipelineState::GrVkPipelineState( std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors, int fragmentProcessorCnt) : fPipeline(pipeline) - , fPipelineLayout(layout) + , fPipelineLayout(new GrVkPipelineLayout(layout)) , fUniformDescriptorSet(nullptr) , fSamplerDescriptorSet(nullptr) , fTexelBufferDescriptorSet(nullptr) @@ -119,10 +120,8 @@ void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) { } if (fPipelineLayout) { - GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), - fPipelineLayout, - nullptr)); - fPipelineLayout = VK_NULL_HANDLE; + fPipelineLayout->unref(gpu); + fPipelineLayout = nullptr; } if (fGeometryUniformBuffer) { @@ -153,10 +152,15 @@ void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) { } void GrVkPipelineState::abandonGPUResources() { - fPipeline->unrefAndAbandon(); - fPipeline = nullptr; + if (fPipeline) { + fPipeline->unrefAndAbandon(); + fPipeline = nullptr; + } - fPipelineLayout = VK_NULL_HANDLE; + if (fPipelineLayout) { + fPipelineLayout->unrefAndAbandon(); + fPipelineLayout = nullptr; + } fGeometryUniformBuffer->abandon(); fFragmentUniformBuffer->abandon(); diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h index 2ea01c1479..ee948a8519 100644 --- a/src/gpu/vk/GrVkPipelineState.h +++ b/src/gpu/vk/GrVkPipelineState.h @@ -23,6 +23,7 @@ class GrVkDescriptorSet; class GrVkGpu; class GrVkImageView; class GrVkPipeline; +class GrVkPipelineLayout; class GrVkSampler; class GrVkUniformBuffer; @@ -125,7 +126,7 @@ private: // Used for binding DescriptorSets to the command buffer but does not need to survive during // command buffer execution. Thus this is not need to be a GrVkResource. - VkPipelineLayout fPipelineLayout; + GrVkPipelineLayout* fPipelineLayout; // The DescriptorSets need to survive until the gpu has finished all draws that use them. // However, they will only be freed by the descriptor pool. Thus by simply keeping the |