Reuse sampler descriptor set allocations in Vulkan
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2172873003
Review-Url: https://codereview.chromium.org/2172873003
diff --git a/src/gpu/vk/GrVkDescriptorSetManager.cpp b/src/gpu/vk/GrVkDescriptorSetManager.cpp
index 51138e1..9f44d65 100644
--- a/src/gpu/vk/GrVkDescriptorSetManager.cpp
+++ b/src/gpu/vk/GrVkDescriptorSetManager.cpp
@@ -10,13 +10,25 @@
#include "GrVkDescriptorPool.h"
#include "GrVkDescriptorSet.h"
#include "GrVkGpu.h"
+#include "GrVkUniformHandler.h"
+#include "glsl/GrGLSLSampler.h"
GrVkDescriptorSetManager::GrVkDescriptorSetManager(GrVkGpu* gpu,
- VkDescriptorSetLayout layout,
VkDescriptorType type,
- uint32_t samplerCount)
- : fPoolManager(layout, type, samplerCount, gpu)
- , fNumSamplerBindings(samplerCount) {
+ const GrVkUniformHandler* uniformHandler)
+ : fPoolManager(type, gpu, uniformHandler) {
+ if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
+ SkASSERT(uniformHandler);
+ for (int i = 0; i < uniformHandler->numSamplers(); ++i) {
+ fBindingVisibilities.push_back(uniformHandler->getSampler(i).visibility());
+ }
+ } else {
+ SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
+ // We set the visibility of the first binding to the vertex shader and the second to the
+ // fragment shader.
+ fBindingVisibilities.push_back(kVertex_GrShaderFlag);
+ fBindingVisibilities.push_back(kFragment_GrShaderFlag);
+ }
}
const GrVkDescriptorSet* GrVkDescriptorSetManager::getDescriptorSet(GrVkGpu* gpu,
@@ -59,8 +71,122 @@
fFreeSets.reset();
}
+bool GrVkDescriptorSetManager::isCompatible(VkDescriptorType type,
+ const GrVkUniformHandler* uniHandler) const {
+ SkASSERT(uniHandler);
+ if (type != fPoolManager.fDescType) {
+ return false;
+ }
+
+ if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
+ if (fBindingVisibilities.count() != uniHandler->numSamplers()) {
+ return false;
+ }
+ for (int i = 0; i < uniHandler->numSamplers(); ++i) {
+ if (uniHandler->getSampler(i).visibility() != fBindingVisibilities[i]) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////////
+VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
+ VkShaderStageFlags flags = 0;
+
+ if (visibility & kVertex_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_VERTEX_BIT;
+ }
+ if (visibility & kGeometry_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
+ }
+ if (visibility & kFragment_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
+ }
+ return flags;
+}
+
+GrVkDescriptorSetManager::DescriptorPoolManager::DescriptorPoolManager(
+ VkDescriptorType type,
+ GrVkGpu* gpu,
+ const GrVkUniformHandler* uniformHandler)
+ : fDescType(type)
+ , fCurrentDescriptorCount(0)
+ , fPool(nullptr) {
+ if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
+ SkASSERT(uniformHandler);
+ uint32_t numSamplers = (uint32_t)uniformHandler->numSamplers();
+
+ SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
+ new VkDescriptorSetLayoutBinding[numSamplers]);
+ for (uint32_t i = 0; i < numSamplers; ++i) {
+ const GrVkGLSLSampler& sampler =
+ static_cast<const GrVkGLSLSampler&>(uniformHandler->getSampler(i));
+ SkASSERT(sampler.binding() == i);
+ dsSamplerBindings[i].binding = sampler.binding();
+ dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ dsSamplerBindings[i].descriptorCount = 1;
+ dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility());
+ dsSamplerBindings[i].pImmutableSamplers = nullptr;
+ }
+
+ VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
+ memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
+ dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ dsSamplerLayoutCreateInfo.pNext = nullptr;
+ dsSamplerLayoutCreateInfo.flags = 0;
+ dsSamplerLayoutCreateInfo.bindingCount = numSamplers;
+ // Setting to nullptr fixes an error in the param checker validation layer. Even though
+ // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is
+ // null.
+ dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr;
+
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(),
+ CreateDescriptorSetLayout(gpu->device(),
+ &dsSamplerLayoutCreateInfo,
+ nullptr,
+ &fDescLayout));
+ fDescCountPerSet = numSamplers;
+ } else {
+ SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
+ // Create Uniform Buffer Descriptor
+ // The vertex uniform buffer will have binding 0 and the fragment binding 1.
+ VkDescriptorSetLayoutBinding dsUniBindings[kUniformDescPerSet];
+ memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
+ dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
+ dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ dsUniBindings[0].descriptorCount = 1;
+ dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+ dsUniBindings[0].pImmutableSamplers = nullptr;
+ dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
+ dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ dsUniBindings[1].descriptorCount = 1;
+ dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+ dsUniBindings[1].pImmutableSamplers = nullptr;
+
+ VkDescriptorSetLayoutCreateInfo uniformLayoutCreateInfo;
+ memset(&uniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
+ uniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ uniformLayoutCreateInfo.pNext = nullptr;
+ uniformLayoutCreateInfo.flags = 0;
+ uniformLayoutCreateInfo.bindingCount = 2;
+ uniformLayoutCreateInfo.pBindings = dsUniBindings;
+
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateDescriptorSetLayout(gpu->device(),
+ &uniformLayoutCreateInfo,
+ nullptr,
+ &fDescLayout));
+ fDescCountPerSet = kUniformDescPerSet;
+ }
+
+ SkASSERT(fDescCountPerSet < kStartNumDescriptors);
+ fMaxDescriptors = kStartNumDescriptors;
+ SkASSERT(fMaxDescriptors > 0);
+ this->getNewPool(gpu);
+}
+
void GrVkDescriptorSetManager::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) {
if (fPool) {
fPool->unref(gpu);
@@ -101,9 +227,11 @@
}
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 (fDescLayout) {
+ GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout,
+ nullptr));
+ fDescLayout = VK_NULL_HANDLE;
+ }
if (fPool) {
fPool->unref(gpu);
diff --git a/src/gpu/vk/GrVkDescriptorSetManager.h b/src/gpu/vk/GrVkDescriptorSetManager.h
index 33a7720..0b11eb3 100644
--- a/src/gpu/vk/GrVkDescriptorSetManager.h
+++ b/src/gpu/vk/GrVkDescriptorSetManager.h
@@ -16,6 +16,7 @@
class GrVkDescriptorSet;
class GrVkGpu;
+class GrVkUniformHandler;
/**
* This class handles the allocation of descriptor sets for a given VkDescriptorSetLayout. It will
@@ -26,40 +27,25 @@
GR_DEFINE_RESOURCE_HANDLE_CLASS(Handle);
GrVkDescriptorSetManager(GrVkGpu* gpu,
- VkDescriptorSetLayout layout,
VkDescriptorType,
- uint32_t samplerCount);
+ const GrVkUniformHandler* handler = nullptr);
~GrVkDescriptorSetManager() {}
void abandon();
void release(const GrVkGpu* gpu);
+ VkDescriptorSetLayout layout() const { return fPoolManager.fDescLayout; }
+
const GrVkDescriptorSet* getDescriptorSet(GrVkGpu* gpu, const Handle& handle);
void recycleDescriptorSet(const GrVkDescriptorSet*);
- int isCompatible(uint32_t numSamplers) const { return numSamplers == fNumSamplerBindings; }
+ bool isCompatible(VkDescriptorType type, const GrVkUniformHandler*) const;
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(VkDescriptorType type, GrVkGpu* gpu,
+ const GrVkUniformHandler* handler = nullptr);
~DescriptorPoolManager() {
SkASSERT(!fDescLayout);
@@ -71,7 +57,7 @@
void freeGPUResources(const GrVkGpu* gpu);
void abandonGPUResources();
- VkDescriptorSetLayout fDescLayout; // Not owned by this class
+ VkDescriptorSetLayout fDescLayout;
VkDescriptorType fDescType;
uint32_t fDescCountPerSet;
uint32_t fMaxDescriptors;
@@ -80,7 +66,7 @@
private:
enum {
- kNumUniformDescPerSet = 2,
+ kUniformDescPerSet = 2,
kMaxDescriptors = 1024,
kStartNumDescriptors = 16, // must be less than kMaxUniformDescriptors
};
@@ -88,10 +74,9 @@
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;
+ DescriptorPoolManager fPoolManager;
+ SkTArray<const GrVkDescriptorSet*, true> fFreeSets;
+ SkSTArray<4, uint32_t> fBindingVisibilities;
};
#endif
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index ab9cff8..5b3fa8f 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -29,7 +29,7 @@
const GrVkPipelineState::Desc& desc,
GrVkPipeline* pipeline,
VkPipelineLayout layout,
- VkDescriptorSetLayout dsSamplerLayout,
+ const GrVkDescriptorSetManager::Handle& samplerDSHandle,
const BuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms,
uint32_t vertexUniformSize,
@@ -41,6 +41,8 @@
: fPipeline(pipeline)
, fPipelineLayout(layout)
, fUniformDescriptorSet(nullptr)
+ , fSamplerDescriptorSet(nullptr)
+ , fSamplerDSHandle(samplerDSHandle)
, fStartDS(SK_MaxS32)
, fDSCount(0)
, fBuiltinUniformHandles(builtinUniformHandles)
@@ -48,9 +50,7 @@
, fXferProcessor(xferProcessor)
, fFragmentProcessors(fragmentProcessors)
, fDesc(desc)
- , fDataManager(uniforms, vertexUniformSize, fragmentUniformSize)
- , fSamplerPoolManager(dsSamplerLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- numSamplers, gpu) {
+ , fDataManager(uniforms, vertexUniformSize, fragmentUniformSize) {
fSamplers.setReserve(numSamplers);
fTextureViews.setReserve(numSamplers);
fTextures.setReserve(numSamplers);
@@ -124,13 +124,16 @@
fFragmentUniformBuffer->release(gpu);
}
- fSamplerPoolManager.freeGPUResources(gpu);
-
if (fUniformDescriptorSet) {
fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
fUniformDescriptorSet = nullptr;
}
+ if (fSamplerDescriptorSet) {
+ fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
+ fSamplerDescriptorSet = nullptr;
+ }
+
this->freeTempResources(gpu);
}
@@ -158,12 +161,15 @@
}
fTextures.rewind();
- fSamplerPoolManager.abandonGPUResources();
-
if (fUniformDescriptorSet) {
fUniformDescriptorSet->unrefAndAbandon();
fUniformDescriptorSet = nullptr;
}
+
+ if (fSamplerDescriptorSet) {
+ fSamplerDescriptorSet->unrefAndAbandon();
+ fSamplerDescriptorSet = nullptr;
+ }
}
static void append_texture_bindings(const GrProcessor& processor,
@@ -204,8 +210,12 @@
// Get new descriptor sets
if (fNumSamplers) {
- fSamplerPoolManager.getNewDescriptorSet(gpu,
- &fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]);
+ if (fSamplerDescriptorSet) {
+ fSamplerDescriptorSet->recycle(gpu);
+ }
+ fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
+ int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
+ fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
this->writeSamplers(gpu, textureBindings, pipeline.getAllowSRGBInputs());
}
@@ -365,13 +375,13 @@
}
void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) {
- if (fSamplerPoolManager.fPool) {
- commandBuffer.addResource(fSamplerPoolManager.fPool);
- }
-
if (fUniformDescriptorSet) {
commandBuffer.addRecycledResource(fUniformDescriptorSet);
}
+ if (fSamplerDescriptorSet) {
+ commandBuffer.addRecycledResource(fSamplerDescriptorSet);
+ }
+
if (fVertexUniformBuffer.get()) {
commandBuffer.addResource(fVertexUniformBuffer->resource());
diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h
index 8988aa3..60c1db6 100644
--- a/src/gpu/vk/GrVkPipelineState.h
+++ b/src/gpu/vk/GrVkPipelineState.h
@@ -10,6 +10,7 @@
#define GrVkPipelineState_DEFINED
#include "GrStencilSettings.h"
+#include "GrVkDescriptorSetManager.h"
#include "GrVkImage.h"
#include "GrVkProgramDesc.h"
#include "GrVkPipelineStateDataManager.h"
@@ -151,7 +152,7 @@
const GrVkPipelineState::Desc&,
GrVkPipeline* pipeline,
VkPipelineLayout layout,
- VkDescriptorSetLayout dsSamplerLayout,
+ const GrVkDescriptorSetManager::Handle& samplerDSHandle,
const BuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms,
uint32_t vertexUniformSize,
@@ -260,6 +261,9 @@
// 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;
+ const GrVkDescriptorSet* fSamplerDescriptorSet;
+
+ const GrVkDescriptorSetManager::Handle fSamplerDSHandle;
// Meta data so we know which descriptor sets we are using and need to bind.
int fStartDS;
@@ -286,8 +290,6 @@
GrVkPipelineStateDataManager fDataManager;
- DescriptorPoolManager fSamplerPoolManager;
-
int fNumSamplers;
friend class GrVkPipelineStateBuilder;
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index d9d1b6c..a3032d7 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -7,6 +7,7 @@
#include "vk/GrVkPipelineStateBuilder.h"
+#include "vk/GrVkDescriptorSetManager.h"
#include "vk/GrVkGpu.h"
#include "vk/GrVkRenderPass.h"
#if USE_SKSL
@@ -60,21 +61,6 @@
outputColor.setLayoutQualifier("location = 0, index = 1");
}
-VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
- VkShaderStageFlags flags = 0;
-
- if (visibility & kVertex_GrShaderFlag) {
- flags |= VK_SHADER_STAGE_VERTEX_BIT;
- }
- if (visibility & kGeometry_GrShaderFlag) {
- flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
- }
- if (visibility & kFragment_GrShaderFlag) {
- flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
- }
- return flags;
-}
-
#if USE_SKSL
SkSL::Program::Kind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) {
if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
@@ -124,7 +110,7 @@
} else {
#if USE_SKSL
- bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage),
+ bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage),
std::string(shaderString.c_str()),
&code);
if (!result) {
@@ -194,39 +180,14 @@
VkShaderModule vertShaderModule;
VkShaderModule fragShaderModule;
- uint32_t numSamplers = (uint32_t)fUniformHandler.numSamplers();
-
- SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
- new VkDescriptorSetLayoutBinding[numSamplers]);
- for (uint32_t i = 0; i < numSamplers; ++i) {
- const GrVkGLSLSampler& sampler =
- static_cast<const GrVkGLSLSampler&>(fUniformHandler.getSampler(i));
- SkASSERT(sampler.binding() == i);
- dsSamplerBindings[i].binding = sampler.binding();
- dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- dsSamplerBindings[i].descriptorCount = 1;
- dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility());
- dsSamplerBindings[i].pImmutableSamplers = nullptr;
- }
-
- VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
- memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
- dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
- dsSamplerLayoutCreateInfo.pNext = nullptr;
- dsSamplerLayoutCreateInfo.flags = 0;
- dsSamplerLayoutCreateInfo.bindingCount = numSamplers;
- // Setting to nullptr fixes an error in the param checker validation layer. Even though
- // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
- dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr;
-
- GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
- CreateDescriptorSetLayout(fGpu->device(),
- &dsSamplerLayoutCreateInfo,
- nullptr,
- &dsLayout[GrVkUniformHandler::kSamplerDescSet]));
-
+ GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
// This layout is not owned by the PipelineStateBuilder and thus should no be destroyed
- dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = fGpu->resourceProvider().getUniDSLayout();
+ dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
+
+ GrVkDescriptorSetManager::Handle samplerDSHandle;
+ resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
+ dsLayout[GrVkUniformHandler::kSamplerDescSet] =
+ resourceProvider.getSamplerDSLayout(samplerDSHandle);
// Create the VkPipelineLayout
VkPipelineLayoutCreateInfo layoutCreateInfo;
@@ -266,7 +227,6 @@
&fragShaderModule,
&shaderStageInfo[1]));
- GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
fPrimProc,
shaderStageInfo,
@@ -295,13 +255,14 @@
desc,
pipeline,
pipelineLayout,
- dsLayout[GrVkUniformHandler::kSamplerDescSet],
+ samplerDSHandle,
fUniformHandles,
fUniformHandler.fUniforms,
fUniformHandler.fCurrentVertexUBOOffset,
fUniformHandler.fCurrentFragmentUBOOffset,
- numSamplers,
+ (uint32_t)fUniformHandler.numSamplers(),
fGeometryProcessor,
fXferProcessor,
fFragmentProcessors);
}
+
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index abe07bd..b1817cf 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -9,6 +9,7 @@
#include "GrTextureParams.h"
#include "GrVkCommandBuffer.h"
+#include "GrVkGLSLSampler.h"
#include "GrVkPipeline.h"
#include "GrVkRenderTarget.h"
#include "GrVkSampler.h"
@@ -22,8 +23,7 @@
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
: fGpu(gpu)
- , fPipelineCache(VK_NULL_HANDLE)
- , fCurrentUniformDescCount(0) {
+ , fPipelineCache(VK_NULL_HANDLE) {
fPipelineStateCache = new PipelineStateCache(gpu);
}
@@ -33,38 +33,6 @@
delete fPipelineStateCache;
}
-void GrVkResourceProvider::initUniformDescObjects() {
- // Create Uniform Buffer Descriptor
- // The vertex uniform buffer will have binding 0 and the fragment binding 1.
- VkDescriptorSetLayoutBinding dsUniBindings[2];
- memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
- dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
- dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- dsUniBindings[0].descriptorCount = 1;
- dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
- dsUniBindings[0].pImmutableSamplers = nullptr;
- dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
- dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- dsUniBindings[1].descriptorCount = 1;
- dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
- dsUniBindings[1].pImmutableSamplers = nullptr;
-
- VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo;
- memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
- dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
- dsUniformLayoutCreateInfo.pNext = nullptr;
- dsUniformLayoutCreateInfo.flags = 0;
- dsUniformLayoutCreateInfo.bindingCount = 2;
- dsUniformLayoutCreateInfo.pBindings = dsUniBindings;
-
- GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(fGpu->device(),
- &dsUniformLayoutCreateInfo,
- nullptr,
- &fUniformDescLayout));
-
- this->getDescSetHandle(0, fUniformDescLayout, &fUniformDSHandle);
-}
-
void GrVkResourceProvider::init() {
VkPipelineCacheCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkPipelineCacheCreateInfo));
@@ -81,7 +49,10 @@
fPipelineCache = VK_NULL_HANDLE;
}
- this->initUniformDescObjects();
+ // Init uniform descriptor objects
+ fDescriptorSetManagers.emplace_back(fGpu, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
+ SkASSERT(1 == fDescriptorSetManagers.count());
+ fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
}
GrVkPipeline* GrVkResourceProvider::createPipeline(const GrPipeline& pipeline,
@@ -190,31 +161,44 @@
return fPipelineStateCache->refPipelineState(pipeline, proc, primitiveType, renderPass);
}
-
-void GrVkResourceProvider::getDescSetHandle(uint32_t numSamplers, VkDescriptorSetLayout layout,
- GrVkDescriptorSetManager::Handle* handle) {
+void GrVkResourceProvider::getSamplerDescriptorSetHandle(const GrVkUniformHandler& uniformHandler,
+ GrVkDescriptorSetManager::Handle* handle) {
SkASSERT(handle);
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
- if (fDescriptorSetManagers[i].isCompatible(numSamplers)) {
+ if (fDescriptorSetManagers[i].isCompatible(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ &uniformHandler)) {
*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);
+ fDescriptorSetManagers.emplace_back(fGpu, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ &uniformHandler);
*handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1);
}
+VkDescriptorSetLayout GrVkResourceProvider::getUniformDSLayout() const {
+ SkASSERT(fUniformDSHandle.isValid());
+ return fDescriptorSetManagers[fUniformDSHandle.toIndex()].layout();
+}
+
+VkDescriptorSetLayout GrVkResourceProvider::getSamplerDSLayout(
+ const GrVkDescriptorSetManager::Handle& handle) const {
+ SkASSERT(handle.isValid());
+ return fDescriptorSetManagers[handle.toIndex()].layout();
+}
+
const GrVkDescriptorSet* GrVkResourceProvider::getUniformDescriptorSet() {
SkASSERT(fUniformDSHandle.isValid());
return fDescriptorSetManagers[fUniformDSHandle.toIndex()].getDescriptorSet(fGpu,
fUniformDSHandle);
}
+const GrVkDescriptorSet* GrVkResourceProvider::getSamplerDescriptorSet(
+ const GrVkDescriptorSetManager::Handle& handle) {
+ SkASSERT(handle.isValid());
+ return fDescriptorSetManagers[handle.toIndex()].getDescriptorSet(fGpu, handle);
+}
void GrVkResourceProvider::recycleDescriptorSet(const GrVkDescriptorSet* descSet,
const GrVkDescriptorSetManager::Handle& handle) {
@@ -326,13 +310,6 @@
GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
fPipelineCache = VK_NULL_HANDLE;
- if (fUniformDescLayout) {
- GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(),
- fUniformDescLayout,
- nullptr));
- fUniformDescLayout = VK_NULL_HANDLE;
- }
-
// We must release/destroy all command buffers and pipeline states before releasing the
// GrVkDescriptorSetManagers
for (int i = 0; i < fDescriptorSetManagers.count(); ++i) {
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 0660e91..9cd8217 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -32,6 +32,7 @@
class GrVkRenderTarget;
class GrVkSampler;
class GrVkSecondaryCommandBuffer;
+class GrVkUniformHandler;
class GrVkResourceProvider {
public:
@@ -101,27 +102,28 @@
GrPrimitiveType,
const GrVkRenderPass& renderPass);
- // 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);
+ void getSamplerDescriptorSetHandle(const GrVkUniformHandler&,
+ GrVkDescriptorSetManager::Handle* 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 getUniformDSLayout() const;
+
+ // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. 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 getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
// 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 GrVkDescriptorSetManager::Handle passed in. 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.
@@ -216,9 +218,6 @@
int fLastReturnedIndex;
};
- // Initialiaze the vkDescriptorSetLayout used for allocating new uniform buffer descritpor sets.
- void initUniformDescObjects();
-
GrVkGpu* fGpu;
// Central cache for creating pipelines
@@ -227,15 +226,15 @@
SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
// Array of PrimaryCommandBuffers that are currently in flight
- SkSTArray<4, GrVkPrimaryCommandBuffer*> fActiveCommandBuffers;
+ SkSTArray<4, GrVkPrimaryCommandBuffer*, true> fActiveCommandBuffers;
// Array of available primary command buffers that are not in flight
- SkSTArray<4, GrVkPrimaryCommandBuffer*> fAvailableCommandBuffers;
+ SkSTArray<4, GrVkPrimaryCommandBuffer*, true> fAvailableCommandBuffers;
// Array of available secondary command buffers
- SkSTArray<16, GrVkSecondaryCommandBuffer*> fAvailableSecondaryCommandBuffers;
+ SkSTArray<16, GrVkSecondaryCommandBuffer*, true> fAvailableSecondaryCommandBuffers;
// Array of available uniform buffer resources
- SkSTArray<16, const GrVkResource*> fAvailableUniformBufferResources;
+ SkSTArray<16, const GrVkResource*, true> fAvailableUniformBufferResources;
// Stores GrVkSampler objects that we've already created so we can reuse them across multiple
// GrVkPipelineStates
@@ -244,21 +243,9 @@
// Cache of GrVkPipelineStates
PipelineStateCache* fPipelineStateCache;
- SkSTArray<4, GrVkDescriptorSetManager> fDescriptorSetManagers;
+ SkSTArray<4, GrVkDescriptorSetManager, true> fDescriptorSetManagers;
- GrVkDescriptorSetManager::Handle fUniformDSHandle;
-
- // Current pool to allocate uniform descriptor sets from
- VkDescriptorSetLayout fUniformDescLayout;
- //Curent number of uniform descriptors allocated from the pool
- int fCurrentUniformDescCount;
- int fCurrMaxUniDescriptors;
-
- enum {
- kMaxUniformDescriptors = 1024,
- kNumUniformDescPerSet = 2,
- kStartNumUniformDescriptors = 16, // must be less than kMaxUniformDescriptors
- };
+ GrVkDescriptorSetManager::Handle fUniformDSHandle;
};
#endif
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index f6060b0..a6ea936 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -90,6 +90,7 @@
uint32_t fCurrentSamplerBinding;
friend class GrVkPipelineStateBuilder;
+ friend class GrVkDescriptorSetManager;
typedef GrGLSLUniformHandler INHERITED;
};