Hash :
daedf4d2
        
        Author :
  
        
        Date :
2018-03-16T09:28:53
        
      
Vulkan: Add a DynamicDescriptorPool class. In order to manage the life of descriptor sets better and allow allocating descriptor sets infinitely. Bug:angleproject:2392 Change-Id: Ia3c7145d85d697c04e8008e8d8839c428dd2e864 Reviewed-on: https://chromium-review.googlesource.com/966786 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DynamicDescriptorPool:
//    Uses DescriptorPool to allocate descriptor sets as needed. If the descriptor pool
//    is full, we simply allocate a new pool to keep allocating descriptor sets as needed and
//    leave the renderer take care of the life time of the pools that become unused.
//
#include "DynamicDescriptorPool.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx
{
namespace
{
// TODO(jmadill): Pick non-arbitrary max.
constexpr uint32_t kMaxSets = 2048;
}  // anonymous namespace
DynamicDescriptorPool::DynamicDescriptorPool()
    : mCurrentAllocatedDescriptorSetCount(0),
      mUniformBufferDescriptorsPerSet(0),
      mCombinedImageSamplerDescriptorsPerSet(0)
{
}
DynamicDescriptorPool::~DynamicDescriptorPool()
{
}
void DynamicDescriptorPool::destroy(RendererVk *rendererVk)
{
    ASSERT(mCurrentDescriptorSetPool.valid());
    rendererVk->releaseResource(*this, &mCurrentDescriptorSetPool);
}
vk::Error DynamicDescriptorPool::init(const VkDevice &device,
                                      uint32_t uniformBufferDescriptorsPerSet,
                                      uint32_t combinedImageSamplerDescriptorsPerSet)
{
    ASSERT(!mCurrentDescriptorSetPool.valid() && mCurrentAllocatedDescriptorSetCount == 0);
    mUniformBufferDescriptorsPerSet        = uniformBufferDescriptorsPerSet;
    mCombinedImageSamplerDescriptorsPerSet = combinedImageSamplerDescriptorsPerSet;
    ANGLE_TRY(allocateNewPool(device));
    return vk::NoError();
}
vk::Error DynamicDescriptorPool::allocateDescriptorSets(
    ContextVk *contextVk,
    const VkDescriptorSetLayout *descriptorSetLayout,
    uint32_t descriptorSetCount,
    VkDescriptorSet *descriptorSetsOut)
{
    updateQueueSerial(contextVk->getRenderer()->getCurrentQueueSerial());
    if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > kMaxSets)
    {
        // We will bust the limit of descriptor set with this allocation so we need to get a new
        // pool for it.
        contextVk->getRenderer()->releaseResource(*this, &mCurrentDescriptorSetPool);
        ANGLE_TRY(allocateNewPool(contextVk->getDevice()));
    }
    VkDescriptorSetAllocateInfo allocInfo;
    allocInfo.sType              = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    allocInfo.pNext              = nullptr;
    allocInfo.descriptorPool     = mCurrentDescriptorSetPool.getHandle();
    allocInfo.descriptorSetCount = descriptorSetCount;
    allocInfo.pSetLayouts        = descriptorSetLayout;
    ANGLE_TRY(mCurrentDescriptorSetPool.allocateDescriptorSets(contextVk->getDevice(), allocInfo,
                                                               descriptorSetsOut));
    mCurrentAllocatedDescriptorSetCount += allocInfo.descriptorSetCount;
    return vk::NoError();
}
vk::Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
{
    VkDescriptorPoolSize poolSizes[DescriptorPoolIndexCount];
    poolSizes[UniformBufferIndex].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
    poolSizes[UniformBufferIndex].descriptorCount =
        mUniformBufferDescriptorsPerSet * kMaxSets / DescriptorPoolIndexCount;
    poolSizes[TextureIndex].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    poolSizes[TextureIndex].descriptorCount =
        mCombinedImageSamplerDescriptorsPerSet * kMaxSets / DescriptorPoolIndexCount;
    VkDescriptorPoolCreateInfo descriptorPoolInfo;
    descriptorPoolInfo.sType   = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
    descriptorPoolInfo.pNext   = nullptr;
    descriptorPoolInfo.flags   = 0;
    descriptorPoolInfo.maxSets = kMaxSets;
    // Reserve pools for uniform blocks and textures.
    descriptorPoolInfo.poolSizeCount = DescriptorPoolIndexCount;
    descriptorPoolInfo.pPoolSizes    = poolSizes;
    mCurrentAllocatedDescriptorSetCount = 0;
    ANGLE_TRY(mCurrentDescriptorSetPool.init(device, descriptorPoolInfo));
    return vk::NoError();
}
}  // namespace rx