Bug 14248: Add vkFreeDescriptorSets
diff --git a/include/vk_layer.h b/include/vk_layer.h
index 8cb5f3f..0881d24 100644
--- a/include/vk_layer.h
+++ b/include/vk_layer.h
@@ -99,6 +99,7 @@
     PFN_vkDestroyDescriptorPool DestroyDescriptorPool;
     PFN_vkResetDescriptorPool ResetDescriptorPool;
     PFN_vkAllocDescriptorSets AllocDescriptorSets;
+    PFN_vkFreeDescriptorSets FreeDescriptorSets;
     PFN_vkUpdateDescriptorSets UpdateDescriptorSets;
     PFN_vkCreateDynamicViewportState CreateDynamicViewportState;
     PFN_vkDestroyDynamicViewportState DestroyDynamicViewportState;
diff --git a/include/vulkan.h b/include/vulkan.h
index d9bc859..f2b35c6 100644
--- a/include/vulkan.h
+++ b/include/vulkan.h
@@ -2345,6 +2345,7 @@
 typedef VkResult (VKAPI *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool);
 typedef VkResult (VKAPI *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool);
 typedef VkResult (VKAPI *PFN_vkAllocDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount);
+typedef VkResult (VKAPI *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets);
 typedef VkResult (VKAPI *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies);
 typedef VkResult (VKAPI *PFN_vkCreateDynamicViewportState)(VkDevice device, const VkDynamicViewportStateCreateInfo* pCreateInfo, VkDynamicViewportState* pState);
 typedef VkResult (VKAPI *PFN_vkDestroyDynamicViewportState)(VkDevice device, VkDynamicViewportState dynamicViewportState);
@@ -2871,6 +2872,12 @@
     VkDescriptorSet*                            pDescriptorSets,
     uint32_t*                                   pCount);
 
+VkResult VKAPI vkFreeDescriptorSets(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool,
+    uint32_t                                    count,
+    const VkDescriptorSet*                      pDescriptorSets);
+
 VkResult VKAPI vkUpdateDescriptorSets(
     VkDevice                                    device,
     uint32_t                                    writeCount,
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index becde6a..60f65aa 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -1918,6 +1918,13 @@
     return result;
 }
 
+VK_LAYER_EXPORT VkResult VKAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
+{
+    VkResult result = get_dispatch_table(draw_state_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
+    // TODO : Clean up any internal data structures using this obj.
+    return result;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
 {
     if (dsUpdate(device, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writeCount, pDescriptorWrites) &&
diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h
index 04f97da..a6d8808 100644
--- a/loader/gpa_helper.h
+++ b/loader/gpa_helper.h
@@ -207,6 +207,8 @@
         return (void*) vkResetDescriptorPool;
     if (!strcmp(name, "AllocDescriptorSets"))
         return (void*) vkAllocDescriptorSets;
+    if (!strcmp(name, "FreeDescriptorSets"))
+        return (void*) vkFreeDescriptorSets;
     if (!strcmp(name, "UpdateDescriptorSets"))
         return (void*) vkUpdateDescriptorSets;
     if (!strcmp(name, "CreateDynamicViewportState"))
diff --git a/loader/table_ops.h b/loader/table_ops.h
index df8c2b4..8e8ce9b 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -107,6 +107,7 @@
     table->DestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) gpa(dev, "vkDestroyDescriptorPool");
     table->ResetDescriptorPool = (PFN_vkResetDescriptorPool) gpa(dev, "vkResetDescriptorPool");
     table->AllocDescriptorSets = (PFN_vkAllocDescriptorSets) gpa(dev, "vkAllocDescriptorSets");
+    table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets) gpa(dev, "vkFreeDescriptorSets");
     table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) gpa(dev, "vkUpdateDescriptorSets");
     table->CreateDynamicViewportState = (PFN_vkCreateDynamicViewportState) gpa(dev, "vkCreateDynamicViewportState");
     table->DestroyDynamicViewportState = (PFN_vkDestroyDynamicViewportState) gpa(dev, "vkDestroyDynamicViewportState");
@@ -323,6 +324,8 @@
         return (void *) table->ResetDescriptorPool;
     if (!strcmp(name, "AllocDescriptorSets"))
         return (void *) table->AllocDescriptorSets;
+    if (!strcmp(name, "FreeDescriptorSets"))
+        return (void *) table->FreeDescriptorSets;
     if (!strcmp(name, "UpdateDescriptorSets"))
         return (void *) table->UpdateDescriptorSets;
     if (!strcmp(name, "CreateDynamicViewportState"))
diff --git a/loader/trampoline.c b/loader/trampoline.c
index dbd134f..13d4e68 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -953,6 +953,15 @@
     return disp->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
 }
 
+LOADER_EXPORT VkResult VKAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
+{
+    const VkLayerDispatchTable *disp;
+
+    disp = loader_get_dispatch(device);
+
+    return disp->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
+}
+
 LOADER_EXPORT VkResult VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
 {
     const VkLayerDispatchTable *disp;
diff --git a/vulkan.py b/vulkan.py
index 1f638f7..4ef8f41 100755
--- a/vulkan.py
+++ b/vulkan.py
@@ -645,6 +645,12 @@
              Param("VkDescriptorSet*", "pDescriptorSets"),
              Param("uint32_t*", "pCount")]),
 
+        Proto("VkResult", "FreeDescriptorSets",
+            [Param("VkDevice", "device"),
+             Param("VkDescriptorPool", "descriptorPool"),
+             Param("uint32_t", "count"),
+             Param("const VkDescriptorSet*", "pDescriptorSets")]),
+
         Proto("VkResult", "UpdateDescriptorSets",
             [Param("VkDevice", "device"),
              Param("uint32_t", "writeCount"),