Vulkan: Reallocate only the right uniform descriptor set when needed

Bug: angleproject:2421

Change-Id: Ibdd8beee8103062a566b8caa23cdd9b8ac35d3a8
Reviewed-on: https://chromium-review.googlesource.com/974105
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index ab31271..ad577b0 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -267,7 +267,6 @@
         mFragmentModuleSerial = renderer->issueProgramSerial();
     }
 
-    ANGLE_TRY(allocateDescriptorSets(contextVk));
     ANGLE_TRY(initDefaultUniformBlocks(glContext));
 
     if (!mState.getSamplerUniformRange().empty())
@@ -650,23 +649,25 @@
     return mFragmentModuleSerial;
 }
 
-vk::Error ProgramVk::allocateDescriptorSets(ContextVk *contextVk)
+vk::Error ProgramVk::allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex)
 {
     RendererVk *renderer = contextVk->getRenderer();
 
     // Write out to a new a descriptor set.
     DynamicDescriptorPool *dynamicDescriptorPool = contextVk->getDynamicDescriptorPool();
-
     const auto &descriptorSetLayouts = renderer->getGraphicsDescriptorSetLayouts();
-    uint32_t descriptorSetCount = static_cast<uint32_t>(descriptorSetLayouts.size());
 
-    mDescriptorSets.resize(descriptorSetCount, VK_NULL_HANDLE);
+    uint32_t potentialNewCount = descriptorSetIndex + 1;
+    if (potentialNewCount > mDescriptorSets.size())
+    {
+        mDescriptorSets.resize(potentialNewCount, VK_NULL_HANDLE);
+    }
 
-    // TODO(lucferron): Its wasteful to reallocate the texture descriptor sets when we only
-    // care about the uniforms.
-    // http://anglebug.com/2421
-    ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(
-        contextVk, descriptorSetLayouts[0].ptr(), descriptorSetCount, &mDescriptorSets[0]));
+    const VkDescriptorSetLayout *descriptorSetLayout =
+        descriptorSetLayouts[descriptorSetIndex].ptr();
+
+    ANGLE_TRY(dynamicDescriptorPool->allocateDescriptorSets(contextVk, descriptorSetLayout, 1,
+                                                            &mDescriptorSets[descriptorSetIndex]));
     return vk::NoError();
 }
 
@@ -721,7 +722,7 @@
     {
         // We need to reinitialize the descriptor sets if we newly allocated buffers since we can't
         // modify the descriptor sets once initialized.
-        ANGLE_TRY(allocateDescriptorSets(contextVk));
+        ANGLE_TRY(allocateDescriptorSet(contextVk, UniformBufferIndex));
         ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk));
     }
 
@@ -800,13 +801,15 @@
     return mUsedDescriptorSetRange;
 }
 
-void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
+vk::Error ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
 {
     if (mState.getSamplerBindings().empty() || !mDirtyTextures)
     {
-        return;
+        return vk::NoError();
     }
 
+    ANGLE_TRY(allocateDescriptorSet(contextVk, TextureIndex));
+
     ASSERT(mUsedDescriptorSetRange.contains(1));
     VkDescriptorSet descriptorSet = mDescriptorSets[1];
 
@@ -862,6 +865,7 @@
     vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);
 
     mDirtyTextures = false;
+    return vk::NoError();
 }
 
 void ProgramVk::invalidateTextures()