aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-06-19 15:22:01 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-20 13:37:28 +0000
commit7d918fde03d44011e7aac067227f88c4ba4cc3b8 (patch)
tree5f185edf442e4afff5c16bec75df4ad65d560082
parent53418da8c64773fed8c927404a8f7e78e93e1c95 (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.gni2
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp30
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h17
-rw-r--r--src/gpu/vk/GrVkCopyManager.cpp25
-rw-r--r--src/gpu/vk/GrVkCopyManager.h3
-rw-r--r--src/gpu/vk/GrVkPipelineLayout.cpp14
-rw-r--r--src/gpu/vk/GrVkPipelineLayout.h38
-rw-r--r--src/gpu/vk/GrVkPipelineState.cpp20
-rw-r--r--src/gpu/vk/GrVkPipelineState.h3
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