Vulkan: Use free descriptor set bits in pool.

This forces us to free descriptor sets when we're done with them,
but saves us from needing to track when a descriptor set pool is no
longer in use. We may need to revisit this in the future if we want
to support pool allocation for performance.

Bug: angleproject:2396
Change-Id: I3f3184f3dd9e4c2911e1aade4dcb95962a26c3a7
Reviewed-on: https://chromium-review.googlesource.com/956574
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index ced4598..24578e9 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -156,12 +156,16 @@
 
 void ProgramVk::destroy(const gl::Context *contextImpl)
 {
-    VkDevice device = vk::GetImpl(contextImpl)->getDevice();
-    reset(device);
+    ContextVk *contextVk = vk::GetImpl(contextImpl);
+    reset(contextVk);
 }
 
-void ProgramVk::reset(VkDevice device)
+void ProgramVk::reset(ContextVk *contextVk)
 {
+    // TODO(jmadill): Handle re-linking a program that is in-use. http://anglebug.com/2397
+
+    VkDevice device = contextVk->getDevice();
+
     for (auto &uniformBlock : mDefaultUniformBlocks)
     {
         uniformBlock.storage.memory.destroy(device);
@@ -176,7 +180,13 @@
     mVertexModuleSerial   = Serial();
     mFragmentModuleSerial = Serial();
 
-    // Descriptor Sets are pool allocated, so do not need to be explicitly freed.
+    // Free our descriptor set handles.
+    if (!mDescriptorSets.empty())
+    {
+        vk::DescriptorPool *descriptorPool = contextVk->getDescriptorPool();
+        vkFreeDescriptorSets(device, descriptorPool->getHandle(),
+                             static_cast<uint32_t>(mDescriptorSets.size()), mDescriptorSets.data());
+    }
     mDescriptorSets.clear();
     mUsedDescriptorSetRange.invalidate();
     mDirtyTextures       = false;
@@ -214,7 +224,7 @@
     GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper();
     VkDevice device                = renderer->getDevice();
 
-    reset(device);
+    reset(contextVk);
 
     std::vector<uint32_t> vertexCode;
     std::vector<uint32_t> fragmentCode;