Commit 0cb6dc4c by Jamie Madill Committed by Commit Bot

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: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 51af38b8
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
class SimpleTextureCubemapSample : public SampleApplication class SimpleTextureCubemapSample : public SampleApplication
{ {
public: public:
SimpleTextureCubemapSample() SimpleTextureCubemapSample(EGLint displayType)
: SampleApplication("SimpleTextureCubemap", 1280, 720) : SampleApplication("SimpleTextureCubemap", 1280, 720, 2, 0, displayType)
{ {
} }
...@@ -129,6 +129,13 @@ class SimpleTextureCubemapSample : public SampleApplication ...@@ -129,6 +129,13 @@ class SimpleTextureCubemapSample : public SampleApplication
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
SimpleTextureCubemapSample app; EGLint displayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
if (argc > 1)
{
displayType = GetDisplayTypeFromArg(argv[1]);
}
SimpleTextureCubemapSample app(displayType);
return app.run(); return app.run();
} }
...@@ -431,7 +431,8 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum ...@@ -431,7 +431,8 @@ void ProgramVk::setUniformImpl(GLint location, GLsizei count, const T *v, GLenum
if (linkedUniform.isSampler()) 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; return;
} }
......
...@@ -19,7 +19,7 @@ namespace vk ...@@ -19,7 +19,7 @@ namespace vk
namespace namespace
{ {
// TODO(jmadill): Pick non-arbitrary max. // TODO(jmadill): Pick non-arbitrary max.
constexpr uint32_t kDynamicDescriptorPoolMaxSets = 2048; 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);
...@@ -239,7 +239,8 @@ void DynamicBuffer::setMinimumSizeForTesting(size_t minSize) ...@@ -239,7 +239,8 @@ void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
// DynamicDescriptorPool implementation. // DynamicDescriptorPool implementation.
DynamicDescriptorPool::DynamicDescriptorPool() DynamicDescriptorPool::DynamicDescriptorPool()
: mCurrentAllocatedDescriptorSetCount(0), : mMaxSetsPerPool(kDefaultDynamicDescriptorPoolMaxSets),
mCurrentAllocatedDescriptorSetCount(0),
mUniformBufferDescriptorsPerSet(0), mUniformBufferDescriptorsPerSet(0),
mCombinedImageSamplerDescriptorsPerSet(0) mCombinedImageSamplerDescriptorsPerSet(0)
{ {
...@@ -274,7 +275,7 @@ Error DynamicDescriptorPool::allocateDescriptorSets( ...@@ -274,7 +275,7 @@ Error DynamicDescriptorPool::allocateDescriptorSets(
uint32_t descriptorSetCount, uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut) VkDescriptorSet *descriptorSetsOut)
{ {
if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > kDynamicDescriptorPoolMaxSets) if (descriptorSetCount + mCurrentAllocatedDescriptorSetCount > mMaxSetsPerPool)
{ {
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
Serial currentSerial = renderer->getCurrentQueueSerial(); Serial currentSerial = renderer->getCurrentQueueSerial();
...@@ -303,17 +304,16 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device) ...@@ -303,17 +304,16 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
VkDescriptorPoolSize poolSizes[DescriptorPoolIndexCount]; VkDescriptorPoolSize poolSizes[DescriptorPoolIndexCount];
poolSizes[UniformBufferIndex].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; poolSizes[UniformBufferIndex].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
poolSizes[UniformBufferIndex].descriptorCount = poolSizes[UniformBufferIndex].descriptorCount =
mUniformBufferDescriptorsPerSet * kDynamicDescriptorPoolMaxSets / DescriptorPoolIndexCount; mUniformBufferDescriptorsPerSet * mMaxSetsPerPool;
poolSizes[TextureIndex].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; poolSizes[TextureIndex].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[TextureIndex].descriptorCount = mCombinedImageSamplerDescriptorsPerSet * poolSizes[TextureIndex].descriptorCount =
kDynamicDescriptorPoolMaxSets / mCombinedImageSamplerDescriptorsPerSet * mMaxSetsPerPool;
DescriptorPoolIndexCount;
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;
descriptorPoolInfo.flags = 0; descriptorPoolInfo.flags = 0;
descriptorPoolInfo.maxSets = kDynamicDescriptorPoolMaxSets; descriptorPoolInfo.maxSets = mMaxSetsPerPool;
// Reserve pools for uniform blocks and textures. // Reserve pools for uniform blocks and textures.
descriptorPoolInfo.poolSizeCount = DescriptorPoolIndexCount; descriptorPoolInfo.poolSizeCount = DescriptorPoolIndexCount;
...@@ -324,6 +324,12 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device) ...@@ -324,6 +324,12 @@ Error DynamicDescriptorPool::allocateNewPool(const VkDevice &device)
return NoError(); return NoError();
} }
void DynamicDescriptorPool::setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool)
{
mMaxSetsPerPool = maxSetsPerPool;
}
// LineLoopHelper implementation.
LineLoopHelper::LineLoopHelper() LineLoopHelper::LineLoopHelper()
: mDynamicIndexBuffer(kLineLoopDynamicBufferUsage, kLineLoopDynamicBufferMinSize) : mDynamicIndexBuffer(kLineLoopDynamicBufferUsage, kLineLoopDynamicBufferMinSize)
{ {
......
...@@ -101,9 +101,13 @@ class DynamicDescriptorPool final : angle::NonCopyable ...@@ -101,9 +101,13 @@ class DynamicDescriptorPool final : angle::NonCopyable
uint32_t descriptorSetCount, uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut); VkDescriptorSet *descriptorSetsOut);
// For testing only!
void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool);
private: private:
Error allocateNewPool(const VkDevice &device); Error allocateNewPool(const VkDevice &device);
uint32_t mMaxSetsPerPool;
DescriptorPool mCurrentDescriptorSetPool; DescriptorPool mCurrentDescriptorSetPool;
size_t mCurrentAllocatedDescriptorSetCount; size_t mCurrentAllocatedDescriptorSetCount;
uint32_t mUniformBufferDescriptorsPerSet; uint32_t mUniformBufferDescriptorsPerSet;
......
...@@ -28,39 +28,39 @@ namespace ...@@ -28,39 +28,39 @@ namespace
class VulkanUniformUpdatesTest : public ANGLETest 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 // This test updates a uniform until a new buffer is allocated and then make sure the uniform
// updates still work. // updates still work.
TEST_P(VulkanUniformUpdatesTest, UpdateUniformUntilNewBufferIsAllocated) TEST_P(VulkanUniformUpdatesTest, UpdateUntilNewBufferIsAllocated)
{ {
ASSERT_TRUE(IsVulkan()); ASSERT_TRUE(IsVulkan());
constexpr char kPositionUniformVertexShader[] = R"( constexpr char kPositionUniformVertexShader[] = R"(attribute vec2 position;
precision mediump float;
attribute vec2 position;
uniform vec2 uniPosModifier; uniform vec2 uniPosModifier;
void main() void main()
{ {
gl_Position = vec4(position + uniPosModifier, 0, 1); gl_Position = vec4(position + uniPosModifier, 0, 1);
})"; })";
constexpr char kColorUniformFragmentShader[] = R"( constexpr char kColorUniformFragmentShader[] = R"(precision mediump float;
precision mediump float;
uniform vec4 uniColor; uniform vec4 uniColor;
void main() void main()
{ {
gl_FragColor = uniColor; 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); ANGLE_GL_PROGRAM(program, kPositionUniformVertexShader, kColorUniformFragmentShader);
glUseProgram(program); glUseProgram(program);
const gl::State &state = contextVk->getGLState(); const gl::State &state = hackANGLE()->getGLState();
rx::ProgramVk *programVk = rx::vk::GetImpl(state.getProgram()); rx::ProgramVk *programVk = rx::vk::GetImpl(state.getProgram());
// Set a really small min size so that uniform updates often allocates a new buffer. // Set a really small min size so that uniform updates often allocates a new buffer.
...@@ -83,6 +83,43 @@ void main() ...@@ -83,6 +83,43 @@ void main()
} }
} }
// 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()); ANGLE_INSTANTIATE_TEST(VulkanUniformUpdatesTest, ES2_VULKAN());
} // anonymous namespace } // 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