vulkan: rewrite top of loader
The top is responsible for layer discovery and chaining, and the bottom is
like a regular layer that is always enabled and is inserted just before
the driver. Make the separation clear by rewriting the top and stripping
the layer managment code from loader.cpp.
Change-Id: I64e525e27bd4c297bccd94a1eb9b88e28088e85d
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index 6531968..65b09db 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -16,6 +16,7 @@
// module header
#include "loader.h"
+#include "driver.h"
// standard C headers
#include <dirent.h>
#include <dlfcn.h>
@@ -150,7 +151,7 @@
return ptr;
void* new_ptr = nullptr;
- if (posix_memalign(&new_ptr, alignment, size) != 0)
+ if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
return nullptr;
if (ptr) {
memcpy(new_ptr, ptr, std::min(old_size, size));
@@ -231,38 +232,21 @@
g_driver_instance_extensions.reset(kKHR_android_surface);
}
-bool EnsureInitialized() {
- static std::once_flag once_flag;
- std::call_once(once_flag, []() {
- LoadVulkanHAL();
- DiscoverLayers();
- });
- return g_hwdevice != nullptr;
-}
-
// -----------------------------------------------------------------------------
struct Instance {
Instance(const VkAllocationCallbacks* alloc_callbacks)
- : dispatch_ptr(&dispatch),
- handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
- alloc(alloc_callbacks),
- num_physical_devices(0),
- active_layers(CallbackAllocator<LayerRef>(alloc)),
- message(VK_NULL_HANDLE) {
- memset(&dispatch, 0, sizeof(dispatch));
+ : base{{}, *alloc_callbacks},
+ alloc(&base.allocator),
+ num_physical_devices(0) {
memset(physical_devices, 0, sizeof(physical_devices));
enabled_extensions.reset();
- drv.instance = VK_NULL_HANDLE;
memset(&drv.dispatch, 0, sizeof(drv.dispatch));
- drv.num_physical_devices = 0;
}
~Instance() {}
- const InstanceDispatchTable* dispatch_ptr;
- const VkInstance handle;
- InstanceDispatchTable dispatch;
+ driver::InstanceData base;
const VkAllocationCallbacks* alloc;
uint32_t num_physical_devices;
@@ -270,29 +254,24 @@
VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
- Vector<LayerRef> active_layers;
- VkDebugReportCallbackEXT message;
DebugReportCallbackList debug_report_callbacks;
InstanceExtensionSet enabled_extensions;
struct {
- VkInstance instance;
DriverDispatchTable dispatch;
- uint32_t num_physical_devices;
} drv; // may eventually be an array
};
struct Device {
Device(Instance* instance_)
- : instance(instance_),
- active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
- memset(&dispatch, 0, sizeof(dispatch));
+ : base{{}, *instance_->alloc}, instance(instance_) {
enabled_extensions.reset();
}
- DeviceDispatchTable dispatch;
+
+ driver::DeviceData base;
+
Instance* instance;
PFN_vkGetDeviceProcAddr get_device_proc_addr;
- Vector<LayerRef> active_layers;
DeviceExtensionSet enabled_extensions;
};
@@ -329,230 +308,25 @@
typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-offsetof"
- const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
+ const size_t kBaseOffset = offsetof(ObjectType, base);
#pragma clang diagnostic pop
- const auto& dispatch = GetDispatchTable(handle);
- uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
- uintptr_t object_addr = dispatch_addr - kDispatchOffset;
+ const auto& base = driver::GetData(handle);
+ uintptr_t base_addr = reinterpret_cast<uintptr_t>(&base);
+ uintptr_t object_addr = base_addr - kBaseOffset;
return *reinterpret_cast<ObjectType*>(object_addr);
}
// -----------------------------------------------------------------------------
-void DestroyDevice(Device* device) {
- const VkAllocationCallbacks* alloc = device->instance->alloc;
+void DestroyDevice(Device* device, VkDevice vkdevice) {
+ const auto& instance = *device->instance;
+
+ if (vkdevice != VK_NULL_HANDLE)
+ instance.drv.dispatch.DestroyDevice(vkdevice, instance.alloc);
+
device->~Device();
- alloc->pfnFree(alloc->pUserData, device);
-}
-
-template <class TObject>
-LayerRef GetLayerRef(const char* name);
-template <>
-LayerRef GetLayerRef<Instance>(const char* name) {
- return GetInstanceLayerRef(name);
-}
-template <>
-LayerRef GetLayerRef<Device>(const char* name) {
- return GetDeviceLayerRef(name);
-}
-
-template <class TObject>
-bool ActivateLayer(TObject* object, const char* name) {
- LayerRef layer(GetLayerRef<TObject>(name));
- if (!layer)
- return false;
- if (std::find(object->active_layers.begin(), object->active_layers.end(),
- layer) == object->active_layers.end()) {
- try {
- object->active_layers.push_back(std::move(layer));
- } catch (std::bad_alloc&) {
- // TODO(jessehall): We should fail with VK_ERROR_OUT_OF_MEMORY
- // if we can't enable a requested layer. Callers currently ignore
- // ActivateLayer's return value.
- ALOGW("failed to activate layer '%s': out of memory", name);
- return false;
- }
- }
- ALOGV("activated layer '%s'", name);
- return true;
-}
-
-struct InstanceNamesPair {
- Instance* instance;
- Vector<String>* layer_names;
-};
-
-void SetLayerNamesFromProperty(const char* name,
- const char* value,
- void* data) {
- try {
- const char prefix[] = "debug.vulkan.layer.";
- const size_t prefixlen = sizeof(prefix) - 1;
- if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
- return;
- const char* number_str = name + prefixlen;
- long layer_number = strtol(number_str, nullptr, 10);
- if (layer_number <= 0 || layer_number == LONG_MAX) {
- ALOGW("Cannot use a layer at number %ld from string %s",
- layer_number, number_str);
- return;
- }
- auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
- Vector<String>* layer_names = instance_names_pair->layer_names;
- Instance* instance = instance_names_pair->instance;
- size_t layer_size = static_cast<size_t>(layer_number);
- if (layer_size > layer_names->size()) {
- layer_names->resize(
- layer_size, String(CallbackAllocator<char>(instance->alloc)));
- }
- (*layer_names)[layer_size - 1] = value;
- } catch (std::bad_alloc&) {
- ALOGW("failed to handle property '%s'='%s': out of memory", name,
- value);
- return;
- }
-}
-
-template <class TInfo, class TObject>
-VkResult ActivateAllLayers(TInfo create_info,
- Instance* instance,
- TObject* object) {
- ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
- create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- "Cannot activate layers for unknown object %p", object);
- CallbackAllocator<char> string_allocator(instance->alloc);
- // Load system layers
- if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
- char layer_prop[PROPERTY_VALUE_MAX];
- property_get("debug.vulkan.layers", layer_prop, "");
- char* strtok_state;
- char* layer_name = nullptr;
- while ((layer_name = strtok_r(layer_name ? nullptr : layer_prop, ":",
- &strtok_state))) {
- ActivateLayer(object, layer_name);
- }
- Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
- InstanceNamesPair instance_names_pair = {.instance = instance,
- .layer_names = &layer_names};
- property_list(SetLayerNamesFromProperty,
- static_cast<void*>(&instance_names_pair));
- for (auto layer_name_element : layer_names) {
- ActivateLayer(object, layer_name_element.c_str());
- }
- }
- // Load app layers
- for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
- if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
- ALOGE("requested %s layer '%s' not present",
- create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
- ? "instance"
- : "device",
- create_info->ppEnabledLayerNames[i]);
- return VK_ERROR_LAYER_NOT_PRESENT;
- }
- }
- return VK_SUCCESS;
-}
-
-template <class TCreateInfo, class TObject>
-bool AddLayersToCreateInfo(TCreateInfo& local_create_info,
- const TObject& object,
- const VkAllocationCallbacks* alloc,
- bool& allocatedMemory) {
- // This should never happen and means there is a likely a bug in layer
- // tracking
- if (object->active_layers.size() < local_create_info.enabledLayerCount) {
- ALOGE("Total number of layers is less than those enabled by the app!");
- return false;
- }
- // Check if the total number of layers enabled is greater than those
- // enabled by the application. If it is then we have system enabled
- // layers which need to be added to the list of layers passed in through
- // create.
- if (object->active_layers.size() > local_create_info.enabledLayerCount) {
- void* mem = alloc->pfnAllocation(
- alloc->pUserData, object->active_layers.size() * sizeof(char*),
- alignof(char*), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
- if (mem) {
- local_create_info.enabledLayerCount = 0;
- const char** names = static_cast<const char**>(mem);
- for (const auto& layer : object->active_layers) {
- const char* name = layer.GetName();
- names[local_create_info.enabledLayerCount++] = name;
- }
- local_create_info.ppEnabledLayerNames = names;
- } else {
- ALOGE("System layers cannot be enabled: memory allocation failed");
- return false;
- }
- allocatedMemory = true;
- } else {
- allocatedMemory = false;
- }
- return true;
-}
-
-template <class T>
-void FreeAllocatedLayerCreateInfo(T& local_create_info,
- const VkAllocationCallbacks* alloc) {
- alloc->pfnFree(alloc->pUserData,
- const_cast<char**>(local_create_info.ppEnabledLayerNames));
-}
-
-template <class TCreateInfo>
-bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
- const char* extension_name,
- const VkAllocationCallbacks* alloc) {
- uint32_t extension_count = local_create_info.enabledExtensionCount;
- local_create_info.enabledExtensionCount++;
- void* mem = alloc->pfnAllocation(
- alloc->pUserData,
- local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
- VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
- if (mem) {
- const char** enabled_extensions = static_cast<const char**>(mem);
- for (uint32_t i = 0; i < extension_count; ++i) {
- enabled_extensions[i] =
- local_create_info.ppEnabledExtensionNames[i];
- }
- enabled_extensions[extension_count] = extension_name;
- local_create_info.ppEnabledExtensionNames = enabled_extensions;
- } else {
- ALOGE("%s extension cannot be enabled: memory allocation failed",
- extension_name);
- return false;
- }
- return true;
-}
-
-template <class T>
-void FreeAllocatedExtensionCreateInfo(T& local_create_info,
- const VkAllocationCallbacks* alloc) {
- alloc->pfnFree(
- alloc->pUserData,
- const_cast<char**>(local_create_info.ppEnabledExtensionNames));
-}
-
-VKAPI_ATTR
-VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
- VkDebugReportObjectTypeEXT /*objectType*/,
- uint64_t /*object*/,
- size_t /*location*/,
- int32_t message_code,
- const char* layer_prefix,
- const char* message,
- void* /*user_data*/) {
- if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
- ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
- } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
- ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
- }
- return false;
-}
-
-VkResult Noop() {
- return VK_SUCCESS;
+ instance.alloc->pfnFree(instance.alloc->pUserData, device);
}
/*
@@ -583,16 +357,11 @@
// function, iff the lower vkCreateInstance call has been made and returned
// successfully.
void DestroyInstance(Instance* instance,
- const VkAllocationCallbacks* allocator) {
- if (instance->message) {
- PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
- destroy_debug_report_callback =
- reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
- GetInstanceProcAddr_Top(instance->handle,
- "vkDestroyDebugReportCallbackEXT"));
- destroy_debug_report_callback(instance->handle, instance->message,
- allocator);
- }
+ const VkAllocationCallbacks* allocator,
+ VkInstance vkinstance) {
+ if (vkinstance != VK_NULL_HANDLE && instance->drv.dispatch.DestroyInstance)
+ instance->drv.dispatch.DestroyInstance(vkinstance, allocator);
+
instance->~Instance();
allocator->pfnFree(allocator->pUserData, instance);
}
@@ -610,20 +379,15 @@
VkInstance* vkinstance) {
VkResult result;
- VkLayerInstanceCreateInfo* chain_info =
- const_cast<VkLayerInstanceCreateInfo*>(
- static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
- while (
- chain_info &&
- !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
- chain_info->function == VK_LAYER_FUNCTION_INSTANCE)) {
- chain_info = const_cast<VkLayerInstanceCreateInfo*>(
- static_cast<const VkLayerInstanceCreateInfo*>(chain_info->pNext));
- }
- ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
+ if (!allocator)
+ allocator = &kDefaultAllocCallbacks;
- Instance& instance = GetDispatchParent(
- static_cast<VkInstance>(chain_info->u.instanceInfo.instance_info));
+ void* instance_mem = allocator->pfnAllocation(
+ allocator->pUserData, sizeof(Instance), alignof(Instance),
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (!instance_mem)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ Instance& instance = *new (instance_mem) Instance(allocator);
// Check that all enabled extensions are supported
uint32_t num_driver_extensions = 0;
@@ -645,19 +409,6 @@
continue;
}
}
- bool supported = false;
- for (const auto& layer : instance.active_layers) {
- if (layer.SupportsExtension(name))
- supported = true;
- }
- if (!supported) {
- ALOGE(
- "requested instance extension '%s' not supported by "
- "loader, driver, or any active layers",
- name);
- DestroyInstance_Bottom(instance.handle, allocator);
- return VK_ERROR_EXTENSION_NOT_PRESENT;
- }
}
VkInstanceCreateInfo driver_create_info = *create_info;
@@ -686,60 +437,48 @@
"different answers!");
}
+ VkInstance drv_instance;
result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
- &instance.drv.instance);
+ &drv_instance);
if (result != VK_SUCCESS) {
- DestroyInstance_Bottom(instance.handle, allocator);
+ DestroyInstance(&instance, allocator, VK_NULL_HANDLE);
return result;
}
- hwvulkan_dispatch_t* drv_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
- if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
- ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
- drv_dispatch->magic);
- DestroyInstance_Bottom(instance.handle, allocator);
+ if (!driver::SetData(drv_instance, instance.base)) {
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_INITIALIZATION_FAILED;
}
- // Skip setting drv_dispatch->vtbl, since we never call through it;
- // we go through instance.drv.dispatch instead.
- if (!LoadDriverDispatchTable(
- instance.drv.instance, g_hwdevice->GetInstanceProcAddr,
- instance.enabled_extensions, instance.drv.dispatch)) {
- DestroyInstance_Bottom(instance.handle, allocator);
+ if (!LoadDriverDispatchTable(drv_instance, g_hwdevice->GetInstanceProcAddr,
+ instance.enabled_extensions,
+ instance.drv.dispatch)) {
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_INITIALIZATION_FAILED;
}
uint32_t num_physical_devices = 0;
result = instance.drv.dispatch.EnumeratePhysicalDevices(
- instance.drv.instance, &num_physical_devices, nullptr);
+ drv_instance, &num_physical_devices, nullptr);
if (result != VK_SUCCESS) {
- DestroyInstance_Bottom(instance.handle, allocator);
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_INITIALIZATION_FAILED;
}
num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
result = instance.drv.dispatch.EnumeratePhysicalDevices(
- instance.drv.instance, &num_physical_devices,
- instance.physical_devices);
+ drv_instance, &num_physical_devices, instance.physical_devices);
if (result != VK_SUCCESS) {
- DestroyInstance_Bottom(instance.handle, allocator);
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_INITIALIZATION_FAILED;
}
Vector<VkExtensionProperties> extensions(
Vector<VkExtensionProperties>::allocator_type(instance.alloc));
for (uint32_t i = 0; i < num_physical_devices; i++) {
- hwvulkan_dispatch_t* pdev_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(
- instance.physical_devices[i]);
- if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
- ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
- pdev_dispatch->magic);
- DestroyInstance_Bottom(instance.handle, allocator);
+ if (!driver::SetData(instance.physical_devices[i], instance.base)) {
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_INITIALIZATION_FAILED;
}
- pdev_dispatch->vtbl = instance.dispatch_ptr;
uint32_t count;
if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
@@ -753,7 +492,7 @@
extensions.resize(count);
} catch (std::bad_alloc&) {
ALOGE("instance creation failed: out of memory");
- DestroyInstance_Bottom(instance.handle, allocator);
+ DestroyInstance(&instance, allocator, drv_instance);
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
@@ -778,10 +517,9 @@
// Ignore driver attempts to support loader extensions
instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
}
- instance.drv.num_physical_devices = num_physical_devices;
- instance.num_physical_devices = instance.drv.num_physical_devices;
+ instance.num_physical_devices = num_physical_devices;
- *vkinstance = instance.handle;
+ *vkinstance = drv_instance;
return VK_SUCCESS;
}
@@ -888,7 +626,7 @@
}
if ((pfn = GetLoaderBottomProcAddr(name)))
return pfn;
- return nullptr;
+ return g_hwdevice->GetInstanceProcAddr(vkinstance, name);
}
VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
@@ -968,15 +706,38 @@
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 /*pdev*/,
- const char* /*layer_name*/,
- uint32_t* /*properties_count*/,
- VkExtensionProperties* /*properties*/) {
- return VK_SUCCESS;
+ VkPhysicalDevice pdev,
+ const char* layer_name,
+ uint32_t* properties_count,
+ VkExtensionProperties* properties) {
+ (void)layer_name;
+
+ Instance& instance = GetDispatchParent(pdev);
+
+ size_t gpu_idx = 0;
+ while (instance.physical_devices[gpu_idx] != pdev)
+ 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)));
+ uint32_t num_extensions = 0;
+ if (driver_extensions[kANDROID_native_buffer]) {
+ available[num_extensions++] = VkExtensionProperties{
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
+ }
+
+ if (!properties || *properties_count > num_extensions)
+ *properties_count = num_extensions;
+ if (properties)
+ std::copy(available, available + *properties_count, properties);
+
+ return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
}
// This is a no-op, the Top function returns the aggregate layer property
@@ -994,23 +755,24 @@
const VkDeviceCreateInfo* create_info,
const VkAllocationCallbacks* allocator,
VkDevice* device_out) {
- VkLayerDeviceCreateInfo* chain_info = const_cast<VkLayerDeviceCreateInfo*>(
- static_cast<const VkLayerDeviceCreateInfo*>(create_info->pNext));
- while (chain_info &&
- !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO &&
- chain_info->function == VK_LAYER_FUNCTION_DEVICE)) {
- chain_info = const_cast<VkLayerDeviceCreateInfo*>(
- static_cast<const VkLayerDeviceCreateInfo*>(chain_info->pNext));
- }
- ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
-
Instance& instance = GetDispatchParent(gpu);
+
+ // FIXME(jessehall): We don't have good conventions or infrastructure yet to
+ // do better than just using the instance allocator and scope for
+ // everything. See b/26732122.
+ if (true /*!allocator*/)
+ allocator = instance.alloc;
+
+ void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
+ alignof(Device),
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (!mem)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ Device* device = new (mem) Device(&instance);
+
size_t gpu_idx = 0;
while (instance.physical_devices[gpu_idx] != gpu)
gpu_idx++;
- Device* device = static_cast<Device*>(chain_info->u.deviceInfo.device_info);
- PFN_vkGetInstanceProcAddr get_instance_proc_addr =
- chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
VkDeviceCreateInfo driver_create_info = *create_info;
driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
@@ -1040,18 +802,6 @@
continue;
}
}
- bool supported = false;
- for (const auto& layer : device->active_layers) {
- if (layer.SupportsExtension(name))
- supported = true;
- }
- if (!supported) {
- ALOGE(
- "requested device extension '%s' not supported by loader, "
- "driver, or any active layers",
- name);
- return VK_ERROR_EXTENSION_NOT_PRESENT;
- }
}
driver_create_info.enabledExtensionCount = num_driver_extensions;
@@ -1060,25 +810,15 @@
VkResult result = instance.drv.dispatch.CreateDevice(
gpu, &driver_create_info, allocator, &drv_device);
if (result != VK_SUCCESS) {
+ DestroyDevice(device, VK_NULL_HANDLE);
return VK_ERROR_INITIALIZATION_FAILED;
}
- hwvulkan_dispatch_t* drv_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
- if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
- ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
- drv_dispatch->magic);
- PFN_vkDestroyDevice destroy_device =
- reinterpret_cast<PFN_vkDestroyDevice>(
- instance.drv.dispatch.GetDeviceProcAddr(drv_device,
- "vkDestroyDevice"));
- destroy_device(drv_device, allocator);
+ if (!driver::SetData(drv_device, device->base)) {
+ DestroyDevice(device, drv_device);
return VK_ERROR_INITIALIZATION_FAILED;
}
- // Set dispatch table for newly created Device
- // CreateDevice_Top will fill in the details
- drv_dispatch->vtbl = &device->dispatch;
device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
instance.drv.dispatch.GetDeviceProcAddr(drv_device,
"vkGetDeviceProcAddr"));
@@ -1090,14 +830,13 @@
const VkAllocationCallbacks* allocator) {
Instance& instance = GetDispatchParent(vkinstance);
- // These checks allow us to call DestroyInstance_Bottom from any error
- // path in CreateInstance_Bottom, before the driver instance is fully
- // initialized.
- if (instance.drv.instance != VK_NULL_HANDLE &&
- instance.drv.dispatch.DestroyInstance) {
- instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
- instance.drv.instance = VK_NULL_HANDLE;
+ VkAllocationCallbacks local_allocator;
+ if (!allocator) {
+ local_allocator = *instance.alloc;
+ allocator = &local_allocator;
}
+
+ DestroyInstance(&instance, allocator, vkinstance);
}
VkResult CreateSwapchainKHR_Disabled(VkDevice,
@@ -1185,507 +924,36 @@
return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
}
-// -----------------------------------------------------------------------------
-// Loader top functions. These are called directly from the loader entry
-// points or from the application (via vkGetInstanceProcAddr) without going
-// through a dispatch table.
-
-VkResult EnumerateInstanceExtensionProperties_Top(
- const char* layer_name,
- uint32_t* properties_count,
- VkExtensionProperties* properties) {
- if (!EnsureInitialized())
- return VK_ERROR_INITIALIZATION_FAILED;
-
- const VkExtensionProperties* extensions = nullptr;
- uint32_t num_extensions = 0;
- if (layer_name) {
- GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
- } else {
- VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
- alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
- available[num_extensions++] = VkExtensionProperties{
- VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
- available[num_extensions++] =
- VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
- VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
- if (g_driver_instance_extensions[kEXT_debug_report]) {
- available[num_extensions++] =
- VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
- VK_EXT_DEBUG_REPORT_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;
+void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) {
+ DestroyDevice(&GetDispatchParent(vkdevice), vkdevice);
}
-VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
- VkLayerProperties* properties) {
- if (!EnsureInitialized())
- return VK_ERROR_INITIALIZATION_FAILED;
+void GetDeviceQueue_Bottom(VkDevice vkdevice,
+ uint32_t family,
+ uint32_t index,
+ VkQueue* queue_out) {
+ const auto& device = GetDispatchParent(vkdevice);
+ const auto& instance = *device.instance;
- uint32_t layer_count =
- EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
- if (!properties || *properties_count > layer_count)
- *properties_count = layer_count;
- return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
+ instance.drv.dispatch.GetDeviceQueue(vkdevice, family, index, queue_out);
+ driver::SetData(*queue_out, device.base);
}
-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_top[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) {
- VkResult result;
-
- if (!EnsureInitialized())
- return VK_ERROR_INITIALIZATION_FAILED;
-
- if (!allocator)
- allocator = &kDefaultAllocCallbacks;
-
- VkInstanceCreateInfo local_create_info = *create_info;
- create_info = &local_create_info;
-
- void* instance_mem = allocator->pfnAllocation(
- allocator->pUserData, sizeof(Instance), alignof(Instance),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
- if (!instance_mem)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- Instance* instance = new (instance_mem) Instance(allocator);
-
- result = ActivateAllLayers(create_info, instance, instance);
- if (result != VK_SUCCESS) {
- DestroyInstance(instance, allocator);
- return result;
- }
-
- uint32_t activated_layers = 0;
- VkLayerInstanceCreateInfo chain_info;
- VkLayerInstanceLink* layer_instance_link_info = nullptr;
- PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
- VkInstance local_instance = nullptr;
-
- if (instance->active_layers.size() > 0) {
- chain_info.u.pLayerInfo = nullptr;
- chain_info.pNext = create_info->pNext;
- chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
- chain_info.function = VK_LAYER_FUNCTION_LINK;
- local_create_info.pNext = &chain_info;
-
- layer_instance_link_info = static_cast<VkLayerInstanceLink*>(alloca(
- sizeof(VkLayerInstanceLink) * instance->active_layers.size()));
- if (!layer_instance_link_info) {
- ALOGE("Failed to alloc Instance objects for layers");
- DestroyInstance(instance, allocator);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
-
- /* Create instance chain of enabled layers */
- for (auto rit = instance->active_layers.rbegin();
- rit != instance->active_layers.rend(); ++rit) {
- LayerRef& layer = *rit;
- layer_instance_link_info[activated_layers].pNext =
- chain_info.u.pLayerInfo;
- layer_instance_link_info[activated_layers]
- .pfnNextGetInstanceProcAddr = next_gipa;
- chain_info.u.pLayerInfo =
- &layer_instance_link_info[activated_layers];
- next_gipa = layer.GetGetInstanceProcAddr();
-
- ALOGV("Insert instance layer %s (v%u)", layer.GetName(),
- layer.GetSpecVersion());
-
- activated_layers++;
- }
- }
-
- PFN_vkCreateInstance create_instance =
- reinterpret_cast<PFN_vkCreateInstance>(
- next_gipa(VK_NULL_HANDLE, "vkCreateInstance"));
- if (!create_instance) {
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- VkLayerInstanceCreateInfo instance_create_info;
-
- instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
- instance_create_info.function = VK_LAYER_FUNCTION_INSTANCE;
-
- instance_create_info.u.instanceInfo.instance_info = instance;
- instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr = next_gipa;
-
- instance_create_info.pNext = local_create_info.pNext;
- local_create_info.pNext = &instance_create_info;
-
- // Force enable callback extension if required
- bool enable_callback = false;
- if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
- enable_callback =
- property_get_bool("debug.vulkan.enable_callback", false);
- if (enable_callback) {
- if (!AddExtensionToCreateInfo(local_create_info,
- "VK_EXT_debug_report", allocator)) {
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- }
- }
- bool allocatedLayerMem;
- if (!AddLayersToCreateInfo(local_create_info, instance, allocator,
- allocatedLayerMem)) {
- if (enable_callback) {
- FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
- }
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- result = create_instance(&local_create_info, allocator, &local_instance);
-
- if (allocatedLayerMem) {
- FreeAllocatedLayerCreateInfo(local_create_info, allocator);
- }
- if (enable_callback) {
- FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
- }
-
- if (result != VK_SUCCESS) {
- DestroyInstance(instance, allocator);
- return result;
- }
-
- const InstanceDispatchTable& instance_dispatch =
- GetDispatchTable(local_instance);
- if (!LoadInstanceDispatchTable(
- local_instance, next_gipa,
- const_cast<InstanceDispatchTable&>(instance_dispatch))) {
- ALOGV("Failed to initialize instance dispatch table");
- PFN_vkDestroyInstance destroy_instance =
- reinterpret_cast<PFN_vkDestroyInstance>(
- next_gipa(local_instance, "vkDestroyInstance"));
- if (!destroy_instance) {
- ALOGD("Loader unable to find DestroyInstance");
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- destroy_instance(local_instance, allocator);
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- // Capture the physical devices from the top of the
- // chain in case it has been wrapped by a layer.
- uint32_t num_physical_devices = 0;
- result = instance_dispatch.EnumeratePhysicalDevices(
- local_instance, &num_physical_devices, nullptr);
- if (result != VK_SUCCESS) {
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
- result = instance_dispatch.EnumeratePhysicalDevices(
- local_instance, &num_physical_devices,
- instance->physical_devices_top);
- if (result != VK_SUCCESS) {
- DestroyInstance(instance, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- *instance_out = local_instance;
-
- if (enable_callback) {
- const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
- .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
- .flags =
- VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
- .pfnCallback = LogDebugMessageCallback,
- };
- PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
- reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
- GetInstanceProcAddr_Top(instance->handle,
- "vkCreateDebugReportCallbackEXT"));
- create_debug_report_callback(instance->handle, &callback_create_info,
- allocator, &instance->message);
- }
-
- return result;
-}
-
-PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
- const char* name) {
- // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
- if (!vkinstance)
- return GetLoaderGlobalProcAddr(name);
-
- const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
- PFN_vkVoidFunction pfn;
- // Always go through the loader-top function if there is one.
- if ((pfn = GetLoaderTopProcAddr(name)))
- return pfn;
- // Otherwise, look up the handler in the instance dispatch table
- if ((pfn = GetDispatchProcAddr(dispatch, name)))
- return pfn;
- // Anything not handled already must be a device-dispatched function
- // without a loader-top. We must return a function that will dispatch based
- // on the dispatchable object parameter -- which is exactly what the
- // exported functions do. So just return them here.
- return GetLoaderExportProcAddr(name);
-}
-
-void DestroyInstance_Top(VkInstance vkinstance,
- const VkAllocationCallbacks* allocator) {
- if (!vkinstance)
- return;
- if (!allocator)
- allocator = &kDefaultAllocCallbacks;
- GetDispatchTable(vkinstance).DestroyInstance(vkinstance, allocator);
- DestroyInstance(&(GetDispatchParent(vkinstance)), allocator);
-}
-
-VKAPI_ATTR
-VkResult EnumerateDeviceLayerProperties_Top(VkPhysicalDevice /*pdev*/,
- uint32_t* properties_count,
- VkLayerProperties* properties) {
- uint32_t layer_count =
- EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
- if (!properties || *properties_count > layer_count)
- *properties_count = layer_count;
- return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
-}
-
-VKAPI_ATTR
-VkResult CreateDevice_Top(VkPhysicalDevice gpu,
- const VkDeviceCreateInfo* create_info,
- const VkAllocationCallbacks* allocator,
- VkDevice* device_out) {
- Instance& instance = GetDispatchParent(gpu);
- VkResult result;
-
- // FIXME(jessehall): We don't have good conventions or infrastructure yet to
- // do better than just using the instance allocator and scope for
- // everything. See b/26732122.
- if (true /*!allocator*/)
- allocator = instance.alloc;
-
- void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
- alignof(Device),
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
- if (!mem)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- Device* device = new (mem) Device(&instance);
-
- result = ActivateAllLayers(create_info, &instance, device);
- if (result != VK_SUCCESS) {
- DestroyDevice(device);
- return result;
- }
-
- uint32_t activated_layers = 0;
- VkLayerDeviceCreateInfo chain_info;
- VkLayerDeviceLink* layer_device_link_info = nullptr;
- PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
- PFN_vkGetDeviceProcAddr next_gdpa = GetDeviceProcAddr_Bottom;
- VkDeviceCreateInfo local_create_info = *create_info;
- VkDevice local_device = nullptr;
-
- if (device->active_layers.size() > 0) {
- chain_info.u.pLayerInfo = nullptr;
- chain_info.pNext = local_create_info.pNext;
- chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
- chain_info.function = VK_LAYER_FUNCTION_LINK;
- local_create_info.pNext = &chain_info;
-
- layer_device_link_info = static_cast<VkLayerDeviceLink*>(
- alloca(sizeof(VkLayerDeviceLink) * device->active_layers.size()));
- if (!layer_device_link_info) {
- ALOGE("Failed to alloc Device objects for layers");
- DestroyDevice(device);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
-
- /* Create device chain of enabled layers */
- for (auto rit = device->active_layers.rbegin();
- rit != device->active_layers.rend(); ++rit) {
- LayerRef& layer = *rit;
- layer_device_link_info[activated_layers].pNext =
- chain_info.u.pLayerInfo;
- layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr =
- next_gdpa;
- layer_device_link_info[activated_layers]
- .pfnNextGetInstanceProcAddr = next_gipa;
- chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
-
- next_gipa = layer.GetGetInstanceProcAddr();
- next_gdpa = layer.GetGetDeviceProcAddr();
-
- ALOGV("Insert device layer %s (v%u)", layer.GetName(),
- layer.GetSpecVersion());
-
- activated_layers++;
- }
- }
-
- PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
- next_gipa(instance.handle, "vkCreateDevice"));
- if (!create_device) {
- ALOGE("Unable to find vkCreateDevice for driver");
- DestroyDevice(device);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- VkLayerDeviceCreateInfo device_create_info;
-
- device_create_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
- device_create_info.function = VK_LAYER_FUNCTION_DEVICE;
-
- device_create_info.u.deviceInfo.device_info = device;
- device_create_info.u.deviceInfo.pfnNextGetInstanceProcAddr = next_gipa;
-
- device_create_info.pNext = local_create_info.pNext;
- local_create_info.pNext = &device_create_info;
-
- bool allocatedLayerMem;
- if (!AddLayersToCreateInfo(local_create_info, device, allocator,
- allocatedLayerMem)) {
- DestroyDevice(device);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- result = create_device(gpu, &local_create_info, allocator, &local_device);
-
- if (allocatedLayerMem) {
- FreeAllocatedLayerCreateInfo(local_create_info, allocator);
- }
-
- if (result != VK_SUCCESS) {
- DestroyDevice(device);
- return result;
- }
-
- // Set dispatch table for newly created Device
- hwvulkan_dispatch_t* vulkan_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(local_device);
- vulkan_dispatch->vtbl = &device->dispatch;
-
- const DeviceDispatchTable& device_dispatch = GetDispatchTable(local_device);
- if (!LoadDeviceDispatchTable(
- local_device, next_gdpa,
- const_cast<DeviceDispatchTable&>(device_dispatch))) {
- ALOGV("Failed to initialize device dispatch table");
- PFN_vkDestroyDevice destroy_device =
- reinterpret_cast<PFN_vkDestroyDevice>(
- next_gipa(instance.handle, "vkDestroyDevice"));
- ALOG_ASSERT(destroy_device != nullptr,
- "Loader unable to find DestroyDevice");
- destroy_device(local_device, allocator);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- *device_out = local_device;
-
- return VK_SUCCESS;
-}
-
-PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
- PFN_vkVoidFunction pfn;
- if (!device)
- return nullptr;
- if ((pfn = GetLoaderTopProcAddr(name)))
- return pfn;
- return GetDispatchProcAddr(GetDispatchTable(device), name);
-}
-
-void GetDeviceQueue_Top(VkDevice vkdevice,
- uint32_t family,
- uint32_t index,
- VkQueue* queue_out) {
- const auto& table = GetDispatchTable(vkdevice);
- table.GetDeviceQueue(vkdevice, family, index, queue_out);
- hwvulkan_dispatch_t* queue_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
- if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
- queue_dispatch->vtbl != &table)
- ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
- queue_dispatch->magic);
- queue_dispatch->vtbl = &table;
-}
-
-VkResult AllocateCommandBuffers_Top(
+VkResult AllocateCommandBuffers_Bottom(
VkDevice vkdevice,
const VkCommandBufferAllocateInfo* alloc_info,
VkCommandBuffer* cmdbufs) {
- const auto& table = GetDispatchTable(vkdevice);
- VkResult result =
- table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
- if (result != VK_SUCCESS)
- return result;
- for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
- hwvulkan_dispatch_t* cmdbuf_dispatch =
- reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
- ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
- "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
- cmdbuf_dispatch->magic);
- cmdbuf_dispatch->vtbl = &table;
- }
- return VK_SUCCESS;
-}
+ const auto& device = GetDispatchParent(vkdevice);
+ const auto& instance = *device.instance;
-void DestroyDevice_Top(VkDevice vkdevice,
- const VkAllocationCallbacks* /*allocator*/) {
- if (!vkdevice)
- return;
- Device& device = GetDispatchParent(vkdevice);
- device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
- DestroyDevice(&device);
+ VkResult result = instance.drv.dispatch.AllocateCommandBuffers(
+ vkdevice, alloc_info, cmdbufs);
+ if (result == VK_SUCCESS) {
+ for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++)
+ driver::SetData(cmdbufs[i], device.base);
+ }
+
+ return result;
}
// -----------------------------------------------------------------------------
@@ -1699,7 +967,7 @@
}
VkInstance GetDriverInstance(VkInstance instance) {
- return GetDispatchParent(instance).drv.instance;
+ return instance;
}
const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
@@ -1718,4 +986,60 @@
return GetDispatchParent(instance).debug_report_callbacks;
}
+namespace driver {
+
+bool Debuggable() {
+ return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
+}
+
+bool OpenHAL() {
+ if (!g_hwdevice)
+ LoadVulkanHAL();
+
+ return (g_hwdevice != nullptr);
+}
+
+const VkAllocationCallbacks& GetDefaultAllocator() {
+ return kDefaultAllocCallbacks;
+}
+
+PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
+ return GetInstanceProcAddr_Bottom(instance, pName);
+}
+
+PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
+ return GetDeviceProcAddr_Bottom(device, pName);
+}
+
+VkResult EnumerateInstanceExtensionProperties(
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties) {
+ (void)pLayerName;
+
+ VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
+ alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
+ uint32_t num_extensions = 0;
+
+ available[num_extensions++] = VkExtensionProperties{
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
+ available[num_extensions++] =
+ VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
+ VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
+ if (g_driver_instance_extensions[kEXT_debug_report]) {
+ available[num_extensions++] =
+ VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
+ VK_EXT_DEBUG_REPORT_SPEC_VERSION};
+ }
+
+ if (!pProperties || *pPropertyCount > num_extensions)
+ *pPropertyCount = num_extensions;
+ if (pProperties)
+ std::copy(available, available + *pPropertyCount, pProperties);
+
+ return *pPropertyCount < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
+}
+
+} // namespace driver
+
} // namespace vulkan