#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,
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);
}
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);
class GrVkDescriptorSet;
class GrVkGpu;
+class GrVkUniformHandler;
/**
* This class handles the allocation of descriptor sets for a given VkDescriptorSetLayout. It will
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);
void freeGPUResources(const GrVkGpu* gpu);
void abandonGPUResources();
- VkDescriptorSetLayout fDescLayout; // Not owned by this class
+ VkDescriptorSetLayout fDescLayout;
VkDescriptorType fDescType;
uint32_t fDescCountPerSet;
uint32_t fMaxDescriptors;
private:
enum {
- kNumUniformDescPerSet = 2,
+ kUniformDescPerSet = 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;
+ DescriptorPoolManager fPoolManager;
+ SkTArray<const GrVkDescriptorSet*, true> fFreeSets;
+ SkSTArray<4, uint32_t> fBindingVisibilities;
};
#endif
const GrVkPipelineState::Desc& desc,
GrVkPipeline* pipeline,
VkPipelineLayout layout,
- VkDescriptorSetLayout dsSamplerLayout,
+ const GrVkDescriptorSetManager::Handle& samplerDSHandle,
const BuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms,
uint32_t vertexUniformSize,
: fPipeline(pipeline)
, fPipelineLayout(layout)
, fUniformDescriptorSet(nullptr)
+ , fSamplerDescriptorSet(nullptr)
+ , fSamplerDSHandle(samplerDSHandle)
, fStartDS(SK_MaxS32)
, fDSCount(0)
, fBuiltinUniformHandles(builtinUniformHandles)
, 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);
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);
}
}
fTextures.rewind();
- fSamplerPoolManager.abandonGPUResources();
-
if (fUniformDescriptorSet) {
fUniformDescriptorSet->unrefAndAbandon();
fUniformDescriptorSet = nullptr;
}
+
+ if (fSamplerDescriptorSet) {
+ fSamplerDescriptorSet->unrefAndAbandon();
+ fSamplerDescriptorSet = nullptr;
+ }
}
static void append_texture_bindings(const GrProcessor& processor,
// 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());
}
}
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());
#define GrVkPipelineState_DEFINED
#include "GrStencilSettings.h"
+#include "GrVkDescriptorSetManager.h"
#include "GrVkImage.h"
#include "GrVkProgramDesc.h"
#include "GrVkPipelineStateDataManager.h"
const GrVkPipelineState::Desc&,
GrVkPipeline* pipeline,
VkPipelineLayout layout,
- VkDescriptorSetLayout dsSamplerLayout,
+ const GrVkDescriptorSetManager::Handle& samplerDSHandle,
const BuiltinUniformHandles& builtinUniformHandles,
const UniformInfoArray& uniforms,
uint32_t vertexUniformSize,
// 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;
GrVkPipelineStateDataManager fDataManager;
- DescriptorPoolManager fSamplerPoolManager;
-
int fNumSamplers;
friend class GrVkPipelineStateBuilder;
#include "vk/GrVkPipelineStateBuilder.h"
+#include "vk/GrVkDescriptorSetManager.h"
#include "vk/GrVkGpu.h"
#include "vk/GrVkRenderPass.h"
#if USE_SKSL
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) {
} 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) {
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;
&fragShaderModule,
&shaderStageInfo[1]));
- GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
fPrimProc,
shaderStageInfo,
desc,
pipeline,
pipelineLayout,
- dsLayout[GrVkUniformHandler::kSamplerDescSet],
+ samplerDSHandle,
fUniformHandles,
fUniformHandler.fUniforms,
fUniformHandler.fCurrentVertexUBOOffset,
fUniformHandler.fCurrentFragmentUBOOffset,
- numSamplers,
+ (uint32_t)fUniformHandler.numSamplers(),
fGeometryProcessor,
fXferProcessor,
fFragmentProcessors);
}
+
#include "GrTextureParams.h"
#include "GrVkCommandBuffer.h"
+#include "GrVkGLSLSampler.h"
#include "GrVkPipeline.h"
#include "GrVkRenderTarget.h"
#include "GrVkSampler.h"
GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
: fGpu(gpu)
- , fPipelineCache(VK_NULL_HANDLE)
- , fCurrentUniformDescCount(0) {
+ , fPipelineCache(VK_NULL_HANDLE) {
fPipelineStateCache = new PipelineStateCache(gpu);
}
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));
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,
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) {
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) {
class GrVkRenderTarget;
class GrVkSampler;
class GrVkSecondaryCommandBuffer;
+class GrVkUniformHandler;
class GrVkResourceProvider {
public:
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.
int fLastReturnedIndex;
};
- // Initialiaze the vkDescriptorSetLayout used for allocating new uniform buffer descritpor sets.
- void initUniformDescObjects();
-
GrVkGpu* fGpu;
// Central cache for creating pipelines
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
// 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
uint32_t fCurrentSamplerBinding;
friend class GrVkPipelineStateBuilder;
+ friend class GrVkDescriptorSetManager;
typedef GrGLSLUniformHandler INHERITED;
};