Commit caeb1e89 by Jamie Madill Committed by Commit Bot

Vulkan: Allow unlimited simultaneous descriptor sets.

This changes the fixed array into a STL vector. Instead of storing Descriptor Pools by value we now store them by pointer. This allows the vector to resize without changing the address of the Descriptor Pool. Also enables some more Vulkan perf tests that were crashing before. Bug: angleproject:2938 Change-Id: I8a88d5315b941c4f54205a9957e2834fe02ada84 Reviewed-on: https://chromium-review.googlesource.com/c/1311395 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent c0b6c639
......@@ -352,21 +352,27 @@ angle::Result DynamicDescriptorPool::init(ContextVk *contextVk,
VkDescriptorType descriptorType,
uint32_t descriptorsPerSet)
{
ASSERT(mCurrentPoolIndex == 0 && !mDescriptorPools[mCurrentPoolIndex].isReferenced());
ASSERT(mCurrentPoolIndex == 0);
ASSERT(mDescriptorPools.empty() || (mDescriptorPools.size() == 1 &&
mDescriptorPools[0]->get().hasCapacity(mMaxSetsPerPool)));
mPoolSize.type = descriptorType;
mPoolSize.descriptorCount = descriptorsPerSet * mMaxSetsPerPool;
return mDescriptorPools[0].get().init(contextVk, mPoolSize, mMaxSetsPerPool);
mDescriptorPools.push_back(new SharedDescriptorPoolHelper());
return mDescriptorPools[0]->get().init(contextVk, mPoolSize, mMaxSetsPerPool);
}
void DynamicDescriptorPool::destroy(VkDevice device)
{
for (SharedDescriptorPoolHelper &pool : mDescriptorPools)
for (SharedDescriptorPoolHelper *pool : mDescriptorPools)
{
ASSERT(!pool.isReferenced());
pool.get().destroy(device);
ASSERT(!pool->isReferenced());
pool->get().destroy(device);
delete pool;
}
mDescriptorPools.clear();
}
angle::Result DynamicDescriptorPool::allocateSets(ContextVk *contextVk,
......@@ -377,7 +383,7 @@ angle::Result DynamicDescriptorPool::allocateSets(ContextVk *contextVk,
{
if (!bindingOut->valid() || !bindingOut->get().hasCapacity(descriptorSetCount))
{
if (!mDescriptorPools[mCurrentPoolIndex].get().hasCapacity(descriptorSetCount))
if (!mDescriptorPools[mCurrentPoolIndex]->get().hasCapacity(descriptorSetCount))
{
ANGLE_TRY(allocateNewPool(contextVk));
}
......@@ -391,7 +397,7 @@ angle::Result DynamicDescriptorPool::allocateSets(ContextVk *contextVk,
bindingOut->get().updateSerial(currentSerial);
}
bindingOut->set(&mDescriptorPools[mCurrentPoolIndex]);
bindingOut->set(mDescriptorPools[mCurrentPoolIndex]);
}
return bindingOut->get().allocateSets(contextVk, descriptorSetLayout, descriptorSetCount,
......@@ -404,12 +410,12 @@ angle::Result DynamicDescriptorPool::allocateNewPool(ContextVk *contextVk)
bool found = false;
for (size_t poolIndex = 0; poolIndex < kMaxInFlightPools; ++poolIndex)
for (size_t poolIndex = 0; poolIndex < mDescriptorPools.size(); ++poolIndex)
{
if (!mDescriptorPools[poolIndex].isReferenced() &&
!renderer->isSerialInUse(mDescriptorPools[poolIndex].get().getSerial()))
if (!mDescriptorPools[poolIndex]->isReferenced() &&
!renderer->isSerialInUse(mDescriptorPools[poolIndex]->get().getSerial()))
{
// We cannot allocate a new pool if the current pool is available.
// The newly allocated pool must be a different index from the current pool.
ASSERT(poolIndex != mCurrentPoolIndex);
mCurrentPoolIndex = poolIndex;
found = true;
......@@ -417,8 +423,16 @@ angle::Result DynamicDescriptorPool::allocateNewPool(ContextVk *contextVk)
}
}
ANGLE_VK_CHECK(contextVk, found, VK_ERROR_TOO_MANY_OBJECTS);
return mDescriptorPools[mCurrentPoolIndex].get().init(contextVk, mPoolSize, mMaxSetsPerPool);
if (!found)
{
mDescriptorPools.push_back(new SharedDescriptorPoolHelper());
mCurrentPoolIndex = mDescriptorPools.size() - 1;
static constexpr size_t kMaxPools = 99999;
ANGLE_VK_CHECK(contextVk, mDescriptorPools.size() < kMaxPools, VK_ERROR_TOO_MANY_OBJECTS);
}
return mDescriptorPools[mCurrentPoolIndex]->get().init(contextVk, mPoolSize, mMaxSetsPerPool);
}
void DynamicDescriptorPool::setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool)
......
......@@ -150,13 +150,9 @@ class DynamicDescriptorPool final : angle::NonCopyable
private:
angle::Result allocateNewPool(ContextVk *contextVk);
// This is somewhat fragile. It limits the total number of in-flight descriptors to
// kMaxInFlightPools * kDefaultDescriptorPoolMaxSets. Currently this is ~500k.
static constexpr size_t kMaxInFlightPools = 256;
uint32_t mMaxSetsPerPool;
size_t mCurrentPoolIndex;
std::array<SharedDescriptorPoolHelper, kMaxInFlightPools> mDescriptorPools;
std::vector<SharedDescriptorPoolHelper *> mDescriptorPools;
VkDescriptorPoolSize mPoolSize;
};
......
......@@ -257,8 +257,6 @@ DrawArraysPerfParams DrawArrays(const DrawCallPerfParams &base, StateChange stat
return params;
}
// TODO(jmadill): Fix tex change test on Vulkan. http://anglebug.com/2938
ANGLE_INSTANTIATE_TEST(
DrawCallPerfBenchmark,
DrawArrays(DrawCallPerfD3D9Params(false, false), StateChange::NoChange),
......@@ -281,6 +279,8 @@ ANGLE_INSTANTIATE_TEST(
DrawArrays(DrawCallPerfVulkanParams(false, false), StateChange::NoChange),
DrawArrays(DrawCallPerfVulkanParams(true, false), StateChange::NoChange),
DrawArrays(DrawCallPerfVulkanParams(false, false), StateChange::VertexBuffer),
DrawArrays(DrawCallPerfVulkanParams(true, false), StateChange::VertexBuffer));
DrawArrays(DrawCallPerfVulkanParams(true, false), StateChange::VertexBuffer),
DrawArrays(DrawCallPerfVulkanParams(false, false), StateChange::Texture),
DrawArrays(DrawCallPerfVulkanParams(true, false), StateChange::Texture));
} // anonymous namespace
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