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() ...@@ -66,7 +66,7 @@ ContextVk::~ContextVk()
void ContextVk::onDestroy(const gl::Context *context) void ContextVk::onDestroy(const gl::Context *context)
{ {
mIncompleteTextures.onDestroy(context); mIncompleteTextures.onDestroy(context);
mDynamicDescriptorPool.destroy(mRenderer); mDynamicDescriptorPool.destroy(getDevice());
} }
gl::Error ContextVk::getIncompleteTexture(const gl::Context *context, gl::Error ContextVk::getIncompleteTexture(const gl::Context *context,
...@@ -80,8 +80,14 @@ gl::Error ContextVk::getIncompleteTexture(const gl::Context *context, ...@@ -80,8 +80,14 @@ gl::Error ContextVk::getIncompleteTexture(const gl::Context *context,
gl::Error ContextVk::initialize() gl::Error ContextVk::initialize()
{ {
ANGLE_TRY(mDynamicDescriptorPool.init(this->getDevice(), GetUniformBufferDescriptorCount(), // Note that this may reserve more sets than strictly necessary for a particular layout.
mRenderer->getMaxActiveTextures())); 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.reset(new vk::PipelineDesc());
mPipelineDesc->initDefaults(); mPipelineDesc->initDefaults();
......
...@@ -749,8 +749,9 @@ vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descri ...@@ -749,8 +749,9 @@ vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descri
const vk::DescriptorSetLayout &descriptorSetLayout = const vk::DescriptorSetLayout &descriptorSetLayout =
mDescriptorSetLayouts[descriptorSetIndex].get(); mDescriptorSetLayouts[descriptorSetIndex].get();
ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout.ptr(), 1, ANGLE_TRY(dynamicDescriptorPool->allocateSets(contextVk, descriptorSetLayout.ptr(), 1,
&mDescriptorSets[descriptorSetIndex])); descriptorSetIndex,
&mDescriptorSets[descriptorSetIndex]));
return vk::NoError(); return vk::NoError();
} }
......
...@@ -647,7 +647,6 @@ constexpr uint32_t kVertexUniformsBindingIndex = 0; ...@@ -647,7 +647,6 @@ constexpr uint32_t kVertexUniformsBindingIndex = 0;
constexpr uint32_t kFragmentUniformsBindingIndex = 1; constexpr uint32_t kFragmentUniformsBindingIndex = 1;
constexpr uint32_t kUniformsDescriptorSetIndex = 0; constexpr uint32_t kUniformsDescriptorSetIndex = 0;
constexpr uint32_t kTextureDescriptorSetIndex = 1; constexpr uint32_t kTextureDescriptorSetIndex = 1;
constexpr uint32_t kDescriptorSetCount = 2;
} // namespace rx } // namespace rx
......
...@@ -19,9 +19,6 @@ namespace vk ...@@ -19,9 +19,6 @@ namespace vk
{ {
namespace namespace
{ {
// TODO(jmadill): Pick non-arbitrary max.
constexpr uint32_t kDefaultDynamicDescriptorPoolMaxSets = 2048;
constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage = constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage =
(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); (VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
constexpr int kLineLoopDynamicBufferMinSize = 1024 * 1024; constexpr int kLineLoopDynamicBufferMinSize = 1024 * 1024;
...@@ -80,6 +77,19 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType) ...@@ -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 } // anonymous namespace
// DynamicBuffer implementation. // DynamicBuffer implementation.
...@@ -268,78 +278,62 @@ void DynamicBuffer::setMinimumSizeForTesting(size_t minSize) ...@@ -268,78 +278,62 @@ void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
// DynamicDescriptorPool implementation. // DynamicDescriptorPool implementation.
DynamicDescriptorPool::DynamicDescriptorPool() DynamicDescriptorPool::DynamicDescriptorPool()
: mMaxSetsPerPool(kDefaultDynamicDescriptorPoolMaxSets), : mMaxSetsPerPool(kDefaultDescriptorPoolMaxSets), mCurrentSetsCount(0), mFreeDescriptorSets({})
mCurrentAllocatedDescriptorSetCount(0),
mUniformBufferDescriptorsPerSet(0),
mCombinedImageSamplerDescriptorsPerSet(0)
{ {
} }
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 ASSERT(!mCurrentDescriptorPool.valid());
// 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;
mPoolSizes = poolSizes;
ANGLE_TRY(allocateNewPool(device)); ANGLE_TRY(allocateNewPool(device));
return NoError(); return NoError();
} }
Error DynamicDescriptorPool::allocateDescriptorSets( void DynamicDescriptorPool::destroy(VkDevice device)
ContextVk *contextVk, {
const VkDescriptorSetLayout *descriptorSetLayout, mCurrentDescriptorPool.destroy(device);
uint32_t descriptorSetCount, }
VkDescriptorSet *descriptorSetsOut)
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(); RendererVk *renderer = contextVk->getRenderer();
Serial currentSerial = renderer->getCurrentQueueSerial(); Serial currentSerial = renderer->getCurrentQueueSerial();
// We will bust the limit of descriptor set with this allocation so we need to get a new // We will bust the limit of descriptor set with this allocation so we need to get a new
// pool for it. // pool for it.
renderer->releaseObject(currentSerial, &mCurrentDescriptorSetPool); renderer->releaseObject(currentSerial, &mCurrentDescriptorPool);
ANGLE_TRY(allocateNewPool(contextVk->getDevice())); ANGLE_TRY(allocateNewPool(contextVk->getDevice()));
} }
VkDescriptorSetAllocateInfo allocInfo; VkDescriptorSetAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.pNext = nullptr; allocInfo.pNext = nullptr;
allocInfo.descriptorPool = mCurrentDescriptorSetPool.getHandle(); allocInfo.descriptorPool = mCurrentDescriptorPool.getHandle();
allocInfo.descriptorSetCount = descriptorSetCount; allocInfo.descriptorSetCount = descriptorSetCount;
allocInfo.pSetLayouts = descriptorSetLayout; allocInfo.pSetLayouts = descriptorSetLayout;
ANGLE_TRY(mCurrentDescriptorSetPool.allocateDescriptorSets(contextVk->getDevice(), allocInfo, ANGLE_TRY(mCurrentDescriptorPool.allocateDescriptorSets(contextVk->getDevice(), allocInfo,
descriptorSetsOut)); descriptorSetsOut));
mCurrentAllocatedDescriptorSetCount += allocInfo.descriptorSetCount;
ASSERT(mFreeDescriptorSets[descriptorSetIndex] >= descriptorSetCount);
mFreeDescriptorSets[descriptorSetIndex] -= descriptorSetCount;
mCurrentSetsCount++;
return NoError(); 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; VkDescriptorPoolCreateInfo descriptorPoolInfo;
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.pNext = nullptr; descriptorPoolInfo.pNext = nullptr;
...@@ -347,11 +341,19 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device) ...@@ -347,11 +341,19 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
descriptorPoolInfo.maxSets = mMaxSetsPerPool; descriptorPoolInfo.maxSets = mMaxSetsPerPool;
// Reserve pools for uniform blocks and textures. // Reserve pools for uniform blocks and textures.
descriptorPoolInfo.poolSizeCount = kDescriptorSetCount; descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(mPoolSizes.size());
descriptorPoolInfo.pPoolSizes = poolSizes; 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(mCurrentDescriptorPool.init(device, descriptorPoolInfo));
ANGLE_TRY(mCurrentDescriptorSetPool.init(device, descriptorPoolInfo));
return NoError(); return NoError();
} }
......
...@@ -90,33 +90,39 @@ class DynamicBuffer : angle::NonCopyable ...@@ -90,33 +90,39 @@ class DynamicBuffer : angle::NonCopyable
// using the maximum number of descriptor sets and buffers with each allocation. Currently: 2 // 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. // (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 class DynamicDescriptorPool final : angle::NonCopyable
{ {
public: public:
DynamicDescriptorPool(); DynamicDescriptorPool();
~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 init(VkDevice device, const DescriptorPoolSizes &poolSizes);
Error allocateDescriptorSets(ContextVk *contextVk, void destroy(VkDevice device);
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount, // We use the descriptor type to help count the number of free sets.
VkDescriptorSet *descriptorSetsOut); // 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! // For testing only!
void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool); void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool);
private: private:
Error allocateNewPool(const VkDevice &device); Error allocateNewPool(VkDevice device);
uint32_t mMaxSetsPerPool; uint32_t mMaxSetsPerPool;
DescriptorPool mCurrentDescriptorSetPool; uint32_t mCurrentSetsCount;
size_t mCurrentAllocatedDescriptorSetCount; DescriptorPool mCurrentDescriptorPool;
uint32_t mUniformBufferDescriptorsPerSet; DescriptorPoolSizes mPoolSizes;
uint32_t mCombinedImageSamplerDescriptorsPerSet; DescriptorSetLayoutArray<uint32_t> mFreeDescriptorSets;
}; };
// This class' responsibility is to create index buffers needed to support line loops in Vulkan. // 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