Reuse sampler descriptor set allocations in Vulkan
authoregdaniel <egdaniel@google.com>
Tue, 26 Jul 2016 14:19:47 +0000 (07:19 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 26 Jul 2016 14:19:48 +0000 (07:19 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2172873003

Review-Url: https://codereview.chromium.org/2172873003

src/gpu/vk/GrVkDescriptorSetManager.cpp
src/gpu/vk/GrVkDescriptorSetManager.h
src/gpu/vk/GrVkPipelineState.cpp
src/gpu/vk/GrVkPipelineState.h
src/gpu/vk/GrVkPipelineStateBuilder.cpp
src/gpu/vk/GrVkResourceProvider.cpp
src/gpu/vk/GrVkResourceProvider.h
src/gpu/vk/GrVkUniformHandler.h

index 51138e1..9f44d65 100644 (file)
 #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 @@ void GrVkDescriptorSetManager::abandon() {
     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::getNewDescriptorSet(GrVkGp
 }
 
 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);
index 33a7720..0b11eb3 100644 (file)
@@ -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 @@ public:
     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 @@ private:
         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:
 
     private:
         enum {
-            kNumUniformDescPerSet = 2,
+            kUniformDescPerSet = 2,
             kMaxDescriptors = 1024,
             kStartNumDescriptors = 16, // must be less than kMaxUniformDescriptors
         };
@@ -88,10 +74,9 @@ private:
         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
index ab9cff8..5b3fa8f 100644 (file)
@@ -29,7 +29,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
                                      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 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
     : fPipeline(pipeline)
     , fPipelineLayout(layout)
     , fUniformDescriptorSet(nullptr)
+    , fSamplerDescriptorSet(nullptr)
+    , fSamplerDSHandle(samplerDSHandle)
     , fStartDS(SK_MaxS32)
     , fDSCount(0)
     , fBuiltinUniformHandles(builtinUniformHandles)
@@ -48,9 +50,7 @@ GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
     , 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 @@ void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) {
         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 @@ void GrVkPipelineState::abandonGPUResources() {
     }
     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 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
 
     // 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::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffe
 }
 
 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());
index 8988aa3..60c1db6 100644 (file)
@@ -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 @@ private:
                       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 @@ private:
     // 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 @@ private:
 
     GrVkPipelineStateDataManager fDataManager;
 
-    DescriptorPoolManager fSamplerPoolManager;
-
     int fNumSamplers;
 
     friend class GrVkPipelineStateBuilder;
index d9d1b6c..a3032d7 100644 (file)
@@ -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 @@ void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrGLSLShaderVar& o
     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 @@ bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
     } 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 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
     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 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
                                         &fragShaderModule,
                                         &shaderStageInfo[1]));
 
-    GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
     GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
                                                              fPrimProc,
                                                              shaderStageInfo,
@@ -295,13 +255,14 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveT
                                  desc,
                                  pipeline,
                                  pipelineLayout,
-                                 dsLayout[GrVkUniformHandler::kSamplerDescSet],
+                                 samplerDSHandle,
                                  fUniformHandles,
                                  fUniformHandler.fUniforms,
                                  fUniformHandler.fCurrentVertexUBOOffset,
                                  fUniformHandler.fCurrentFragmentUBOOffset,
-                                 numSamplers,
+                                 (uint32_t)fUniformHandler.numSamplers(),
                                  fGeometryProcessor,
                                  fXferProcessor,
                                  fFragmentProcessors);
 }
+
index abe07bd..b1817cf 100644 (file)
@@ -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 @@ uint32_t GrVkResource::fKeyCounter = 0;
 
 GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
     : fGpu(gpu)
-    , fPipelineCache(VK_NULL_HANDLE)
-    , fCurrentUniformDescCount(0) {
+    , fPipelineCache(VK_NULL_HANDLE) {
     fPipelineStateCache = new PipelineStateCache(gpu);
 }
 
@@ -33,38 +33,6 @@ GrVkResourceProvider::~GrVkResourceProvider() {
     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 @@ void GrVkResourceProvider::init() {
         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 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::findOrCreateCompatiblePipelineSta
     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 @@ void GrVkResourceProvider::destroyResources() {
     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) {
index 0660e91..9cd8217 100644 (file)
@@ -32,6 +32,7 @@ class GrVkPrimaryCommandBuffer;
 class GrVkRenderTarget;
 class GrVkSampler;
 class GrVkSecondaryCommandBuffer;
+class GrVkUniformHandler;
 
 class GrVkResourceProvider {
 public:
@@ -101,27 +102,28 @@ 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.
@@ -216,9 +218,6 @@ private:
         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 @@ private:
     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 @@ private:
     // 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
index f6060b0..a6ea936 100644 (file)
@@ -90,6 +90,7 @@ private:
     uint32_t         fCurrentSamplerBinding;
 
     friend class GrVkPipelineStateBuilder;
+    friend class GrVkDescriptorSetManager;
 
     typedef GrGLSLUniformHandler INHERITED;
 };