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)