Commit 8a4c49fb by Jamie Madill Committed by Commit Bot

Vulkan: Refactor DynamicDescriptorPool.

Changes the set counting to use a free count by descriptor type. Also changes the init to take a pool size count that more closely mirrors Vulkan. Will lead to a fix for descriptor set recreation. Bug: angleproject:2678 Change-Id: I26816befec28ebb866fb0f3aaba27d2bc1d3be43 Reviewed-on: https://chromium-review.googlesource.com/1110661Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 3cacf69b
......@@ -66,7 +66,7 @@ ContextVk::~ContextVk()
void ContextVk::onDestroy(const gl::Context *context)
{
mIncompleteTextures.onDestroy(context);
mDynamicDescriptorPool.destroy(mRenderer);
mDynamicDescriptorPool.destroy(getDevice());
}
gl::Error ContextVk::getIncompleteTexture(const gl::Context *context,
......@@ -80,8 +80,14 @@ gl::Error ContextVk::getIncompleteTexture(const gl::Context *context,
gl::Error ContextVk::initialize()
{
ANGLE_TRY(mDynamicDescriptorPool.init(this->getDevice(), GetUniformBufferDescriptorCount(),
mRenderer->getMaxActiveTextures()));
// Note that this may reserve more sets than strictly necessary for a particular layout.
vk::DescriptorPoolSizes poolSizes;
poolSizes.push_back({VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
GetUniformBufferDescriptorCount() * vk::kDefaultDescriptorPoolMaxSets});
poolSizes.push_back({VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
mRenderer->getMaxActiveTextures() * vk::kDefaultDescriptorPoolMaxSets});
ANGLE_TRY(mDynamicDescriptorPool.init(getDevice(), poolSizes));
mPipelineDesc.reset(new vk::PipelineDesc());
mPipelineDesc->initDefaults();
......
......@@ -749,8 +749,9 @@ vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descri
const vk::DescriptorSetLayout &descriptorSetLayout =
mDescriptorSetLayouts[descriptorSetIndex].get();
ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout.ptr(), 1,
&mDescriptorSets[descriptorSetIndex]));
ANGLE_TRY(dynamicDescriptorPool->allocateSets(contextVk, descriptorSetLayout.ptr(), 1,
descriptorSetIndex,
&mDescriptorSets[descriptorSetIndex]));
return vk::NoError();
}
......
......@@ -647,7 +647,6 @@ constexpr uint32_t kVertexUniformsBindingIndex = 0;
constexpr uint32_t kFragmentUniformsBindingIndex = 1;
constexpr uint32_t kUniformsDescriptorSetIndex = 0;
constexpr uint32_t kTextureDescriptorSetIndex = 1;
constexpr uint32_t kDescriptorSetCount = 2;
} // namespace rx
......
......@@ -19,9 +19,6 @@ namespace vk
{
namespace
{
// TODO(jmadill): Pick non-arbitrary max.
constexpr uint32_t kDefaultDynamicDescriptorPoolMaxSets = 2048;
constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage =
(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
constexpr int kLineLoopDynamicBufferMinSize = 1024 * 1024;
......@@ -80,6 +77,19 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType)
}
}
size_t GetDescriptorSetIndexfromType(VkDescriptorType descriptorType)
{
switch (descriptorType)
{
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
return kUniformsDescriptorSetIndex;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
return kTextureDescriptorSetIndex;
default:
UNREACHABLE();
return 0;
}
}
} // anonymous namespace
// DynamicBuffer implementation.
......@@ -268,78 +278,62 @@ void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
// DynamicDescriptorPool implementation.
DynamicDescriptorPool::DynamicDescriptorPool()
: mMaxSetsPerPool(kDefaultDynamicDescriptorPoolMaxSets),
mCurrentAllocatedDescriptorSetCount(0),
mUniformBufferDescriptorsPerSet(0),
mCombinedImageSamplerDescriptorsPerSet(0)
: mMaxSetsPerPool(kDefaultDescriptorPoolMaxSets), mCurrentSetsCount(0), mFreeDescriptorSets({})
{
}
DynamicDescriptorPool::~DynamicDescriptorPool()
{
}
DynamicDescriptorPool::~DynamicDescriptorPool() = default;
void DynamicDescriptorPool::destroy(RendererVk *rendererVk)
Error DynamicDescriptorPool::init(VkDevice device, const DescriptorPoolSizes &poolSizes)
{
// It's possible that mCurrentDescriptorSetPool is not valid if the owning context was never
// made current/initialized
mCurrentDescriptorSetPool.destroy(rendererVk->getDevice());
}
Error DynamicDescriptorPool::init(const VkDevice &device,
uint32_t uniformBufferDescriptorsPerSet,
uint32_t combinedImageSamplerDescriptorsPerSet)
{
ASSERT(!mCurrentDescriptorSetPool.valid() && mCurrentAllocatedDescriptorSetCount == 0);
// Note that this may allocate more sets than strictly necessary for a particular layout.
mUniformBufferDescriptorsPerSet = uniformBufferDescriptorsPerSet;
mCombinedImageSamplerDescriptorsPerSet = combinedImageSamplerDescriptorsPerSet;
ASSERT(!mCurrentDescriptorPool.valid());
mPoolSizes = poolSizes;
ANGLE_TRY(allocateNewPool(device));
return NoError();
}
Error DynamicDescriptorPool::allocateDescriptorSets(
ContextVk *contextVk,
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut)
void DynamicDescriptorPool::destroy(VkDevice device)
{
mCurrentDescriptorPool.destroy(device);
}
Error DynamicDescriptorPool::allocateSets(ContextVk *contextVk,
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount,
uint32_t descriptorSetIndex,
VkDescriptorSet *descriptorSetsOut)
{
if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > mMaxSetsPerPool)
if (mFreeDescriptorSets[descriptorSetIndex] < descriptorSetCount ||
mCurrentSetsCount >= mMaxSetsPerPool)
{
RendererVk *renderer = contextVk->getRenderer();
Serial currentSerial = renderer->getCurrentQueueSerial();
// We will bust the limit of descriptor set with this allocation so we need to get a new
// pool for it.
renderer->releaseObject(currentSerial, &mCurrentDescriptorSetPool);
renderer->releaseObject(currentSerial, &mCurrentDescriptorPool);
ANGLE_TRY(allocateNewPool(contextVk->getDevice()));
}
VkDescriptorSetAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.descriptorPool = mCurrentDescriptorSetPool.getHandle();
allocInfo.descriptorPool = mCurrentDescriptorPool.getHandle();
allocInfo.descriptorSetCount = descriptorSetCount;
allocInfo.pSetLayouts = descriptorSetLayout;
ANGLE_TRY(mCurrentDescriptorSetPool.allocateDescriptorSets(contextVk->getDevice(), allocInfo,
descriptorSetsOut));
mCurrentAllocatedDescriptorSetCount += allocInfo.descriptorSetCount;
ANGLE_TRY(mCurrentDescriptorPool.allocateDescriptorSets(contextVk->getDevice(), allocInfo,
descriptorSetsOut));
ASSERT(mFreeDescriptorSets[descriptorSetIndex] >= descriptorSetCount);
mFreeDescriptorSets[descriptorSetIndex] -= descriptorSetCount;
mCurrentSetsCount++;
return NoError();
}
Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
Error DynamicDescriptorPool::allocateNewPool(VkDevice device)
{
VkDescriptorPoolSize poolSizes[kDescriptorSetCount];
poolSizes[kUniformsDescriptorSetIndex].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
poolSizes[kUniformsDescriptorSetIndex].descriptorCount =
mUniformBufferDescriptorsPerSet * mMaxSetsPerPool;
poolSizes[kTextureDescriptorSetIndex].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[kTextureDescriptorSetIndex].descriptorCount =
mCombinedImageSamplerDescriptorsPerSet * mMaxSetsPerPool;
VkDescriptorPoolCreateInfo descriptorPoolInfo;
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.pNext = nullptr;
......@@ -347,11 +341,19 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
descriptorPoolInfo.maxSets = mMaxSetsPerPool;
// Reserve pools for uniform blocks and textures.
descriptorPoolInfo.poolSizeCount = kDescriptorSetCount;
descriptorPoolInfo.pPoolSizes = poolSizes;
descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(mPoolSizes.size());
descriptorPoolInfo.pPoolSizes = mPoolSizes.data();
mFreeDescriptorSets.fill(0);
mCurrentSetsCount = 0;
for (const VkDescriptorPoolSize &poolSize : mPoolSizes)
{
size_t setIndex = GetDescriptorSetIndexfromType(poolSize.type);
mFreeDescriptorSets[setIndex] += poolSize.descriptorCount;
}
mCurrentAllocatedDescriptorSetCount = 0;
ANGLE_TRY(mCurrentDescriptorSetPool.init(device, descriptorPoolInfo));
ANGLE_TRY(mCurrentDescriptorPool.init(device, descriptorPoolInfo));
return NoError();
}
......
......@@ -90,33 +90,39 @@ class DynamicBuffer : angle::NonCopyable
// using the maximum number of descriptor sets and buffers with each allocation. Currently: 2
// (Vertex/Fragment) uniform buffers and 64 (MAX_ACTIVE_TEXTURES) image/samplers.
using DescriptorPoolSizes = angle::FixedVector<VkDescriptorPoolSize, kMaxDescriptorSetLayouts>;
// This is an arbitrary max. We can change this later if necessary.
constexpr uint32_t kDefaultDescriptorPoolMaxSets = 2048;
class DynamicDescriptorPool final : angle::NonCopyable
{
public:
DynamicDescriptorPool();
~DynamicDescriptorPool();
void destroy(RendererVk *rendererVk);
Error init(const VkDevice &device,
uint32_t uniformBufferDescriptorsPerSet,
uint32_t combinedImageSamplerDescriptorsPerSet);
// It is an undefined behavior to pass a different descriptorSetLayout from call to call.
Error allocateDescriptorSets(ContextVk *contextVk,
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut);
Error init(VkDevice device, const DescriptorPoolSizes &poolSizes);
void destroy(VkDevice device);
// We use the descriptor type to help count the number of free sets.
// By convention, sets are indexed according to the constants in vk_cache_utils.h.
Error allocateSets(ContextVk *contextVk,
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount,
uint32_t descriptorSetIndex,
VkDescriptorSet *descriptorSetsOut);
// For testing only!
void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool);
private:
Error allocateNewPool(const VkDevice &device);
Error allocateNewPool(VkDevice device);
uint32_t mMaxSetsPerPool;
DescriptorPool mCurrentDescriptorSetPool;
size_t mCurrentAllocatedDescriptorSetCount;
uint32_t mUniformBufferDescriptorsPerSet;
uint32_t mCombinedImageSamplerDescriptorsPerSet;
uint32_t mCurrentSetsCount;
DescriptorPool mCurrentDescriptorPool;
DescriptorPoolSizes mPoolSizes;
DescriptorSetLayoutArray<uint32_t> mFreeDescriptorSets;
};
// This class' responsibility is to create index buffers needed to support line loops in Vulkan.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment