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/GrVkCommandBuffer.h',
|
||||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorPool.cpp',
|
'<(skia_src_path)/gpu/vk/GrVkDescriptorPool.cpp',
|
||||||
'<(skia_src_path)/gpu/vk/GrVkDescriptorPool.h',
|
'<(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.cpp',
|
||||||
'<(skia_src_path)/gpu/vk/GrVkExtensions.h',
|
'<(skia_src_path)/gpu/vk/GrVkExtensions.h',
|
||||||
'<(skia_src_path)/gpu/vk/GrVkFramebuffer.cpp',
|
'<(skia_src_path)/gpu/vk/GrVkFramebuffer.cpp',
|
||||||
|
@ -73,7 +73,6 @@ void GrVkCommandBuffer::reset(GrVkGpu* gpu) {
|
|||||||
}
|
}
|
||||||
fTrackedRecycledResources.reset();
|
fTrackedRecycledResources.reset();
|
||||||
|
|
||||||
|
|
||||||
this->invalidateState();
|
this->invalidateState();
|
||||||
|
|
||||||
// we will retain resources for later use
|
// 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
|
#ifdef SK_TRACE_VK_RESOURCES
|
||||||
void dumpInfo() const override {
|
void dumpInfo() const override {
|
||||||
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
|
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "GrTexturePriv.h"
|
#include "GrTexturePriv.h"
|
||||||
#include "GrVkCommandBuffer.h"
|
#include "GrVkCommandBuffer.h"
|
||||||
#include "GrVkDescriptorPool.h"
|
#include "GrVkDescriptorPool.h"
|
||||||
|
#include "GrVkDescriptorSet.h"
|
||||||
#include "GrVkGpu.h"
|
#include "GrVkGpu.h"
|
||||||
#include "GrVkImageView.h"
|
#include "GrVkImageView.h"
|
||||||
#include "GrVkMemory.h"
|
#include "GrVkMemory.h"
|
||||||
@ -39,6 +40,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
|
|||||||
const GrGLSLFragProcs& fragmentProcessors)
|
const GrGLSLFragProcs& fragmentProcessors)
|
||||||
: fPipeline(pipeline)
|
: fPipeline(pipeline)
|
||||||
, fPipelineLayout(layout)
|
, fPipelineLayout(layout)
|
||||||
|
, fUniformDescriptorSet(nullptr)
|
||||||
, fStartDS(SK_MaxS32)
|
, fStartDS(SK_MaxS32)
|
||||||
, fDSCount(0)
|
, fDSCount(0)
|
||||||
, fBuiltinUniformHandles(builtinUniformHandles)
|
, fBuiltinUniformHandles(builtinUniformHandles)
|
||||||
@ -48,8 +50,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
|
|||||||
, fDesc(desc)
|
, fDesc(desc)
|
||||||
, fDataManager(uniforms, vertexUniformSize, fragmentUniformSize)
|
, fDataManager(uniforms, vertexUniformSize, fragmentUniformSize)
|
||||||
, fSamplerPoolManager(dsSamplerLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
, fSamplerPoolManager(dsSamplerLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
numSamplers, gpu)
|
numSamplers, gpu) {
|
||||||
, fCurrentUniformDescPool(nullptr) {
|
|
||||||
fSamplers.setReserve(numSamplers);
|
fSamplers.setReserve(numSamplers);
|
||||||
fTextureViews.setReserve(numSamplers);
|
fTextureViews.setReserve(numSamplers);
|
||||||
fTextures.setReserve(numSamplers);
|
fTextures.setReserve(numSamplers);
|
||||||
@ -124,9 +125,10 @@ void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fSamplerPoolManager.freeGPUResources(gpu);
|
fSamplerPoolManager.freeGPUResources(gpu);
|
||||||
if (fCurrentUniformDescPool) {
|
|
||||||
fCurrentUniformDescPool->unref(gpu);
|
if (fUniformDescriptorSet) {
|
||||||
fCurrentUniformDescPool = nullptr;
|
fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
|
||||||
|
fUniformDescriptorSet = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->freeTempResources(gpu);
|
this->freeTempResources(gpu);
|
||||||
@ -157,9 +159,10 @@ void GrVkPipelineState::abandonGPUResources() {
|
|||||||
fTextures.rewind();
|
fTextures.rewind();
|
||||||
|
|
||||||
fSamplerPoolManager.abandonGPUResources();
|
fSamplerPoolManager.abandonGPUResources();
|
||||||
if (fCurrentUniformDescPool) {
|
|
||||||
fCurrentUniformDescPool->unrefAndAbandon();
|
if (fUniformDescriptorSet) {
|
||||||
fCurrentUniformDescPool = nullptr;
|
fUniformDescriptorSet->unrefAndAbandon();
|
||||||
|
fUniformDescriptorSet = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,18 +211,13 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
|
|||||||
|
|
||||||
if (fVertexUniformBuffer.get() || fFragmentUniformBuffer.get()) {
|
if (fVertexUniformBuffer.get() || fFragmentUniformBuffer.get()) {
|
||||||
if (fDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmentUniformBuffer) ||
|
if (fDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmentUniformBuffer) ||
|
||||||
VK_NULL_HANDLE == fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]) {
|
!fUniformDescriptorSet) {
|
||||||
const GrVkDescriptorPool* pool;
|
if (fUniformDescriptorSet) {
|
||||||
int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
|
fUniformDescriptorSet->recycle(gpu);
|
||||||
gpu->resourceProvider().getUniformDescriptorSet(&fDescriptorSets[uniformDSIdx],
|
|
||||||
&pool);
|
|
||||||
if (pool != fCurrentUniformDescPool) {
|
|
||||||
if (fCurrentUniformDescPool) {
|
|
||||||
fCurrentUniformDescPool->unref(gpu);
|
|
||||||
}
|
|
||||||
fCurrentUniformDescPool = pool;
|
|
||||||
fCurrentUniformDescPool->ref();
|
|
||||||
}
|
}
|
||||||
|
fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
|
||||||
|
int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
|
||||||
|
fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
|
||||||
this->writeUniformBuffers(gpu);
|
this->writeUniformBuffers(gpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,8 +368,9 @@ void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) {
|
|||||||
if (fSamplerPoolManager.fPool) {
|
if (fSamplerPoolManager.fPool) {
|
||||||
commandBuffer.addResource(fSamplerPoolManager.fPool);
|
commandBuffer.addResource(fSamplerPoolManager.fPool);
|
||||||
}
|
}
|
||||||
if (fCurrentUniformDescPool) {
|
|
||||||
commandBuffer.addResource(fCurrentUniformDescPool);
|
if (fUniformDescriptorSet) {
|
||||||
|
commandBuffer.addRecycledResource(fUniformDescriptorSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fVertexUniformBuffer.get()) {
|
if (fVertexUniformBuffer.get()) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
class GrPipeline;
|
class GrPipeline;
|
||||||
class GrVkCommandBuffer;
|
class GrVkCommandBuffer;
|
||||||
class GrVkDescriptorPool;
|
class GrVkDescriptorPool;
|
||||||
|
class GrVkDescriptorSet;
|
||||||
class GrVkGpu;
|
class GrVkGpu;
|
||||||
class GrVkImageView;
|
class GrVkImageView;
|
||||||
class GrVkPipeline;
|
class GrVkPipeline;
|
||||||
@ -256,6 +257,10 @@ private:
|
|||||||
// GrVkPipelineState since we update the descriptor sets and bind them at separate times;
|
// GrVkPipelineState since we update the descriptor sets and bind them at separate times;
|
||||||
VkDescriptorSet fDescriptorSets[2];
|
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.
|
// Meta data so we know which descriptor sets we are using and need to bind.
|
||||||
int fStartDS;
|
int fStartDS;
|
||||||
int fDSCount;
|
int fDSCount;
|
||||||
@ -282,7 +287,6 @@ private:
|
|||||||
GrVkPipelineStateDataManager fDataManager;
|
GrVkPipelineStateDataManager fDataManager;
|
||||||
|
|
||||||
DescriptorPoolManager fSamplerPoolManager;
|
DescriptorPoolManager fSamplerPoolManager;
|
||||||
const GrVkDescriptorPool* fCurrentUniformDescPool;
|
|
||||||
|
|
||||||
int fNumSamplers;
|
int fNumSamplers;
|
||||||
|
|
||||||
|
@ -195,13 +195,14 @@ private:
|
|||||||
class GrVkRecycledResource : public GrVkResource {
|
class GrVkRecycledResource : public GrVkResource {
|
||||||
public:
|
public:
|
||||||
// When recycle is called and there is only one ref left on the resource, we will signal that
|
// 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
|
// the resource can be recycled for reuse. If the sublass (or whoever is managing this resource)
|
||||||
// if the object is recycled it should be ref'd inside the onRecycle call.
|
// decides not to recycle the objects, it is their responsibility to call unref on the object.
|
||||||
void recycle(GrVkGpu* gpu) const {
|
void recycle(GrVkGpu* gpu) const {
|
||||||
if (this->unique()) {
|
if (this->unique()) {
|
||||||
this->onRecycle(gpu);
|
this->onRecycle(gpu);
|
||||||
|
} else {
|
||||||
|
this->unref(gpu);
|
||||||
}
|
}
|
||||||
this->unref(gpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -22,7 +22,6 @@ uint32_t GrVkResource::fKeyCounter = 0;
|
|||||||
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
|
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
|
||||||
: fGpu(gpu)
|
: fGpu(gpu)
|
||||||
, fPipelineCache(VK_NULL_HANDLE)
|
, fPipelineCache(VK_NULL_HANDLE)
|
||||||
, fUniformDescPool(nullptr)
|
|
||||||
, fCurrentUniformDescCount(0) {
|
, fCurrentUniformDescCount(0) {
|
||||||
fPipelineStateCache = new PipelineStateCache(gpu);
|
fPipelineStateCache = new PipelineStateCache(gpu);
|
||||||
}
|
}
|
||||||
@ -61,9 +60,8 @@ void GrVkResourceProvider::initUniformDescObjects() {
|
|||||||
&dsUniformLayoutCreateInfo,
|
&dsUniformLayoutCreateInfo,
|
||||||
nullptr,
|
nullptr,
|
||||||
&fUniformDescLayout));
|
&fUniformDescLayout));
|
||||||
fCurrMaxUniDescriptors = kStartNumUniformDescriptors;
|
|
||||||
fUniformDescPool = this->findOrCreateCompatibleDescriptorPool(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
this->getDescSetHandle(0, fUniformDescLayout, &fUniformDSHandle);
|
||||||
fCurrMaxUniDescriptors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrVkResourceProvider::init() {
|
void GrVkResourceProvider::init() {
|
||||||
@ -191,42 +189,46 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::findOrCreateCompatiblePipelineSta
|
|||||||
return fPipelineStateCache->refPipelineState(pipeline, proc, primitiveType, renderPass);
|
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;
|
void GrVkResourceProvider::getDescSetHandle(uint32_t numSamplers, VkDescriptorSetLayout layout,
|
||||||
memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
|
GrVkDescriptorSetManager::Handle* handle) {
|
||||||
dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
SkASSERT(handle);
|
||||||
dsAllocateInfo.pNext = nullptr;
|
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
|
||||||
dsAllocateInfo.descriptorPool = fUniformDescPool->descPool();
|
if (fDescriptorSetManagers[i].isCompatible(numSamplers)) {
|
||||||
dsAllocateInfo.descriptorSetCount = 1;
|
*handle = GrVkDescriptorSetManager::Handle(i);
|
||||||
dsAllocateInfo.pSetLayouts = &fUniformDescLayout;
|
return;
|
||||||
GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(),
|
}
|
||||||
&dsAllocateInfo,
|
}
|
||||||
ds));
|
|
||||||
*outPool = fUniformDescPool;
|
// 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* GrVkResourceProvider::findOrCreatePrimaryCommandBuffer() {
|
||||||
GrVkPrimaryCommandBuffer* cmdBuffer = nullptr;
|
GrVkPrimaryCommandBuffer* cmdBuffer = nullptr;
|
||||||
int count = fAvailableCommandBuffers.count();
|
int count = fAvailableCommandBuffers.count();
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
cmdBuffer = fAvailableCommandBuffers[count -1];
|
cmdBuffer = fAvailableCommandBuffers[count - 1];
|
||||||
SkASSERT(cmdBuffer->finished(fGpu));
|
SkASSERT(cmdBuffer->finished(fGpu));
|
||||||
fAvailableCommandBuffers.removeShuffle(count - 1);
|
fAvailableCommandBuffers.removeShuffle(count - 1);
|
||||||
} else {
|
} else {
|
||||||
@ -313,7 +315,13 @@ void GrVkResourceProvider::destroyResources() {
|
|||||||
nullptr));
|
nullptr));
|
||||||
fUniformDescLayout = VK_NULL_HANDLE;
|
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() {
|
void GrVkResourceProvider::abandonResources() {
|
||||||
@ -356,8 +364,13 @@ void GrVkResourceProvider::abandonResources() {
|
|||||||
|
|
||||||
fPipelineCache = VK_NULL_HANDLE;
|
fPipelineCache = VK_NULL_HANDLE;
|
||||||
|
|
||||||
fUniformDescLayout = VK_NULL_HANDLE;
|
// We must abandon all command buffers and pipeline states before abandoning the
|
||||||
fUniformDescPool->unrefAndAbandon();
|
// GrVkDescriptorSetManagers
|
||||||
|
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
|
||||||
|
fDescriptorSetManagers[i].abandon();
|
||||||
|
}
|
||||||
|
fDescriptorSetManagers.reset();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
#include "GrResourceHandle.h"
|
#include "GrResourceHandle.h"
|
||||||
#include "GrVkDescriptorPool.h"
|
#include "GrVkDescriptorPool.h"
|
||||||
|
#include "GrVkDescriptorSetManager.h"
|
||||||
#include "GrVkPipelineState.h"
|
#include "GrVkPipelineState.h"
|
||||||
#include "GrVkRenderPass.h"
|
#include "GrVkRenderPass.h"
|
||||||
#include "GrVkResource.h"
|
#include "GrVkResource.h"
|
||||||
@ -100,18 +101,33 @@ public:
|
|||||||
GrPrimitiveType,
|
GrPrimitiveType,
|
||||||
const GrVkRenderPass& renderPass);
|
const GrVkRenderPass& renderPass);
|
||||||
|
|
||||||
// For all our GrVkPipelineState objects, we require a layout where the first set contains two
|
// Returns a handle which the GrVkResourceProvider uses to know which compatible
|
||||||
// uniform buffers, one for the vertex shader and one for the fragment shader. Thus it is
|
// GrVkDescriptorSetManager to use when getting or recycling a GrVkDescriptorSet. Passing in a
|
||||||
// possible for us to use a shadered descriptor pool to allocate all these similar descriptor
|
// value of 0 for numSamplers is used to signal this is for the uniform descriptor set.
|
||||||
// sets. The caller is responsible for reffing the outPool for as long as the returned
|
void getDescSetHandle(uint32_t numSamplers, VkDescriptorSetLayout layout,
|
||||||
// VkDescriptor set is in use.
|
GrVkDescriptorSetManager::Handle* handle);
|
||||||
void getUniformDescriptorSet(VkDescriptorSet*, const GrVkDescriptorPool** outPool);
|
|
||||||
|
// 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
|
// 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
|
// own the VkDescriptorSetLayout and thus should not delete it. This function should be used
|
||||||
// when the caller needs the layout to create a VkPipelineLayout.
|
// when the caller needs the layout to create a VkPipelineLayout.
|
||||||
VkDescriptorSetLayout getUniDSLayout() const { return fUniformDescLayout; }
|
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.
|
// 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.
|
// 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
|
// For resource tracing to work properly, this should be called after unrefing all other
|
||||||
@ -163,7 +179,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CompatibleRenderPassSet {
|
class CompatibleRenderPassSet {
|
||||||
public:
|
public:
|
||||||
// This will always construct the basic load store render pass (all attachments load and
|
// This will always construct the basic load store render pass (all attachments load and
|
||||||
@ -218,8 +233,11 @@ private:
|
|||||||
// Cache of GrVkPipelineStates
|
// Cache of GrVkPipelineStates
|
||||||
PipelineStateCache* fPipelineStateCache;
|
PipelineStateCache* fPipelineStateCache;
|
||||||
|
|
||||||
|
SkSTArray<4, GrVkDescriptorSetManager> fDescriptorSetManagers;
|
||||||
|
|
||||||
|
GrVkDescriptorSetManager::Handle fUniformDSHandle;
|
||||||
|
|
||||||
// Current pool to allocate uniform descriptor sets from
|
// Current pool to allocate uniform descriptor sets from
|
||||||
const GrVkDescriptorPool* fUniformDescPool;
|
|
||||||
VkDescriptorSetLayout fUniformDescLayout;
|
VkDescriptorSetLayout fUniformDescLayout;
|
||||||
//Curent number of uniform descriptors allocated from the pool
|
//Curent number of uniform descriptors allocated from the pool
|
||||||
int fCurrentUniformDescCount;
|
int fCurrentUniformDescCount;
|
||||||
|
Loading…
Reference in New Issue
Block a user