Vulkan: Fix texture descriptor set alloc count.
We were reserving half the required descriptor sets for our pool. This
fixes the counting and ensures we won't regress by adding a test.
Also enables the cube map texture sample, and removes an UNIMPLEMENTED
warning that was spurious.
Bug: angleproject:2318
Change-Id: I371cd7c5b42e1ce980cce7bb0ef04885db72b614
Reviewed-on: https://chromium-review.googlesource.com/1014165
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 6fb33e0..989232f 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -431,7 +431,8 @@
if (linkedUniform.isSampler())
{
- UNIMPLEMENTED();
+ // We could potentially cache some indexing here. For now this is a no-op since the mapping
+ // is handled entirely in ContextVk.
return;
}
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index dba6875..4261879 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -19,7 +19,7 @@
namespace
{
// TODO(jmadill): Pick non-arbitrary max.
-constexpr uint32_t kDynamicDescriptorPoolMaxSets = 2048;
+constexpr uint32_t kDefaultDynamicDescriptorPoolMaxSets = 2048;
constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage =
(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
@@ -239,7 +239,8 @@
// DynamicDescriptorPool implementation.
DynamicDescriptorPool::DynamicDescriptorPool()
- : mCurrentAllocatedDescriptorSetCount(0),
+ : mMaxSetsPerPool(kDefaultDynamicDescriptorPoolMaxSets),
+ mCurrentAllocatedDescriptorSetCount(0),
mUniformBufferDescriptorsPerSet(0),
mCombinedImageSamplerDescriptorsPerSet(0)
{
@@ -274,7 +275,7 @@
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut)
{
- if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > kDynamicDescriptorPoolMaxSets)
+ if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > mMaxSetsPerPool)
{
RendererVk *renderer = contextVk->getRenderer();
Serial currentSerial = renderer->getCurrentQueueSerial();
@@ -303,17 +304,16 @@
VkDescriptorPoolSize poolSizes[DescriptorPoolIndexCount];
poolSizes[UniformBufferIndex].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
poolSizes[UniformBufferIndex].descriptorCount =
- mUniformBufferDescriptorsPerSet * kDynamicDescriptorPoolMaxSets / DescriptorPoolIndexCount;
+ mUniformBufferDescriptorsPerSet * mMaxSetsPerPool;
poolSizes[TextureIndex].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- poolSizes[TextureIndex].descriptorCount = mCombinedImageSamplerDescriptorsPerSet *
- kDynamicDescriptorPoolMaxSets /
- DescriptorPoolIndexCount;
+ poolSizes[TextureIndex].descriptorCount =
+ mCombinedImageSamplerDescriptorsPerSet * mMaxSetsPerPool;
VkDescriptorPoolCreateInfo descriptorPoolInfo;
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.pNext = nullptr;
descriptorPoolInfo.flags = 0;
- descriptorPoolInfo.maxSets = kDynamicDescriptorPoolMaxSets;
+ descriptorPoolInfo.maxSets = mMaxSetsPerPool;
// Reserve pools for uniform blocks and textures.
descriptorPoolInfo.poolSizeCount = DescriptorPoolIndexCount;
@@ -324,6 +324,12 @@
return NoError();
}
+void DynamicDescriptorPool::setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool)
+{
+ mMaxSetsPerPool = maxSetsPerPool;
+}
+
+// LineLoopHelper implementation.
LineLoopHelper::LineLoopHelper()
: mDynamicIndexBuffer(kLineLoopDynamicBufferUsage, kLineLoopDynamicBufferMinSize)
{
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index 3b6c628..09cf845 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -101,9 +101,13 @@
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut);
+ // For testing only!
+ void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool);
+
private:
Error allocateNewPool(const VkDevice &device);
+ uint32_t mMaxSetsPerPool;
DescriptorPool mCurrentDescriptorSetPool;
size_t mCurrentAllocatedDescriptorSetCount;
uint32_t mUniformBufferDescriptorsPerSet;
diff --git a/src/tests/gl_tests/VulkanUniformUpdatesTest.cpp b/src/tests/gl_tests/VulkanUniformUpdatesTest.cpp
index 854ac37..a4e0003 100644
--- a/src/tests/gl_tests/VulkanUniformUpdatesTest.cpp
+++ b/src/tests/gl_tests/VulkanUniformUpdatesTest.cpp
@@ -28,39 +28,39 @@
class VulkanUniformUpdatesTest : public ANGLETest
{
+ protected:
+ rx::ContextVk *hackANGLE()
+ {
+ // Hack the angle!
+ const gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
+ return rx::GetImplAs<rx::ContextVk>(context);
+ }
};
// This test updates a uniform until a new buffer is allocated and then make sure the uniform
// updates still work.
-TEST_P(VulkanUniformUpdatesTest, UpdateUniformUntilNewBufferIsAllocated)
+TEST_P(VulkanUniformUpdatesTest, UpdateUntilNewBufferIsAllocated)
{
ASSERT_TRUE(IsVulkan());
- constexpr char kPositionUniformVertexShader[] = R"(
-precision mediump float;
-attribute vec2 position;
+ constexpr char kPositionUniformVertexShader[] = R"(attribute vec2 position;
uniform vec2 uniPosModifier;
void main()
{
gl_Position = vec4(position + uniPosModifier, 0, 1);
})";
- constexpr char kColorUniformFragmentShader[] = R"(
-precision mediump float;
+ constexpr char kColorUniformFragmentShader[] = R"(precision mediump float;
uniform vec4 uniColor;
void main()
{
gl_FragColor = uniColor;
})";
- // Hack the angle!
- const gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
- auto *contextVk = rx::GetImplAs<rx::ContextVk>(context);
-
ANGLE_GL_PROGRAM(program, kPositionUniformVertexShader, kColorUniformFragmentShader);
glUseProgram(program);
- const gl::State &state = contextVk->getGLState();
+ const gl::State &state = hackANGLE()->getGLState();
rx::ProgramVk *programVk = rx::vk::GetImpl(state.getProgram());
// Set a really small min size so that uniform updates often allocates a new buffer.
@@ -83,6 +83,43 @@
}
}
+// Force uniform updates until the dynamic descriptor pool wraps into a new pool allocation.
+TEST_P(VulkanUniformUpdatesTest, DescriptorPoolUpdates)
+{
+ ASSERT_TRUE(IsVulkan());
+
+ // Force a small limit on the max sets per pool to more easily trigger a new allocation.
+ constexpr uint32_t kMaxSetsForTesting = 32;
+ rx::vk::DynamicDescriptorPool *dynamicDescriptorPool = hackANGLE()->getDynamicDescriptorPool();
+ dynamicDescriptorPool->setMaxSetsPerPoolForTesting(kMaxSetsForTesting);
+
+ // Initialize texture program.
+ GLuint program = get2DTexturedQuadProgram();
+ ASSERT_NE(0u, program);
+ glUseProgram(program);
+
+ GLint texLoc = glGetUniformLocation(program, "tex");
+ ASSERT_NE(-1, texLoc);
+
+ // Initialize basic red texture.
+ const std::vector<GLColor> redColors(4, GLColor::red);
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, redColors.data());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ // Draw multiple times, each iteration will create a new descriptor set.
+ for (uint32_t iteration = 0; iteration < kMaxSetsForTesting * 8; ++iteration)
+ {
+ glUniform1i(texLoc, 0);
+ drawQuad(program, "position", 0.5f, 1.0f, true);
+ swapBuffers();
+ ASSERT_GL_NO_ERROR();
+ }
+}
+
ANGLE_INSTANTIATE_TEST(VulkanUniformUpdatesTest, ES2_VULKAN());
} // anonymous namespace