vulkan: Implement new vkGet*ProcAddrBehavior

The primary goal of this change is to switch to the revised GPA
behavior:
- GIPA(NULL, ..) only works for non-dispatched (global) commands
- GIPA(instance, ..) returns functions for commands that dispatch on any
  object type, and the function works for any object of the appropriate
  type if it is a child of the instance.
- GDPA(NULL, ..) returns NULL.
- GDPA(device, ..) returns a device-specific function for the command.

This change refactors/tidies many of the things it modified. Some
notable changes:
- All the loader generated code is now in dispatch.tmpl ->
  dispatch_gen.{h,cpp}, instead of two separate templates.
  - Reorganization allowed generating the dispatch table structures,
    eliminating one source of frequent bugs.
  - Removes some error-prone macro duplication.
  - Handling of extensions and special loader functions is now much
    more uniform and hopefully clearer.
- Loader top- and bottom-level functions are now consistently named with
  _Top and _Bottom suffixes, and are grouped by level in loader.cpp.
- The VkInstance and VkDevice implementations are no longer derived from
  ::VkInstance_T and ::VkDevice_T. Was more trouble than it was worth.
- Renamed 'vtbl' to 'dispatch' in most places.
- Renamed nulldrv template and generated files to match the loader
  naming pattern: null_driver.tmpl -> null_driver_gen.{h,cpp}
  - Now all the entry point prototypes are generated, instead of having
    to be updated by hand (another source of several bugs).

Change-Id: Ic263f802d0d523b18a0f00420b3a722aa04ce299
(cherry picked from commit 3cffb8e837222f413a1fe53522e2cc33366b8eeb)
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 88e4d6f..7bfae27 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -65,34 +65,40 @@
         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE;
 };
 
-template <typename T, typename Host>
+template <typename T>
 class VulkanAllocator {
    public:
     typedef T value_type;
 
-    explicit VulkanAllocator(Host host) : host_(host) {}
+    VulkanAllocator(const VkAllocationCallbacks& allocator,
+                    VkSystemAllocationScope scope)
+        : allocator_(allocator), scope_(scope) {}
 
     template <typename U>
-    explicit VulkanAllocator(const VulkanAllocator<U, Host>& other)
-        : host_(other.host_) {}
+    explicit VulkanAllocator(const VulkanAllocator<U>& other)
+        : allocator_(other.allocator_), scope_(other.scope_) {}
 
     T* allocate(size_t n) const {
-        return static_cast<T*>(AllocMem(host_, n * sizeof(T), alignof(T),
-                                        AllocScope<Host>::kScope));
+        return static_cast<T*>(allocator_.pfnAllocation(
+            allocator_.pUserData, n * sizeof(T), alignof(T), scope_));
     }
-    void deallocate(T* p, size_t) const { return FreeMem(host_, p); }
+    void deallocate(T* p, size_t) const {
+        return allocator_.pfnFree(allocator_.pUserData, p);
+    }
 
    private:
-    template <typename U, typename H>
+    template <typename U>
     friend class VulkanAllocator;
-    Host host_;
+    const VkAllocationCallbacks& allocator_;
+    const VkSystemAllocationScope scope_;
 };
 
 template <typename T, typename Host>
 std::shared_ptr<T> InitSharedPtr(Host host, T* obj) {
     obj->common.incRef(&obj->common);
-    return std::shared_ptr<T>(obj, NativeBaseDeleter<T>(),
-                              VulkanAllocator<T, Host>(host));
+    return std::shared_ptr<T>(
+        obj, NativeBaseDeleter<T>(),
+        VulkanAllocator<T>(*GetAllocator(host), AllocScope<Host>::kScope));
 }
 
 // ----------------------------------------------------------------------------
@@ -142,12 +148,15 @@
 namespace vulkan {
 
 VKAPI_ATTR
-VkResult CreateAndroidSurfaceKHR(VkInstance instance,
-                                 ANativeWindow* window,
-                                 const VkAllocationCallbacks* /*allocator*/,
-                                 VkSurfaceKHR* out_surface) {
-    void* mem = AllocMem(instance, sizeof(Surface), alignof(Surface),
-                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+VkResult CreateAndroidSurfaceKHR_Bottom(VkInstance instance,
+                                        ANativeWindow* window,
+                                        const VkAllocationCallbacks* allocator,
+                                        VkSurfaceKHR* out_surface) {
+    if (!allocator)
+        allocator = GetAllocator(instance);
+    void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface),
+                                         alignof(Surface),
+                                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (!mem)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     Surface* surface = new (mem) Surface;
@@ -163,7 +172,7 @@
         ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err),
               err);
         surface->~Surface();
-        FreeMem(instance, surface);
+        allocator->pfnFree(allocator->pUserData, surface);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
 
@@ -172,28 +181,30 @@
 }
 
 VKAPI_ATTR
-void DestroySurfaceKHR(VkInstance instance,
-                       VkSurfaceKHR surface_handle,
-                       const VkAllocationCallbacks* /*allocator*/) {
+void DestroySurfaceKHR_Bottom(VkInstance instance,
+                              VkSurfaceKHR surface_handle,
+                              const VkAllocationCallbacks* allocator) {
     Surface* surface = SurfaceFromHandle(surface_handle);
     if (!surface)
         return;
     native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL);
     surface->~Surface();
-    FreeMem(instance, surface);
+    if (!allocator)
+        allocator = GetAllocator(instance);
+    allocator->pfnFree(allocator->pUserData, surface);
 }
 
 VKAPI_ATTR
-VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
-                                            uint32_t /*queue_family*/,
-                                            VkSurfaceKHR /*surface*/,
-                                            VkBool32* supported) {
+VkResult GetPhysicalDeviceSurfaceSupportKHR_Bottom(VkPhysicalDevice /*pdev*/,
+                                                   uint32_t /*queue_family*/,
+                                                   VkSurfaceKHR /*surface*/,
+                                                   VkBool32* supported) {
     *supported = VK_TRUE;
     return VK_SUCCESS;
 }
 
 VKAPI_ATTR
-VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(
+VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom(
     VkPhysicalDevice /*pdev*/,
     VkSurfaceKHR surface,
     VkSurfaceCapabilitiesKHR* capabilities) {
@@ -250,10 +261,11 @@
 }
 
 VKAPI_ATTR
-VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice /*pdev*/,
-                                            VkSurfaceKHR /*surface*/,
-                                            uint32_t* count,
-                                            VkSurfaceFormatKHR* formats) {
+VkResult GetPhysicalDeviceSurfaceFormatsKHR_Bottom(
+    VkPhysicalDevice /*pdev*/,
+    VkSurfaceKHR /*surface*/,
+    uint32_t* count,
+    VkSurfaceFormatKHR* formats) {
     // TODO(jessehall): Fill out the set of supported formats. Longer term, add
     // a new gralloc method to query whether a (format, usage) pair is
     // supported, and check that for each gralloc format that corresponds to a
@@ -277,10 +289,11 @@
 }
 
 VKAPI_ATTR
-VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice /*pdev*/,
-                                                 VkSurfaceKHR /*surface*/,
-                                                 uint32_t* count,
-                                                 VkPresentModeKHR* modes) {
+VkResult GetPhysicalDeviceSurfacePresentModesKHR_Bottom(
+    VkPhysicalDevice /*pdev*/,
+    VkSurfaceKHR /*surface*/,
+    uint32_t* count,
+    VkPresentModeKHR* modes) {
     const VkPresentModeKHR kModes[] = {
         VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
     };
@@ -297,13 +310,16 @@
 }
 
 VKAPI_ATTR
-VkResult CreateSwapchainKHR(VkDevice device,
-                            const VkSwapchainCreateInfoKHR* create_info,
-                            const VkAllocationCallbacks* /*allocator*/,
-                            VkSwapchainKHR* swapchain_handle) {
+VkResult CreateSwapchainKHR_Bottom(VkDevice device,
+                                   const VkSwapchainCreateInfoKHR* create_info,
+                                   const VkAllocationCallbacks* allocator,
+                                   VkSwapchainKHR* swapchain_handle) {
     int err;
     VkResult result = VK_SUCCESS;
 
+    if (!allocator)
+        allocator = GetAllocator(device);
+
     ALOGV_IF(create_info->imageArraySize != 1,
              "Swapchain imageArraySize (%u) != 1 not supported",
              create_info->imageArraySize);
@@ -322,7 +338,7 @@
     // -- Configure the native window --
 
     Surface& surface = *SurfaceFromHandle(create_info->surface);
-    const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
+    const DriverDispatchTable& dispatch = GetDriverDispatch(device);
 
     err = native_window_set_buffers_dimensions(surface.window.get(),
                                                create_info->imageExtent.width,
@@ -369,8 +385,8 @@
 
     int gralloc_usage = 0;
     // TODO(jessehall): Remove conditional once all drivers have been updated
-    if (driver_vtbl.GetSwapchainGrallocUsageANDROID) {
-        result = driver_vtbl.GetSwapchainGrallocUsageANDROID(
+    if (dispatch.GetSwapchainGrallocUsageANDROID) {
+        result = dispatch.GetSwapchainGrallocUsageANDROID(
             device, create_info->imageFormat, create_info->imageUsage,
             &gralloc_usage);
         if (result != VK_SUCCESS) {
@@ -391,8 +407,9 @@
     // -- Allocate our Swapchain object --
     // After this point, we must deallocate the swapchain on error.
 
-    void* mem = AllocMem(device, sizeof(Swapchain), alignof(Swapchain),
-                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    void* mem = allocator->pfnAllocation(allocator->pUserData,
+                                         sizeof(Swapchain), alignof(Swapchain),
+                                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (!mem)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     Swapchain* swapchain = new (mem) Swapchain(surface, num_images);
@@ -401,7 +418,6 @@
     // Any failures during or after this must cancel the dequeued buffers.
 
     VkNativeBufferANDROID image_native_buffer = {
-// TODO(jessehall): Figure out how to make extension headers not horrible.
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wold-style-cast"
         .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
@@ -449,7 +465,7 @@
         image_native_buffer.usage = img.buffer->usage;
 
         result =
-            driver_vtbl.CreateImage(device, &image_create, nullptr, &img.image);
+            dispatch.CreateImage(device, &image_create, nullptr, &img.image);
         if (result != VK_SUCCESS) {
             ALOGD("vkCreateImage w/ native buffer failed: %u", result);
             break;
@@ -472,13 +488,13 @@
         }
         if (result != VK_SUCCESS) {
             if (img.image)
-                driver_vtbl.DestroyImage(device, img.image, nullptr);
+                dispatch.DestroyImage(device, img.image, nullptr);
         }
     }
 
     if (result != VK_SUCCESS) {
         swapchain->~Swapchain();
-        FreeMem(device, swapchain);
+        allocator->pfnFree(allocator->pUserData, swapchain);
         return result;
     }
 
@@ -487,10 +503,10 @@
 }
 
 VKAPI_ATTR
-void DestroySwapchainKHR(VkDevice device,
-                         VkSwapchainKHR swapchain_handle,
-                         const VkAllocationCallbacks* /*allocator*/) {
-    const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
+void DestroySwapchainKHR_Bottom(VkDevice device,
+                                VkSwapchainKHR swapchain_handle,
+                                const VkAllocationCallbacks* allocator) {
+    const DriverDispatchTable& dispatch = GetDriverDispatch(device);
     Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
     const std::shared_ptr<ANativeWindow>& window = swapchain->surface.window;
 
@@ -503,19 +519,21 @@
             img.dequeued = false;
         }
         if (img.image) {
-            driver_vtbl.DestroyImage(device, img.image, nullptr);
+            dispatch.DestroyImage(device, img.image, nullptr);
         }
     }
 
+    if (!allocator)
+        allocator = GetAllocator(device);
     swapchain->~Swapchain();
-    FreeMem(device, swapchain);
+    allocator->pfnFree(allocator->pUserData, swapchain);
 }
 
 VKAPI_ATTR
-VkResult GetSwapchainImagesKHR(VkDevice,
-                               VkSwapchainKHR swapchain_handle,
-                               uint32_t* count,
-                               VkImage* images) {
+VkResult GetSwapchainImagesKHR_Bottom(VkDevice,
+                                      VkSwapchainKHR swapchain_handle,
+                                      uint32_t* count,
+                                      VkImage* images) {
     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
     VkResult result = VK_SUCCESS;
     if (images) {
@@ -532,12 +550,12 @@
 }
 
 VKAPI_ATTR
-VkResult AcquireNextImageKHR(VkDevice device,
-                             VkSwapchainKHR swapchain_handle,
-                             uint64_t timeout,
-                             VkSemaphore semaphore,
-                             VkFence vk_fence,
-                             uint32_t* image_index) {
+VkResult AcquireNextImageKHR_Bottom(VkDevice device,
+                                    VkSwapchainKHR swapchain_handle,
+                                    uint64_t timeout,
+                                    VkSemaphore semaphore,
+                                    VkFence vk_fence,
+                                    uint32_t* image_index) {
     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
     ANativeWindow* window = swapchain.surface.window.get();
     VkResult result;
@@ -581,18 +599,8 @@
         }
     }
 
-    const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
-    if (driver_vtbl.AcquireImageANDROID) {
-        result =
-            driver_vtbl.AcquireImageANDROID(device, swapchain.images[idx].image,
-                                            fence_clone, semaphore, vk_fence);
-    } else {
-        ALOG_ASSERT(driver_vtbl.ImportNativeFenceANDROID,
-                    "Have neither vkAcquireImageANDROID nor "
-                    "vkImportNativeFenceANDROID");
-        result = driver_vtbl.ImportNativeFenceANDROID(device, semaphore,
-                                                      fence_clone);
-    }
+    result = GetDriverDispatch(device).AcquireImageANDROID(
+        device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence);
     if (result != VK_SUCCESS) {
         // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
         // even if the call fails. We could close it ourselves on failure, but
@@ -612,13 +620,14 @@
 }
 
 VKAPI_ATTR
-VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
+VkResult QueuePresentKHR_Bottom(VkQueue queue,
+                                const VkPresentInfoKHR* present_info) {
     ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
              "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d",
              present_info->sType);
     ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL");
 
-    const DeviceVtbl& driver_vtbl = GetDriverVtbl(queue);
+    const DriverDispatchTable& dispatch = GetDriverDispatch(queue);
     VkResult final_result = VK_SUCCESS;
     for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) {
         Swapchain& swapchain =
@@ -630,15 +639,8 @@
         int err;
 
         int fence = -1;
-        if (driver_vtbl.QueueSignalReleaseImageANDROID) {
-            result = driver_vtbl.QueueSignalReleaseImageANDROID(
-                queue, img.image, &fence);
-        } else {
-            ALOG_ASSERT(driver_vtbl.QueueSignalNativeFenceANDROID,
-                        "Have neither vkQueueSignalReleaseImageANDROID nor "
-                        "vkQueueSignalNativeFenceANDROID");
-            result = driver_vtbl.QueueSignalNativeFenceANDROID(queue, &fence);
-        }
+        result =
+            dispatch.QueueSignalReleaseImageANDROID(queue, img.image, &fence);
         if (result != VK_SUCCESS) {
             ALOGE("QueueSignalReleaseImageANDROID failed: %d", result);
             if (present_info->pResults)