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>
This commit is contained in:
parent
53418da8c6
commit
7d918fde03
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
14
src/gpu/vk/GrVkPipelineLayout.cpp
Normal file
14
src/gpu/vk/GrVkPipelineLayout.cpp
Normal file
@ -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));
|
||||
}
|
38
src/gpu/vk/GrVkPipelineLayout.h
Normal file
38
src/gpu/vk/GrVkPipelineLayout.h
Normal file
@ -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
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user