Setup system in Vulkan to reuse VkDescriptorSet allocations.
This CL uses the new system for uniform buffers. In a follow up CL I will add support for samplers. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2163673002 Review-Url: https://codereview.chromium.org/2163673002
This commit is contained in:
parent
81681949d3
commit
a95220d3b8
@ -455,6 +455,10 @@
|
||||
'<(skia_src_path)/gpu/vk/GrVkCommandBuffer.h',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorPool.cpp',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorPool.h',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorSet.cpp',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorSet.h',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorSetManager.cpp',
|
||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorSetManager.h',
|
||||
'<(skia_src_path)/gpu/vk/GrVkExtensions.cpp',
|
||||
'<(skia_src_path)/gpu/vk/GrVkExtensions.h',
|
||||
'<(skia_src_path)/gpu/vk/GrVkFramebuffer.cpp',
|
||||
|
@ -73,7 +73,6 @@ void GrVkCommandBuffer::reset(GrVkGpu* gpu) {
|
||||
}
|
||||
fTrackedRecycledResources.reset();
|
||||
|
||||
|
||||
this->invalidateState();
|
||||
|
||||
// we will retain resources for later use
|
||||
|
34
src/gpu/vk/GrVkDescriptorSet.cpp
Normal file
34
src/gpu/vk/GrVkDescriptorSet.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrVkDescriptorSet.h"
|
||||
|
||||
#include "GrVkDescriptorPool.h"
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrVkResourceProvider.h"
|
||||
|
||||
GrVkDescriptorSet::GrVkDescriptorSet(VkDescriptorSet descSet,
|
||||
GrVkDescriptorPool* pool,
|
||||
GrVkDescriptorSetManager::Handle handle)
|
||||
: fDescSet(descSet)
|
||||
, fPool(pool)
|
||||
, fHandle(handle) {
|
||||
fPool->ref();
|
||||
}
|
||||
|
||||
void GrVkDescriptorSet::freeGPUData(const GrVkGpu* gpu) const {
|
||||
fPool->unref(gpu);
|
||||
}
|
||||
|
||||
void GrVkDescriptorSet::onRecycle(GrVkGpu* gpu) const {
|
||||
gpu->resourceProvider().recycleDescriptorSet(this, fHandle);
|
||||
}
|
||||
|
||||
void GrVkDescriptorSet::abandonSubResources() const {
|
||||
fPool->unrefAndAbandon();
|
||||
}
|
||||
|
44
src/gpu/vk/GrVkDescriptorSet.h
Normal file
44
src/gpu/vk/GrVkDescriptorSet.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrVkDescriptorSet_DEFINED
|
||||
#define GrVkDescriptorSet_DEFINED
|
||||
|
||||
#include "GrVkDescriptorSetManager.h"
|
||||
#include "GrVkResource.h"
|
||||
#include "vk/GrVkDefines.h"
|
||||
|
||||
class GrVkDescriptorPool;
|
||||
class GrVkGpu;
|
||||
|
||||
class GrVkDescriptorSet : public GrVkRecycledResource {
|
||||
public:
|
||||
GrVkDescriptorSet(VkDescriptorSet descSet,
|
||||
GrVkDescriptorPool* pool,
|
||||
GrVkDescriptorSetManager::Handle handle);
|
||||
|
||||
~GrVkDescriptorSet() override {}
|
||||
|
||||
VkDescriptorSet descriptorSet() const { return fDescSet; }
|
||||
|
||||
#ifdef SK_TRACE_VK_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
SkDebugf("GrVkDescriptorSet: %d (%d refs)\n", fDescSet, this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||
void abandonSubResources() const override;
|
||||
void onRecycle(GrVkGpu* gpu) const override;
|
||||
|
||||
VkDescriptorSet fDescSet;
|
||||
SkDEBUGCODE(mutable) GrVkDescriptorPool* fPool;
|
||||
GrVkDescriptorSetManager::Handle fHandle;
|
||||
};
|
||||
|
||||
#endif
|
120
src/gpu/vk/GrVkDescriptorSetManager.cpp
Normal file
120
src/gpu/vk/GrVkDescriptorSetManager.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrVkDescriptorSetManager.h"
|
||||
|
||||
#include "GrVkDescriptorPool.h"
|
||||
#include "GrVkDescriptorSet.h"
|
||||
#include "GrVkGpu.h"
|
||||
|
||||
GrVkDescriptorSetManager::GrVkDescriptorSetManager(GrVkGpu* gpu,
|
||||
VkDescriptorSetLayout layout,
|
||||
VkDescriptorType type,
|
||||
uint32_t samplerCount)
|
||||
: fPoolManager(layout, type, samplerCount, gpu)
|
||||
, fNumSamplerBindings(samplerCount) {
|
||||
}
|
||||
|
||||
const GrVkDescriptorSet* GrVkDescriptorSetManager::getDescriptorSet(GrVkGpu* gpu,
|
||||
const Handle& handle) {
|
||||
const GrVkDescriptorSet* ds = nullptr;
|
||||
int count = fFreeSets.count();
|
||||
if (count > 0) {
|
||||
ds = fFreeSets[count - 1];
|
||||
fFreeSets.removeShuffle(count - 1);
|
||||
} else {
|
||||
VkDescriptorSet vkDS;
|
||||
fPoolManager.getNewDescriptorSet(gpu, &vkDS);
|
||||
|
||||
ds = new GrVkDescriptorSet(vkDS, fPoolManager.fPool, handle);
|
||||
}
|
||||
SkASSERT(ds);
|
||||
return ds;
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::recycleDescriptorSet(const GrVkDescriptorSet* descSet) {
|
||||
SkASSERT(descSet);
|
||||
fFreeSets.push_back(descSet);
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::release(const GrVkGpu* gpu) {
|
||||
fPoolManager.freeGPUResources(gpu);
|
||||
|
||||
for (int i = 0; i < fFreeSets.count(); ++i) {
|
||||
fFreeSets[i]->unref(gpu);
|
||||
}
|
||||
fFreeSets.reset();
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::abandon() {
|
||||
fPoolManager.abandonGPUResources();
|
||||
|
||||
for (int i = 0; i < fFreeSets.count(); ++i) {
|
||||
fFreeSets[i]->unrefAndAbandon();
|
||||
}
|
||||
fFreeSets.reset();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrVkDescriptorSetManager::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) {
|
||||
if (fPool) {
|
||||
fPool->unref(gpu);
|
||||
uint32_t newPoolSize = fMaxDescriptors + ((fMaxDescriptors + 1) >> 1);
|
||||
if (newPoolSize < kMaxDescriptors) {
|
||||
fMaxDescriptors = newPoolSize;
|
||||
} else {
|
||||
fMaxDescriptors = kMaxDescriptors;
|
||||
}
|
||||
|
||||
}
|
||||
fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType,
|
||||
fMaxDescriptors);
|
||||
SkASSERT(fPool);
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu,
|
||||
VkDescriptorSet* ds) {
|
||||
if (!fMaxDescriptors) {
|
||||
return;
|
||||
}
|
||||
fCurrentDescriptorCount += fDescCountPerSet;
|
||||
if (fCurrentDescriptorCount > fMaxDescriptors) {
|
||||
this->getNewPool(gpu);
|
||||
fCurrentDescriptorCount = fDescCountPerSet;
|
||||
}
|
||||
|
||||
VkDescriptorSetAllocateInfo dsAllocateInfo;
|
||||
memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
|
||||
dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
dsAllocateInfo.pNext = nullptr;
|
||||
dsAllocateInfo.descriptorPool = fPool->descPool();
|
||||
dsAllocateInfo.descriptorSetCount = 1;
|
||||
dsAllocateInfo.pSetLayouts = &fDescLayout;
|
||||
GR_VK_CALL_ERRCHECK(gpu->vkInterface(), AllocateDescriptorSets(gpu->device(),
|
||||
&dsAllocateInfo,
|
||||
ds));
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::DescriptorPoolManager::freeGPUResources(const GrVkGpu* gpu) {
|
||||
// The layout should be owned by the class which owns the DescriptorSetManager so it will
|
||||
// take care of destroying it.
|
||||
fDescLayout = VK_NULL_HANDLE;
|
||||
|
||||
if (fPool) {
|
||||
fPool->unref(gpu);
|
||||
fPool = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GrVkDescriptorSetManager::DescriptorPoolManager::abandonGPUResources() {
|
||||
fDescLayout = VK_NULL_HANDLE;
|
||||
if (fPool) {
|
||||
fPool->unrefAndAbandon();
|
||||
fPool = nullptr;
|
||||
}
|
||||
}
|
97
src/gpu/vk/GrVkDescriptorSetManager.h
Normal file
97
src/gpu/vk/GrVkDescriptorSetManager.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrVkDescriptorSetManager_DEFINED
|
||||
#define GrVkDescriptorSetManager_DEFINED
|
||||
|
||||
#include "GrResourceHandle.h"
|
||||
#include "GrVkDescriptorPool.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkTArray.h"
|
||||
#include "vk/GrVkDefines.h"
|
||||
|
||||
class GrVkDescriptorSet;
|
||||
class GrVkGpu;
|
||||
|
||||
/**
|
||||
* This class handles the allocation of descriptor sets for a given VkDescriptorSetLayout. It will
|
||||
* try to reuse previously allocated descriptor sets if they are no longer in use by other objects.
|
||||
*/
|
||||
class GrVkDescriptorSetManager {
|
||||
public:
|
||||
GR_DEFINE_RESOURCE_HANDLE_CLASS(Handle);
|
||||
|
||||
GrVkDescriptorSetManager(GrVkGpu* gpu,
|
||||
VkDescriptorSetLayout layout,
|
||||
VkDescriptorType,
|
||||
uint32_t samplerCount);
|
||||
~GrVkDescriptorSetManager() {}
|
||||
|
||||
void abandon();
|
||||
void release(const GrVkGpu* gpu);
|
||||
|
||||
const GrVkDescriptorSet* getDescriptorSet(GrVkGpu* gpu, const Handle& handle);
|
||||
|
||||
void recycleDescriptorSet(const GrVkDescriptorSet*);
|
||||
|
||||
int isCompatible(uint32_t numSamplers) const { return numSamplers == fNumSamplerBindings; }
|
||||
|
||||
private:
|
||||
struct DescriptorPoolManager {
|
||||
DescriptorPoolManager(VkDescriptorSetLayout layout, VkDescriptorType type,
|
||||
uint32_t samplerCount, GrVkGpu* gpu)
|
||||
: fDescLayout(layout)
|
||||
, fDescType(type)
|
||||
, fCurrentDescriptorCount(0)
|
||||
, fPool(nullptr) {
|
||||
if (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type) {
|
||||
fDescCountPerSet = kNumUniformDescPerSet;
|
||||
} else {
|
||||
SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
fDescCountPerSet = samplerCount;
|
||||
}
|
||||
|
||||
SkASSERT(fDescCountPerSet < kStartNumDescriptors);
|
||||
fMaxDescriptors = kStartNumDescriptors;
|
||||
SkASSERT(fMaxDescriptors > 0);
|
||||
this->getNewPool(gpu);
|
||||
}
|
||||
|
||||
~DescriptorPoolManager() {
|
||||
SkASSERT(!fDescLayout);
|
||||
SkASSERT(!fPool);
|
||||
}
|
||||
|
||||
void getNewDescriptorSet(GrVkGpu* gpu, VkDescriptorSet* ds);
|
||||
|
||||
void freeGPUResources(const GrVkGpu* gpu);
|
||||
void abandonGPUResources();
|
||||
|
||||
VkDescriptorSetLayout fDescLayout; // Not owned by this class
|
||||
VkDescriptorType fDescType;
|
||||
uint32_t fDescCountPerSet;
|
||||
uint32_t fMaxDescriptors;
|
||||
uint32_t fCurrentDescriptorCount;
|
||||
GrVkDescriptorPool* fPool;
|
||||
|
||||
private:
|
||||
enum {
|
||||
kNumUniformDescPerSet = 2,
|
||||
kMaxDescriptors = 1024,
|
||||
kStartNumDescriptors = 16, // must be less than kMaxUniformDescriptors
|
||||
};
|
||||
|
||||
void getNewPool(GrVkGpu* gpu);
|
||||
};
|
||||
|
||||
DescriptorPoolManager fPoolManager;
|
||||
SkTArray<const GrVkDescriptorSet*> fFreeSets;
|
||||
// If the number of bindings is 0 we assume this is for uniform buffers
|
||||
uint32_t fNumSamplerBindings;
|
||||
};
|
||||
|
||||
#endif
|
@ -110,7 +110,7 @@ private:
|
||||
|
||||
#ifdef SK_TRACE_VK_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
|
||||
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GrTexturePriv.h"
|
||||
#include "GrVkCommandBuffer.h"
|
||||
#include "GrVkDescriptorPool.h"
|
||||
#include "GrVkDescriptorSet.h"
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrVkImageView.h"
|
||||
#include "GrVkMemory.h"
|
||||
@ -39,6 +40,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
|
||||
const GrGLSLFragProcs& fragmentProcessors)
|
||||
: fPipeline(pipeline)
|
||||
, fPipelineLayout(layout)
|
||||
, fUniformDescriptorSet(nullptr)
|
||||
, fStartDS(SK_MaxS32)
|
||||
, fDSCount(0)
|
||||
, fBuiltinUniformHandles(builtinUniformHandles)
|
||||
@ -48,8 +50,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
|
||||
, fDesc(desc)
|
||||
, fDataManager(uniforms, vertexUniformSize, fragmentUniformSize)
|
||||
, fSamplerPoolManager(dsSamplerLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
numSamplers, gpu)
|
||||
, fCurrentUniformDescPool(nullptr) {
|
||||
numSamplers, gpu) {
|
||||
fSamplers.setReserve(numSamplers);
|
||||
fTextureViews.setReserve(numSamplers);
|
||||
fTextures.setReserve(numSamplers);
|
||||
@ -124,9 +125,10 @@ void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) {
|
||||
}
|
||||
|
||||
fSamplerPoolManager.freeGPUResources(gpu);
|
||||
if (fCurrentUniformDescPool) {
|
||||
fCurrentUniformDescPool->unref(gpu);
|
||||
fCurrentUniformDescPool = nullptr;
|
||||
|
||||
if (fUniformDescriptorSet) {
|
||||
fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
|
||||
fUniformDescriptorSet = nullptr;
|
||||
}
|
||||
|
||||
this->freeTempResources(gpu);
|
||||
@ -157,9 +159,10 @@ void GrVkPipelineState::abandonGPUResources() {
|
||||
fTextures.rewind();
|
||||
|
||||
fSamplerPoolManager.abandonGPUResources();
|
||||
if (fCurrentUniformDescPool) {
|
||||
fCurrentUniformDescPool->unrefAndAbandon();
|
||||
fCurrentUniformDescPool = nullptr;
|
||||
|
||||
if (fUniformDescriptorSet) {
|
||||
fUniformDescriptorSet->unrefAndAbandon();
|
||||
fUniformDescriptorSet = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,18 +211,13 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
|
||||
|
||||
if (fVertexUniformBuffer.get() || fFragmentUniformBuffer.get()) {
|
||||
if (fDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmentUniformBuffer) ||
|
||||
VK_NULL_HANDLE == fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]) {
|
||||
const GrVkDescriptorPool* pool;
|
||||
int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
|
||||
gpu->resourceProvider().getUniformDescriptorSet(&fDescriptorSets[uniformDSIdx],
|
||||
&pool);
|
||||
if (pool != fCurrentUniformDescPool) {
|
||||
if (fCurrentUniformDescPool) {
|
||||
fCurrentUniformDescPool->unref(gpu);
|
||||
}
|
||||
fCurrentUniformDescPool = pool;
|
||||
fCurrentUniformDescPool->ref();
|
||||
!fUniformDescriptorSet) {
|
||||
if (fUniformDescriptorSet) {
|
||||
fUniformDescriptorSet->recycle(gpu);
|
||||
}
|
||||
fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
|
||||
int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
|
||||
fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
|
||||
this->writeUniformBuffers(gpu);
|
||||
}
|
||||
}
|
||||
@ -370,8 +368,9 @@ void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) {
|
||||
if (fSamplerPoolManager.fPool) {
|
||||
commandBuffer.addResource(fSamplerPoolManager.fPool);
|
||||
}
|
||||
if (fCurrentUniformDescPool) {
|
||||
commandBuffer.addResource(fCurrentUniformDescPool);
|
||||
|
||||
if (fUniformDescriptorSet) {
|
||||
commandBuffer.addRecycledResource(fUniformDescriptorSet);
|
||||
}
|
||||
|
||||
if (fVertexUniformBuffer.get()) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
class GrPipeline;
|
||||
class GrVkCommandBuffer;
|
||||
class GrVkDescriptorPool;
|
||||
class GrVkDescriptorSet;
|
||||
class GrVkGpu;
|
||||
class GrVkImageView;
|
||||
class GrVkPipeline;
|
||||
@ -256,6 +257,10 @@ private:
|
||||
// GrVkPipelineState since we update the descriptor sets and bind them at separate times;
|
||||
VkDescriptorSet fDescriptorSets[2];
|
||||
|
||||
// Once we move samplers over to use the resource provider for descriptor sets we will not need
|
||||
// the above array and instead just use GrVkDescriptorSet like the uniform one here.
|
||||
const GrVkDescriptorSet* fUniformDescriptorSet;
|
||||
|
||||
// Meta data so we know which descriptor sets we are using and need to bind.
|
||||
int fStartDS;
|
||||
int fDSCount;
|
||||
@ -282,7 +287,6 @@ private:
|
||||
GrVkPipelineStateDataManager fDataManager;
|
||||
|
||||
DescriptorPoolManager fSamplerPoolManager;
|
||||
const GrVkDescriptorPool* fCurrentUniformDescPool;
|
||||
|
||||
int fNumSamplers;
|
||||
|
||||
|
@ -195,13 +195,14 @@ private:
|
||||
class GrVkRecycledResource : public GrVkResource {
|
||||
public:
|
||||
// When recycle is called and there is only one ref left on the resource, we will signal that
|
||||
// the resource can be recycled for reuse. This function will always unref the object. Thus
|
||||
// if the object is recycled it should be ref'd inside the onRecycle call.
|
||||
// the resource can be recycled for reuse. If the sublass (or whoever is managing this resource)
|
||||
// decides not to recycle the objects, it is their responsibility to call unref on the object.
|
||||
void recycle(GrVkGpu* gpu) const {
|
||||
if (this->unique()) {
|
||||
this->onRecycle(gpu);
|
||||
} else {
|
||||
this->unref(gpu);
|
||||
}
|
||||
this->unref(gpu);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -22,7 +22,6 @@ uint32_t GrVkResource::fKeyCounter = 0;
|
||||
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
|
||||
: fGpu(gpu)
|
||||
, fPipelineCache(VK_NULL_HANDLE)
|
||||
, fUniformDescPool(nullptr)
|
||||
, fCurrentUniformDescCount(0) {
|
||||
fPipelineStateCache = new PipelineStateCache(gpu);
|
||||
}
|
||||
@ -61,9 +60,8 @@ void GrVkResourceProvider::initUniformDescObjects() {
|
||||
&dsUniformLayoutCreateInfo,
|
||||
nullptr,
|
||||
&fUniformDescLayout));
|
||||
fCurrMaxUniDescriptors = kStartNumUniformDescriptors;
|
||||
fUniformDescPool = this->findOrCreateCompatibleDescriptorPool(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
fCurrMaxUniDescriptors);
|
||||
|
||||
this->getDescSetHandle(0, fUniformDescLayout, &fUniformDSHandle);
|
||||
}
|
||||
|
||||
void GrVkResourceProvider::init() {
|
||||
@ -191,42 +189,46 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::findOrCreateCompatiblePipelineSta
|
||||
return fPipelineStateCache->refPipelineState(pipeline, proc, primitiveType, renderPass);
|
||||
}
|
||||
|
||||
void GrVkResourceProvider::getUniformDescriptorSet(VkDescriptorSet* ds,
|
||||
const GrVkDescriptorPool** outPool) {
|
||||
fCurrentUniformDescCount += kNumUniformDescPerSet;
|
||||
if (fCurrentUniformDescCount > fCurrMaxUniDescriptors) {
|
||||
fUniformDescPool->unref(fGpu);
|
||||
uint32_t newPoolSize = fCurrMaxUniDescriptors + ((fCurrMaxUniDescriptors + 1) >> 1);
|
||||
if (newPoolSize < kMaxUniformDescriptors) {
|
||||
fCurrMaxUniDescriptors = newPoolSize;
|
||||
} else {
|
||||
fCurrMaxUniDescriptors = kMaxUniformDescriptors;
|
||||
}
|
||||
fUniformDescPool =
|
||||
this->findOrCreateCompatibleDescriptorPool(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
fCurrMaxUniDescriptors);
|
||||
fCurrentUniformDescCount = kNumUniformDescPerSet;
|
||||
}
|
||||
SkASSERT(fUniformDescPool);
|
||||
|
||||
VkDescriptorSetAllocateInfo dsAllocateInfo;
|
||||
memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
|
||||
dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
dsAllocateInfo.pNext = nullptr;
|
||||
dsAllocateInfo.descriptorPool = fUniformDescPool->descPool();
|
||||
dsAllocateInfo.descriptorSetCount = 1;
|
||||
dsAllocateInfo.pSetLayouts = &fUniformDescLayout;
|
||||
GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(),
|
||||
&dsAllocateInfo,
|
||||
ds));
|
||||
*outPool = fUniformDescPool;
|
||||
void GrVkResourceProvider::getDescSetHandle(uint32_t numSamplers, VkDescriptorSetLayout layout,
|
||||
GrVkDescriptorSetManager::Handle* handle) {
|
||||
SkASSERT(handle);
|
||||
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
|
||||
if (fDescriptorSetManagers[i].isCompatible(numSamplers)) {
|
||||
*handle = GrVkDescriptorSetManager::Handle(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Failed to find a DescSetManager, we must create a new one;
|
||||
VkDescriptorType type = numSamplers ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
|
||||
: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
|
||||
fDescriptorSetManagers.emplace_back(fGpu, layout, type, numSamplers);
|
||||
*handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1);
|
||||
}
|
||||
|
||||
const GrVkDescriptorSet* GrVkResourceProvider::getUniformDescriptorSet() {
|
||||
SkASSERT(fUniformDSHandle.isValid());
|
||||
return fDescriptorSetManagers[fUniformDSHandle.toIndex()].getDescriptorSet(fGpu,
|
||||
fUniformDSHandle);
|
||||
}
|
||||
|
||||
|
||||
void GrVkResourceProvider::recycleDescriptorSet(const GrVkDescriptorSet* descSet,
|
||||
const GrVkDescriptorSetManager::Handle& handle) {
|
||||
SkASSERT(descSet);
|
||||
SkASSERT(handle.isValid());
|
||||
int managerIdx = handle.toIndex();
|
||||
SkASSERT(managerIdx < fDescriptorSetManagers.count());
|
||||
fDescriptorSetManagers[managerIdx].recycleDescriptorSet(descSet);
|
||||
}
|
||||
|
||||
GrVkPrimaryCommandBuffer* GrVkResourceProvider::findOrCreatePrimaryCommandBuffer() {
|
||||
GrVkPrimaryCommandBuffer* cmdBuffer = nullptr;
|
||||
int count = fAvailableCommandBuffers.count();
|
||||
if (count > 0) {
|
||||
cmdBuffer = fAvailableCommandBuffers[count -1];
|
||||
cmdBuffer = fAvailableCommandBuffers[count - 1];
|
||||
SkASSERT(cmdBuffer->finished(fGpu));
|
||||
fAvailableCommandBuffers.removeShuffle(count - 1);
|
||||
} else {
|
||||
@ -313,7 +315,13 @@ void GrVkResourceProvider::destroyResources() {
|
||||
nullptr));
|
||||
fUniformDescLayout = VK_NULL_HANDLE;
|
||||
}
|
||||
fUniformDescPool->unref(fGpu);
|
||||
|
||||
// We must release/destroy all command buffers and pipeline states before releasing the
|
||||
// GrVkDescriptorSetManagers
|
||||
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
|
||||
fDescriptorSetManagers[i].release(fGpu);
|
||||
}
|
||||
fDescriptorSetManagers.reset();
|
||||
}
|
||||
|
||||
void GrVkResourceProvider::abandonResources() {
|
||||
@ -356,8 +364,13 @@ void GrVkResourceProvider::abandonResources() {
|
||||
|
||||
fPipelineCache = VK_NULL_HANDLE;
|
||||
|
||||
fUniformDescLayout = VK_NULL_HANDLE;
|
||||
fUniformDescPool->unrefAndAbandon();
|
||||
// We must abandon all command buffers and pipeline states before abandoning the
|
||||
// GrVkDescriptorSetManagers
|
||||
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
|
||||
fDescriptorSetManagers[i].abandon();
|
||||
}
|
||||
fDescriptorSetManagers.reset();
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GrGpu.h"
|
||||
#include "GrResourceHandle.h"
|
||||
#include "GrVkDescriptorPool.h"
|
||||
#include "GrVkDescriptorSetManager.h"
|
||||
#include "GrVkPipelineState.h"
|
||||
#include "GrVkRenderPass.h"
|
||||
#include "GrVkResource.h"
|
||||
@ -100,18 +101,33 @@ public:
|
||||
GrPrimitiveType,
|
||||
const GrVkRenderPass& renderPass);
|
||||
|
||||
// For all our GrVkPipelineState objects, we require a layout where the first set contains two
|
||||
// uniform buffers, one for the vertex shader and one for the fragment shader. Thus it is
|
||||
// possible for us to use a shadered descriptor pool to allocate all these similar descriptor
|
||||
// sets. The caller is responsible for reffing the outPool for as long as the returned
|
||||
// VkDescriptor set is in use.
|
||||
void getUniformDescriptorSet(VkDescriptorSet*, const GrVkDescriptorPool** outPool);
|
||||
// Returns a handle which the GrVkResourceProvider uses to know which compatible
|
||||
// GrVkDescriptorSetManager to use when getting or recycling a GrVkDescriptorSet. Passing in a
|
||||
// value of 0 for numSamplers is used to signal this is for the uniform descriptor set.
|
||||
void getDescSetHandle(uint32_t numSamplers, VkDescriptorSetLayout layout,
|
||||
GrVkDescriptorSetManager::Handle* handle);
|
||||
|
||||
// Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
|
||||
// is already reffed for the caller.
|
||||
const GrVkDescriptorSet* getUniformDescriptorSet();
|
||||
|
||||
// Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
|
||||
// the GrVkDescriptorSetManager::Handle passed int.. The GrVkDescriptorSet is already reffed for
|
||||
// the caller.
|
||||
// TODO: Move samplers in GrVkPipelineState to use the GrVkResourceProvider to allocate
|
||||
// descriptor sets from.
|
||||
const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
|
||||
|
||||
// Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
|
||||
// own the VkDescriptorSetLayout and thus should not delete it. This function should be used
|
||||
// when the caller needs the layout to create a VkPipelineLayout.
|
||||
VkDescriptorSetLayout getUniDSLayout() const { return fUniformDescLayout; }
|
||||
|
||||
// Signals that the descriptor set passed it, which is compatible with the passed in handle,
|
||||
// can be reused by the next allocation request.
|
||||
void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
|
||||
const GrVkDescriptorSetManager::Handle&);
|
||||
|
||||
// Destroy any cached resources. To be called before destroying the VkDevice.
|
||||
// The assumption is that all queues are idle and all command buffers are finished.
|
||||
// For resource tracing to work properly, this should be called after unrefing all other
|
||||
@ -163,7 +179,6 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class CompatibleRenderPassSet {
|
||||
public:
|
||||
// This will always construct the basic load store render pass (all attachments load and
|
||||
@ -218,8 +233,11 @@ private:
|
||||
// Cache of GrVkPipelineStates
|
||||
PipelineStateCache* fPipelineStateCache;
|
||||
|
||||
SkSTArray<4, GrVkDescriptorSetManager> fDescriptorSetManagers;
|
||||
|
||||
GrVkDescriptorSetManager::Handle fUniformDSHandle;
|
||||
|
||||
// Current pool to allocate uniform descriptor sets from
|
||||
const GrVkDescriptorPool* fUniformDescPool;
|
||||
VkDescriptorSetLayout fUniformDescLayout;
|
||||
//Curent number of uniform descriptors allocated from the pool
|
||||
int fCurrentUniformDescCount;
|
||||
|
Loading…
Reference in New Issue
Block a user