loader: Fix enumerate device extension properties

Same as device layer property issue.
Loader needs to provide aggregate data rather
than send to instance chain.

Change-Id: Ib0e963e8d1780e4870110c556051da921f94353b
diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl
index 204e7fb..306aae4 100644
--- a/vulkan/libvulkan/dispatch.tmpl
+++ b/vulkan/libvulkan/dispatch.tmpl
@@ -562,6 +562,7 @@
   {{else if eq $.Name "vkAllocateCommandBuffers"}}true
   {{else if eq $.Name "vkCreateDevice"}}true
   {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true
+  {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
 
   {{/* vkDestroy for dispatchable objects needs to handle VK_NULL_HANDLE;
        trying to dispatch through that would crash. */}}
diff --git a/vulkan/libvulkan/dispatch_gen.cpp b/vulkan/libvulkan/dispatch_gen.cpp
index 147ff9a..b41efb8 100644
--- a/vulkan/libvulkan/dispatch_gen.cpp
+++ b/vulkan/libvulkan/dispatch_gen.cpp
@@ -215,6 +215,7 @@
     {"vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateInstance>(CreateInstance_Top))},
     {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDevice>(DestroyDevice_Top))},
     {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyInstance>(DestroyInstance_Top))},
+    {"vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateDeviceExtensionProperties>(EnumerateDeviceExtensionProperties_Top))},
     {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateDeviceLayerProperties>(EnumerateDeviceLayerProperties_Top))},
     {"vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateInstanceExtensionProperties>(EnumerateInstanceExtensionProperties_Top))},
     {"vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateInstanceLayerProperties>(EnumerateInstanceLayerProperties_Top))},
@@ -1417,7 +1418,7 @@
 
 __attribute__((visibility("default")))
 VKAPI_ATTR VkResult vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties) {
-    return GetDispatchTable(physicalDevice).EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties);
+    return EnumerateDeviceExtensionProperties_Top(physicalDevice, pLayerName, pPropertyCount, pProperties);
 }
 
 __attribute__((visibility("default")))
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index 345b114..c82c420 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -821,44 +821,15 @@
             properties);
 }
 
+// This is a no-op, the Top function returns the aggregate layer property
+// data. This is to keep the dispatch generator happy.
 VKAPI_ATTR
 VkResult EnumerateDeviceExtensionProperties_Bottom(
-    VkPhysicalDevice gpu,
-    const char* layer_name,
-    uint32_t* properties_count,
-    VkExtensionProperties* properties) {
-    const VkExtensionProperties* extensions = nullptr;
-    uint32_t num_extensions = 0;
-    if (layer_name) {
-        GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
-    } else {
-        Instance& instance = GetDispatchParent(gpu);
-        size_t gpu_idx = 0;
-        while (instance.physical_devices[gpu_idx] != gpu)
-            gpu_idx++;
-        const DeviceExtensionSet driver_extensions =
-            instance.physical_device_driver_extensions[gpu_idx];
-
-        // We only support VK_KHR_swapchain if the GPU supports
-        // VK_ANDROID_native_buffer
-        VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
-            alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
-        if (driver_extensions[kANDROID_native_buffer]) {
-            available[num_extensions++] = VkExtensionProperties{
-                VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
-        }
-
-        // TODO(jessehall): We need to also enumerate extensions supported by
-        // implicitly-enabled layers. Currently we don't have that list of
-        // layers until instance creation.
-        extensions = available;
-    }
-
-    if (!properties || *properties_count > num_extensions)
-        *properties_count = num_extensions;
-    if (properties)
-        std::copy(extensions, extensions + *properties_count, properties);
-    return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
+    VkPhysicalDevice /*pdev*/,
+    const char* /*layer_name*/,
+    uint32_t* /*properties_count*/,
+    VkExtensionProperties* /*properties*/) {
+    return VK_SUCCESS;
 }
 
 // This is a no-op, the Top function returns the aggregate layer property
@@ -1060,6 +1031,51 @@
     return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
 }
 
+VKAPI_ATTR
+VkResult EnumerateDeviceExtensionProperties_Top(
+    VkPhysicalDevice gpu,
+    const char* layer_name,
+    uint32_t* properties_count,
+    VkExtensionProperties* properties) {
+    const VkExtensionProperties* extensions = nullptr;
+    uint32_t num_extensions = 0;
+
+    ALOGV("EnumerateDeviceExtensionProperties_Top:");
+    if (layer_name) {
+        ALOGV("  layer %s", layer_name);
+        GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
+    } else {
+        ALOGV("  no layer");
+        Instance& instance = GetDispatchParent(gpu);
+        size_t gpu_idx = 0;
+        while (instance.physical_devices[gpu_idx] != gpu)
+            gpu_idx++;
+        const DeviceExtensionSet driver_extensions =
+            instance.physical_device_driver_extensions[gpu_idx];
+
+        // We only support VK_KHR_swapchain if the GPU supports
+        // VK_ANDROID_native_buffer
+        VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
+            alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
+        if (driver_extensions[kANDROID_native_buffer]) {
+            available[num_extensions++] = VkExtensionProperties{
+                VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
+        }
+
+        // TODO(jessehall): We need to also enumerate extensions supported by
+        // implicitly-enabled layers. Currently we don't have that list of
+        // layers until instance creation.
+        extensions = available;
+    }
+
+    ALOGV("  num: %d, extensions: %p", num_extensions, extensions);
+    if (!properties || *properties_count > num_extensions)
+        *properties_count = num_extensions;
+    if (properties)
+        std::copy(extensions, extensions + *properties_count, properties);
+    return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
+}
+
 VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
                             const VkAllocationCallbacks* allocator,
                             VkInstance* instance_out) {
diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h
index a724411..77c8ebe 100644
--- a/vulkan/libvulkan/loader.h
+++ b/vulkan/libvulkan/loader.h
@@ -95,6 +95,7 @@
 VKAPI_ATTR void GetDeviceQueue_Top(VkDevice drv_device, uint32_t family, uint32_t index, VkQueue* out_queue);
 VKAPI_ATTR VkResult AllocateCommandBuffers_Top(VkDevice device, const VkCommandBufferAllocateInfo* alloc_info, VkCommandBuffer* cmdbufs);
 VKAPI_ATTR VkResult EnumerateDeviceLayerProperties_Top(VkPhysicalDevice pdev, uint32_t* properties_count, VkLayerProperties* properties);
+VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Top(VkPhysicalDevice pdev, const char * layer_name, uint32_t* properties_count, VkExtensionProperties* properties);
 VKAPI_ATTR VkResult CreateDevice_Top(VkPhysicalDevice pdev, const VkDeviceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkDevice* device_out);
 VKAPI_ATTR void DestroyDevice_Top(VkDevice drv_device, const VkAllocationCallbacks* allocator);