summaryrefslogtreecommitdiff
path: root/vulkan/libvulkan/loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vulkan/libvulkan/loader.cpp')
-rw-r--r--vulkan/libvulkan/loader.cpp1045
1 files changed, 0 insertions, 1045 deletions
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
deleted file mode 100644
index 65b09db145..0000000000
--- a/vulkan/libvulkan/loader.cpp
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * Copyright 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// module header
-#include "loader.h"
-#include "driver.h"
-// standard C headers
-#include <dirent.h>
-#include <dlfcn.h>
-#include <inttypes.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-// standard C++ headers
-#include <algorithm>
-#include <mutex>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-// platform/library headers
-#include <cutils/properties.h>
-#include <hardware/hwvulkan.h>
-#include <log/log.h>
-#include <vulkan/vulkan_loader_data.h>
-#include <vulkan/vk_layer_interface.h>
-
-// #define ENABLE_ALLOC_CALLSTACKS 1
-#if ENABLE_ALLOC_CALLSTACKS
-#include <utils/CallStack.h>
-#define ALOGD_CALLSTACK(...) \
- do { \
- ALOGD(__VA_ARGS__); \
- android::CallStack callstack; \
- callstack.update(); \
- callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
- } while (false)
-#else
-#define ALOGD_CALLSTACK(...) \
- do { \
- } while (false)
-#endif
-
-using namespace vulkan;
-
-static const uint32_t kMaxPhysicalDevices = 4;
-
-namespace {
-
-// ----------------------------------------------------------------------------
-
-// Standard-library allocator that delegates to VkAllocationCallbacks.
-//
-// TODO(jessehall): This class currently always uses
-// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template
-// parameter or a constructor parameter. The former would help catch bugs
-// where we use the wrong scope, e.g. adding a command-scope string to an
-// instance-scope vector. But that might also be pretty annoying to deal with.
-template <class T>
-class CallbackAllocator {
- public:
- typedef T value_type;
-
- CallbackAllocator(const VkAllocationCallbacks* alloc_input)
- : alloc(alloc_input) {}
-
- template <class T2>
- CallbackAllocator(const CallbackAllocator<T2>& other)
- : alloc(other.alloc) {}
-
- T* allocate(std::size_t n) {
- void* mem =
- alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
- if (!mem)
- throw std::bad_alloc();
- return static_cast<T*>(mem);
- }
-
- void deallocate(T* array, std::size_t /*n*/) noexcept {
- alloc->pfnFree(alloc->pUserData, array);
- }
-
- const VkAllocationCallbacks* alloc;
-};
-// These are needed in order to move Strings
-template <class T>
-bool operator==(const CallbackAllocator<T>& alloc1,
- const CallbackAllocator<T>& alloc2) {
- return alloc1.alloc == alloc2.alloc;
-}
-template <class T>
-bool operator!=(const CallbackAllocator<T>& alloc1,
- const CallbackAllocator<T>& alloc2) {
- return !(alloc1 == alloc2);
-}
-
-template <class T>
-using Vector = std::vector<T, CallbackAllocator<T>>;
-
-typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>>
- String;
-
-// ----------------------------------------------------------------------------
-
-VKAPI_ATTR void* DefaultAllocate(void*,
- size_t size,
- size_t alignment,
- VkSystemAllocationScope) {
- void* ptr = nullptr;
- // Vulkan requires 'alignment' to be a power of two, but posix_memalign
- // additionally requires that it be at least sizeof(void*).
- int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
- ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
- ret, ptr);
- return ret == 0 ? ptr : nullptr;
-}
-
-VKAPI_ATTR void* DefaultReallocate(void*,
- void* ptr,
- size_t size,
- size_t alignment,
- VkSystemAllocationScope) {
- if (size == 0) {
- free(ptr);
- return nullptr;
- }
-
- // TODO(jessehall): Right now we never shrink allocations; if the new
- // request is smaller than the existing chunk, we just continue using it.
- // Right now the loader never reallocs, so this doesn't matter. If that
- // changes, or if this code is copied into some other project, this should
- // probably have a heuristic to allocate-copy-free when doing so will save
- // "enough" space.
- size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
- if (size <= old_size)
- return ptr;
-
- void* new_ptr = nullptr;
- 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));
- free(ptr);
- }
- return new_ptr;
-}
-
-VKAPI_ATTR void DefaultFree(void*, void* ptr) {
- ALOGD_CALLSTACK("Free: %p", ptr);
- free(ptr);
-}
-
-const VkAllocationCallbacks kDefaultAllocCallbacks = {
- .pUserData = nullptr,
- .pfnAllocation = DefaultAllocate,
- .pfnReallocation = DefaultReallocate,
- .pfnFree = DefaultFree,
-};
-
-// ----------------------------------------------------------------------------
-// Global Data and Initialization
-
-hwvulkan_device_t* g_hwdevice = nullptr;
-InstanceExtensionSet g_driver_instance_extensions;
-
-void LoadVulkanHAL() {
- static const hwvulkan_module_t* module;
- int result =
- hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
- if (result != 0) {
- ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
- return;
- }
- result = module->common.methods->open(
- &module->common, HWVULKAN_DEVICE_0,
- reinterpret_cast<hw_device_t**>(&g_hwdevice));
- if (result != 0) {
- ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
- result);
- module = nullptr;
- return;
- }
-
- VkResult vkresult;
- uint32_t count;
- if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
- nullptr, &count, nullptr)) != VK_SUCCESS) {
- ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
- vkresult);
- g_hwdevice->common.close(&g_hwdevice->common);
- g_hwdevice = nullptr;
- module = nullptr;
- return;
- }
- VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>(
- alloca(count * sizeof(VkExtensionProperties)));
- if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
- nullptr, &count, extensions)) != VK_SUCCESS) {
- ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
- vkresult);
- g_hwdevice->common.close(&g_hwdevice->common);
- g_hwdevice = nullptr;
- module = nullptr;
- return;
- }
- ALOGV_IF(count > 0, "Driver-supported instance extensions:");
- for (uint32_t i = 0; i < count; i++) {
- ALOGV(" %s (v%u)", extensions[i].extensionName,
- extensions[i].specVersion);
- InstanceExtension id =
- InstanceExtensionFromName(extensions[i].extensionName);
- if (id != kInstanceExtensionCount)
- g_driver_instance_extensions.set(id);
- }
- // Ignore driver attempts to support loader extensions
- g_driver_instance_extensions.reset(kKHR_surface);
- g_driver_instance_extensions.reset(kKHR_android_surface);
-}
-
-// -----------------------------------------------------------------------------
-
-struct Instance {
- Instance(const VkAllocationCallbacks* alloc_callbacks)
- : base{{}, *alloc_callbacks},
- alloc(&base.allocator),
- num_physical_devices(0) {
- memset(physical_devices, 0, sizeof(physical_devices));
- enabled_extensions.reset();
- memset(&drv.dispatch, 0, sizeof(drv.dispatch));
- }
-
- ~Instance() {}
-
- driver::InstanceData base;
-
- const VkAllocationCallbacks* alloc;
- uint32_t num_physical_devices;
- VkPhysicalDevice physical_devices_top[kMaxPhysicalDevices];
- VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
- DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
-
- DebugReportCallbackList debug_report_callbacks;
- InstanceExtensionSet enabled_extensions;
-
- struct {
- DriverDispatchTable dispatch;
- } drv; // may eventually be an array
-};
-
-struct Device {
- Device(Instance* instance_)
- : base{{}, *instance_->alloc}, instance(instance_) {
- enabled_extensions.reset();
- }
-
- driver::DeviceData base;
-
- Instance* instance;
- PFN_vkGetDeviceProcAddr get_device_proc_addr;
- DeviceExtensionSet enabled_extensions;
-};
-
-template <typename THandle>
-struct HandleTraits {};
-template <>
-struct HandleTraits<VkInstance> {
- typedef Instance LoaderObjectType;
-};
-template <>
-struct HandleTraits<VkPhysicalDevice> {
- typedef Instance LoaderObjectType;
-};
-template <>
-struct HandleTraits<VkDevice> {
- typedef Device LoaderObjectType;
-};
-template <>
-struct HandleTraits<VkQueue> {
- typedef Device LoaderObjectType;
-};
-template <>
-struct HandleTraits<VkCommandBuffer> {
- typedef Device LoaderObjectType;
-};
-
-template <typename THandle>
-typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
- THandle handle) {
- // TODO(jessehall): Make Instance and Device POD types (by removing the
- // non-default constructors), so that offsetof is actually legal to use.
- // The specific case we're using here is safe in gcc/clang (and probably
- // most other C++ compilers), but isn't guaranteed by C++.
- typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Winvalid-offsetof"
- const size_t kBaseOffset = offsetof(ObjectType, base);
-#pragma clang diagnostic pop
-
- 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, VkDevice vkdevice) {
- const auto& instance = *device->instance;
-
- if (vkdevice != VK_NULL_HANDLE)
- instance.drv.dispatch.DestroyDevice(vkdevice, instance.alloc);
-
- device->~Device();
- instance.alloc->pfnFree(instance.alloc->pUserData, device);
-}
-
-/*
- * This function will return the pNext pointer of any
- * CreateInfo extensions that are not loader extensions.
- * This is used to skip past the loader extensions prepended
- * to the list during CreateInstance and CreateDevice.
- */
-void* StripCreateExtensions(const void* pNext) {
- VkLayerInstanceCreateInfo* create_info =
- const_cast<VkLayerInstanceCreateInfo*>(
- static_cast<const VkLayerInstanceCreateInfo*>(pNext));
-
- while (
- create_info &&
- (create_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
- create_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)) {
- create_info = const_cast<VkLayerInstanceCreateInfo*>(
- static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
- }
-
- return create_info;
-}
-
-// Clean up and deallocate an Instance; called from both the failure paths in
-// CreateInstance_Top as well as from DestroyInstance_Top. This function does
-// not call down the dispatch chain; that should be done before calling this
-// function, iff the lower vkCreateInstance call has been made and returned
-// successfully.
-void DestroyInstance(Instance* instance,
- 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);
-}
-
-} // anonymous namespace
-
-namespace vulkan {
-
-// -----------------------------------------------------------------------------
-// "Bottom" functions. These are called at the end of the instance dispatch
-// chain.
-
-VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
- const VkAllocationCallbacks* allocator,
- VkInstance* vkinstance) {
- VkResult result;
-
- if (!allocator)
- allocator = &kDefaultAllocCallbacks;
-
- 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;
- for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
- const char* name = create_info->ppEnabledExtensionNames[i];
- InstanceExtension id = InstanceExtensionFromName(name);
- if (id != kInstanceExtensionCount) {
- if (g_driver_instance_extensions[id]) {
- num_driver_extensions++;
- instance.enabled_extensions.set(id);
- continue;
- }
- if (id == kKHR_surface || id == kKHR_android_surface) {
- instance.enabled_extensions.set(id);
- continue;
- }
- // The loader natively supports debug report.
- if (id == kEXT_debug_report) {
- continue;
- }
- }
- }
-
- VkInstanceCreateInfo driver_create_info = *create_info;
- driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
- driver_create_info.enabledLayerCount = 0;
- driver_create_info.ppEnabledLayerNames = nullptr;
- driver_create_info.enabledExtensionCount = 0;
- driver_create_info.ppEnabledExtensionNames = nullptr;
- if (num_driver_extensions > 0) {
- const char** names = static_cast<const char**>(
- alloca(num_driver_extensions * sizeof(char*)));
- for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
- const char* name = create_info->ppEnabledExtensionNames[i];
- InstanceExtension id = InstanceExtensionFromName(name);
- if (id != kInstanceExtensionCount) {
- if (g_driver_instance_extensions[id]) {
- names[driver_create_info.enabledExtensionCount++] = name;
- continue;
- }
- }
- }
- driver_create_info.ppEnabledExtensionNames = names;
- ALOG_ASSERT(
- driver_create_info.enabledExtensionCount == num_driver_extensions,
- "counted enabled driver instance extensions twice and got "
- "different answers!");
- }
-
- VkInstance drv_instance;
- result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
- &drv_instance);
- if (result != VK_SUCCESS) {
- DestroyInstance(&instance, allocator, VK_NULL_HANDLE);
- return result;
- }
-
- if (!driver::SetData(drv_instance, instance.base)) {
- DestroyInstance(&instance, allocator, drv_instance);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- 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(
- drv_instance, &num_physical_devices, nullptr);
- if (result != VK_SUCCESS) {
- DestroyInstance(&instance, allocator, drv_instance);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
- result = instance.drv.dispatch.EnumeratePhysicalDevices(
- drv_instance, &num_physical_devices, instance.physical_devices);
- if (result != VK_SUCCESS) {
- 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++) {
- if (!driver::SetData(instance.physical_devices[i], instance.base)) {
- DestroyInstance(&instance, allocator, drv_instance);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- uint32_t count;
- if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
- instance.physical_devices[i], nullptr, &count, nullptr)) !=
- VK_SUCCESS) {
- ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
- result);
- continue;
- }
- try {
- extensions.resize(count);
- } catch (std::bad_alloc&) {
- ALOGE("instance creation failed: out of memory");
- DestroyInstance(&instance, allocator, drv_instance);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
- if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
- instance.physical_devices[i], nullptr, &count,
- extensions.data())) != VK_SUCCESS) {
- ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
- result);
- continue;
- }
- ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
- for (const auto& extension : extensions) {
- ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
- DeviceExtension id =
- DeviceExtensionFromName(extension.extensionName);
- if (id == kDeviceExtensionCount) {
- ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
- extension.extensionName);
- } else {
- instance.physical_device_driver_extensions[i].set(id);
- }
- }
- // Ignore driver attempts to support loader extensions
- instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
- }
- instance.num_physical_devices = num_physical_devices;
-
- *vkinstance = drv_instance;
-
- return VK_SUCCESS;
-}
-
-VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance,
- const VkAndroidSurfaceCreateInfoKHR*,
- const VkAllocationCallbacks*,
- VkSurfaceKHR*) {
- ALOGE(
- "VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-void DestroySurfaceKHR_Disabled(VkInstance,
- VkSurfaceKHR,
- const VkAllocationCallbacks*) {
- ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
-}
-
-VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice,
- uint32_t,
- VkSurfaceKHR,
- VkBool32*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled(
- VkPhysicalDevice,
- VkSurfaceKHR,
- VkSurfaceCapabilitiesKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceapabilitiesKHR "
- "not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice,
- VkSurfaceKHR,
- uint32_t*,
- VkSurfaceFormatKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice,
- VkSurfaceKHR,
- uint32_t*,
- VkPresentModeKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR "
- "not executed.");
-
- return VK_SUCCESS;
-}
-
-PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance vkinstance,
- const char* name) {
- PFN_vkVoidFunction pfn;
-
- if (vkinstance) {
- Instance& instance = GetDispatchParent(vkinstance);
- if (!instance.enabled_extensions[kKHR_android_surface]) {
- // KHR_android_surface is not enabled, use error stubs instead
- if (strcmp(name, "vkCreateAndroidSurfaceKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- CreateAndroidSurfaceKHR_Disabled);
- }
- }
- if (!instance.enabled_extensions[kKHR_surface]) {
- // KHR_surface is not enabled, use error stubs instead
- if (strcmp(name, "vkDestroySurfaceKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- DestroySurfaceKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceSupportKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceSupportKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") ==
- 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceFormatsKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceFormatsKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfacePresentModesKHR") ==
- 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfacePresentModesKHR_Disabled);
- }
- }
- }
- if ((pfn = GetLoaderBottomProcAddr(name)))
- return pfn;
- return g_hwdevice->GetInstanceProcAddr(vkinstance, name);
-}
-
-VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
- uint32_t* pdev_count,
- VkPhysicalDevice* pdevs) {
- Instance& instance = GetDispatchParent(vkinstance);
- uint32_t count = instance.num_physical_devices;
- if (pdevs) {
- count = std::min(count, *pdev_count);
- std::copy(instance.physical_devices, instance.physical_devices + count,
- pdevs);
- }
- *pdev_count = count;
- return VK_SUCCESS;
-}
-
-void GetPhysicalDeviceProperties_Bottom(
- VkPhysicalDevice pdev,
- VkPhysicalDeviceProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
- pdev, properties);
-}
-
-void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
- VkPhysicalDeviceFeatures* features) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
- features);
-}
-
-void GetPhysicalDeviceMemoryProperties_Bottom(
- VkPhysicalDevice pdev,
- VkPhysicalDeviceMemoryProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
- pdev, properties);
-}
-
-void GetPhysicalDeviceQueueFamilyProperties_Bottom(
- VkPhysicalDevice pdev,
- uint32_t* pCount,
- VkQueueFamilyProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
- pdev, pCount, properties);
-}
-
-void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
- VkFormat format,
- VkFormatProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
- pdev, format, properties);
-}
-
-VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
- VkPhysicalDevice pdev,
- VkFormat format,
- VkImageType type,
- VkImageTiling tiling,
- VkImageUsageFlags usage,
- VkImageCreateFlags flags,
- VkImageFormatProperties* properties) {
- return GetDispatchParent(pdev)
- .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
- pdev, format, type, tiling, usage, flags, properties);
-}
-
-void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
- VkPhysicalDevice pdev,
- VkFormat format,
- VkImageType type,
- VkSampleCountFlagBits samples,
- VkImageUsageFlags usage,
- VkImageTiling tiling,
- uint32_t* properties_count,
- VkSparseImageFormatProperties* properties) {
- GetDispatchParent(pdev)
- .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
- pdev, format, type, samples, usage, tiling, properties_count,
- properties);
-}
-
-VKAPI_ATTR
-VkResult EnumerateDeviceExtensionProperties_Bottom(
- 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
-// data. This is to keep the dispatch generator happy.
-VKAPI_ATTR
-VkResult EnumerateDeviceLayerProperties_Bottom(
- VkPhysicalDevice /*pdev*/,
- uint32_t* /*properties_count*/,
- VkLayerProperties* /*properties*/) {
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR
-VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
- const VkDeviceCreateInfo* create_info,
- const VkAllocationCallbacks* allocator,
- VkDevice* device_out) {
- 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++;
-
- VkDeviceCreateInfo driver_create_info = *create_info;
- driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
- driver_create_info.enabledLayerCount = 0;
- driver_create_info.ppEnabledLayerNames = nullptr;
-
- uint32_t num_driver_extensions = 0;
- const char** driver_extensions = static_cast<const char**>(
- alloca(create_info->enabledExtensionCount * sizeof(const char*)));
- for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
- const char* name = create_info->ppEnabledExtensionNames[i];
- DeviceExtension id = DeviceExtensionFromName(name);
- if (id != kDeviceExtensionCount) {
- if (instance.physical_device_driver_extensions[gpu_idx][id]) {
- driver_extensions[num_driver_extensions++] = name;
- device->enabled_extensions.set(id);
- continue;
- }
- // Add the VK_ANDROID_native_buffer extension to the list iff
- // the VK_KHR_swapchain extension was requested
- if (id == kKHR_swapchain &&
- instance.physical_device_driver_extensions
- [gpu_idx][kANDROID_native_buffer]) {
- driver_extensions[num_driver_extensions++] =
- VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
- device->enabled_extensions.set(id);
- continue;
- }
- }
- }
-
- driver_create_info.enabledExtensionCount = num_driver_extensions;
- driver_create_info.ppEnabledExtensionNames = driver_extensions;
- VkDevice drv_device;
- 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;
- }
-
- if (!driver::SetData(drv_device, device->base)) {
- DestroyDevice(device, drv_device);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
- instance.drv.dispatch.GetDeviceProcAddr(drv_device,
- "vkGetDeviceProcAddr"));
- *device_out = drv_device;
- return VK_SUCCESS;
-}
-
-void DestroyInstance_Bottom(VkInstance vkinstance,
- const VkAllocationCallbacks* allocator) {
- Instance& instance = GetDispatchParent(vkinstance);
-
- VkAllocationCallbacks local_allocator;
- if (!allocator) {
- local_allocator = *instance.alloc;
- allocator = &local_allocator;
- }
-
- DestroyInstance(&instance, allocator, vkinstance);
-}
-
-VkResult CreateSwapchainKHR_Disabled(VkDevice,
- const VkSwapchainCreateInfoKHR*,
- const VkAllocationCallbacks*,
- VkSwapchainKHR*) {
- ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-void DestroySwapchainKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- const VkAllocationCallbacks*) {
- ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
-}
-
-VkResult GetSwapchainImagesKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- uint32_t*,
- VkImage*) {
- ALOGE(
- "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult AcquireNextImageKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- uint64_t,
- VkSemaphore,
- VkFence,
- uint32_t*) {
- ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult QueuePresentKHR_Disabled(VkQueue, const VkPresentInfoKHR*) {
- ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
- const char* name) {
- if (strcmp(name, "vkCreateDevice") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom);
- }
-
- Device& device = GetDispatchParent(vkdevice);
- if (!device.enabled_extensions[kKHR_swapchain]) {
- if (strcmp(name, "vkCreateSwapchainKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- CreateSwapchainKHR_Disabled);
- }
- if (strcmp(name, "vkDestroySwapchainKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- DestroySwapchainKHR_Disabled);
- }
- if (strcmp(name, "vkGetSwapchainImagesKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetSwapchainImagesKHR_Disabled);
- }
- if (strcmp(name, "vkAcquireNextSwapchainImageKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- AcquireNextImageKHR_Disabled);
- }
- if (strcmp(name, "vkQueuePresentKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- QueuePresentKHR_Disabled);
- }
- }
-
- // VK_ANDROID_native_buffer should be hidden from applications and layers.
- // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
- PFN_vkVoidFunction pfn;
- if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
- strcmp(name, "vkAcquireImageANDROID") == 0 ||
- strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
- return nullptr;
- }
- if ((pfn = GetLoaderBottomProcAddr(name)))
- return pfn;
- return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
-}
-
-void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) {
- DestroyDevice(&GetDispatchParent(vkdevice), vkdevice);
-}
-
-void GetDeviceQueue_Bottom(VkDevice vkdevice,
- uint32_t family,
- uint32_t index,
- VkQueue* queue_out) {
- const auto& device = GetDispatchParent(vkdevice);
- const auto& instance = *device.instance;
-
- instance.drv.dispatch.GetDeviceQueue(vkdevice, family, index, queue_out);
- driver::SetData(*queue_out, device.base);
-}
-
-VkResult AllocateCommandBuffers_Bottom(
- VkDevice vkdevice,
- const VkCommandBufferAllocateInfo* alloc_info,
- VkCommandBuffer* cmdbufs) {
- const auto& device = GetDispatchParent(vkdevice);
- const auto& instance = *device.instance;
-
- 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;
-}
-
-// -----------------------------------------------------------------------------
-
-const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
- return GetDispatchParent(vkinstance).alloc;
-}
-
-const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
- return GetDispatchParent(vkdevice).instance->alloc;
-}
-
-VkInstance GetDriverInstance(VkInstance instance) {
- return instance;
-}
-
-const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
- return GetDispatchParent(instance).drv.dispatch;
-}
-
-const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
- return GetDispatchParent(device).instance->drv.dispatch;
-}
-
-const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
- return GetDispatchParent(queue).instance->drv.dispatch;
-}
-
-DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
- 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