Home | History | Annotate | Download | only in libvulkan
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <malloc.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <sys/prctl.h>
     21 
     22 #include <algorithm>
     23 #include <array>
     24 #include <dlfcn.h>
     25 #include <new>
     26 
     27 #include <log/log.h>
     28 
     29 #include <android/dlext.h>
     30 #include <cutils/properties.h>
     31 #include <graphicsenv/GraphicsEnv.h>
     32 #include <utils/Vector.h>
     33 
     34 #include "android-base/properties.h"
     35 
     36 #include "driver.h"
     37 #include "stubhal.h"
     38 
     39 // TODO(b/37049319) Get this from a header once one exists
     40 extern "C" {
     41 android_namespace_t* android_get_exported_namespace(const char*);
     42 }
     43 
     44 // #define ENABLE_ALLOC_CALLSTACKS 1
     45 #if ENABLE_ALLOC_CALLSTACKS
     46 #include <utils/CallStack.h>
     47 #define ALOGD_CALLSTACK(...)                             \
     48     do {                                                 \
     49         ALOGD(__VA_ARGS__);                              \
     50         android::CallStack callstack;                    \
     51         callstack.update();                              \
     52         callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
     53     } while (false)
     54 #else
     55 #define ALOGD_CALLSTACK(...) \
     56     do {                     \
     57     } while (false)
     58 #endif
     59 
     60 namespace vulkan {
     61 namespace driver {
     62 
     63 namespace {
     64 
     65 class Hal {
     66    public:
     67     static bool Open();
     68 
     69     static const Hal& Get() { return hal_; }
     70     static const hwvulkan_device_t& Device() { return *Get().dev_; }
     71 
     72     int GetDebugReportIndex() const { return debug_report_index_; }
     73 
     74    private:
     75     Hal() : dev_(nullptr), debug_report_index_(-1) {}
     76     Hal(const Hal&) = delete;
     77     Hal& operator=(const Hal&) = delete;
     78 
     79     bool InitDebugReportIndex();
     80 
     81     static Hal hal_;
     82 
     83     const hwvulkan_device_t* dev_;
     84     int debug_report_index_;
     85 };
     86 
     87 class CreateInfoWrapper {
     88    public:
     89     CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
     90                       const VkAllocationCallbacks& allocator);
     91     CreateInfoWrapper(VkPhysicalDevice physical_dev,
     92                       const VkDeviceCreateInfo& create_info,
     93                       const VkAllocationCallbacks& allocator);
     94     ~CreateInfoWrapper();
     95 
     96     VkResult Validate();
     97 
     98     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
     99     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
    100 
    101     explicit operator const VkInstanceCreateInfo*() const;
    102     explicit operator const VkDeviceCreateInfo*() const;
    103 
    104    private:
    105     struct ExtensionFilter {
    106         VkExtensionProperties* exts;
    107         uint32_t ext_count;
    108 
    109         const char** names;
    110         uint32_t name_count;
    111     };
    112 
    113     VkResult SanitizePNext();
    114 
    115     VkResult SanitizeLayers();
    116     VkResult SanitizeExtensions();
    117 
    118     VkResult QueryExtensionCount(uint32_t& count) const;
    119     VkResult EnumerateExtensions(uint32_t& count,
    120                                  VkExtensionProperties* props) const;
    121     VkResult InitExtensionFilter();
    122     void FilterExtension(const char* name);
    123 
    124     const bool is_instance_;
    125     const VkAllocationCallbacks& allocator_;
    126 
    127     VkPhysicalDevice physical_dev_;
    128 
    129     union {
    130         VkInstanceCreateInfo instance_info_;
    131         VkDeviceCreateInfo dev_info_;
    132     };
    133 
    134     ExtensionFilter extension_filter_;
    135 
    136     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
    137     std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
    138 };
    139 
    140 Hal Hal::hal_;
    141 
    142 void* LoadLibrary(const android_dlextinfo& dlextinfo,
    143                   const char* subname,
    144                   int subname_len) {
    145     const char kLibFormat[] = "vulkan.%*s.so";
    146     char* name = static_cast<char*>(
    147         alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
    148     sprintf(name, kLibFormat, subname_len, subname);
    149     return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
    150 }
    151 
    152 const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
    153     "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
    154     "ro.board.platform",
    155 }};
    156 
    157 int LoadDriver(android_namespace_t* library_namespace,
    158                const hwvulkan_module_t** module) {
    159     const android_dlextinfo dlextinfo = {
    160         .flags = ANDROID_DLEXT_USE_NAMESPACE,
    161         .library_namespace = library_namespace,
    162     };
    163     void* so = nullptr;
    164     char prop[PROPERTY_VALUE_MAX];
    165     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
    166         int prop_len = property_get(key, prop, nullptr);
    167         if (prop_len > 0) {
    168             so = LoadLibrary(dlextinfo, prop, prop_len);
    169             if (so)
    170                 break;
    171         }
    172     }
    173     if (!so)
    174         return -ENOENT;
    175 
    176     auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
    177     if (!hmi) {
    178         ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
    179         dlclose(so);
    180         return -EINVAL;
    181     }
    182     if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
    183         ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
    184         dlclose(so);
    185         return -EINVAL;
    186     }
    187     hmi->dso = so;
    188     *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
    189     return 0;
    190 }
    191 
    192 int LoadBuiltinDriver(const hwvulkan_module_t** module) {
    193     auto ns = android_get_exported_namespace("sphal");
    194     if (!ns)
    195         return -ENOENT;
    196     return LoadDriver(ns, module);
    197 }
    198 
    199 int LoadUpdatedDriver(const hwvulkan_module_t** module) {
    200     auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
    201     if (!ns)
    202         return -ENOENT;
    203     return LoadDriver(ns, module);
    204 }
    205 
    206 bool Hal::Open() {
    207     ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
    208 
    209     // Use a stub device unless we successfully open a real HAL device.
    210     hal_.dev_ = &stubhal::kDevice;
    211 
    212     int result;
    213     const hwvulkan_module_t* module = nullptr;
    214 
    215     result = LoadUpdatedDriver(&module);
    216     if (result == -ENOENT) {
    217         result = LoadBuiltinDriver(&module);
    218         if (result != 0) {
    219             // -ENOENT means the sphal namespace doesn't exist, not that there
    220             // is a problem with the driver.
    221             ALOGW_IF(
    222                 result != -ENOENT,
    223                 "Failed to load Vulkan driver into sphal namespace. This "
    224                 "usually means the driver has forbidden library dependencies."
    225                 "Please fix, this will soon stop working.");
    226             result =
    227                 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
    228                               reinterpret_cast<const hw_module_t**>(&module));
    229         }
    230     }
    231     if (result != 0) {
    232         ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
    233         return true;
    234     }
    235 
    236     hwvulkan_device_t* device;
    237     result =
    238         module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
    239                                      reinterpret_cast<hw_device_t**>(&device));
    240     if (result != 0) {
    241         // Any device with a Vulkan HAL should be able to open the device.
    242         ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
    243               result);
    244         return false;
    245     }
    246 
    247     hal_.dev_ = device;
    248 
    249     hal_.InitDebugReportIndex();
    250 
    251     return true;
    252 }
    253 
    254 bool Hal::InitDebugReportIndex() {
    255     uint32_t count;
    256     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
    257         VK_SUCCESS) {
    258         ALOGE("failed to get HAL instance extension count");
    259         return false;
    260     }
    261 
    262     VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
    263         malloc(sizeof(VkExtensionProperties) * count));
    264     if (!exts) {
    265         ALOGE("failed to allocate HAL instance extension array");
    266         return false;
    267     }
    268 
    269     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
    270         VK_SUCCESS) {
    271         ALOGE("failed to enumerate HAL instance extensions");
    272         free(exts);
    273         return false;
    274     }
    275 
    276     for (uint32_t i = 0; i < count; i++) {
    277         if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
    278             0) {
    279             debug_report_index_ = static_cast<int>(i);
    280             break;
    281         }
    282     }
    283 
    284     free(exts);
    285 
    286     return true;
    287 }
    288 
    289 CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
    290                                      const VkAllocationCallbacks& allocator)
    291     : is_instance_(true),
    292       allocator_(allocator),
    293       physical_dev_(VK_NULL_HANDLE),
    294       instance_info_(create_info),
    295       extension_filter_() {
    296     hook_extensions_.set(ProcHook::EXTENSION_CORE);
    297     hal_extensions_.set(ProcHook::EXTENSION_CORE);
    298 }
    299 
    300 CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
    301                                      const VkDeviceCreateInfo& create_info,
    302                                      const VkAllocationCallbacks& allocator)
    303     : is_instance_(false),
    304       allocator_(allocator),
    305       physical_dev_(physical_dev),
    306       dev_info_(create_info),
    307       extension_filter_() {
    308     hook_extensions_.set(ProcHook::EXTENSION_CORE);
    309     hal_extensions_.set(ProcHook::EXTENSION_CORE);
    310 }
    311 
    312 CreateInfoWrapper::~CreateInfoWrapper() {
    313     allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
    314     allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
    315 }
    316 
    317 VkResult CreateInfoWrapper::Validate() {
    318     VkResult result = SanitizePNext();
    319     if (result == VK_SUCCESS)
    320         result = SanitizeLayers();
    321     if (result == VK_SUCCESS)
    322         result = SanitizeExtensions();
    323 
    324     return result;
    325 }
    326 
    327 const std::bitset<ProcHook::EXTENSION_COUNT>&
    328 CreateInfoWrapper::GetHookExtensions() const {
    329     return hook_extensions_;
    330 }
    331 
    332 const std::bitset<ProcHook::EXTENSION_COUNT>&
    333 CreateInfoWrapper::GetHalExtensions() const {
    334     return hal_extensions_;
    335 }
    336 
    337 CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
    338     return &instance_info_;
    339 }
    340 
    341 CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
    342     return &dev_info_;
    343 }
    344 
    345 VkResult CreateInfoWrapper::SanitizePNext() {
    346     const struct StructHeader {
    347         VkStructureType type;
    348         const void* next;
    349     } * header;
    350 
    351     if (is_instance_) {
    352         header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
    353 
    354         // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
    355         while (header &&
    356                header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
    357             header = reinterpret_cast<const StructHeader*>(header->next);
    358 
    359         instance_info_.pNext = header;
    360     } else {
    361         header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
    362 
    363         // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
    364         while (header &&
    365                header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
    366             header = reinterpret_cast<const StructHeader*>(header->next);
    367 
    368         dev_info_.pNext = header;
    369     }
    370 
    371     return VK_SUCCESS;
    372 }
    373 
    374 VkResult CreateInfoWrapper::SanitizeLayers() {
    375     auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
    376                                        : dev_info_.ppEnabledLayerNames;
    377     auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
    378                                        : dev_info_.enabledLayerCount;
    379 
    380     // remove all layers
    381     layer_names = nullptr;
    382     layer_count = 0;
    383 
    384     return VK_SUCCESS;
    385 }
    386 
    387 VkResult CreateInfoWrapper::SanitizeExtensions() {
    388     auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
    389                                      : dev_info_.ppEnabledExtensionNames;
    390     auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
    391                                      : dev_info_.enabledExtensionCount;
    392     if (!ext_count)
    393         return VK_SUCCESS;
    394 
    395     VkResult result = InitExtensionFilter();
    396     if (result != VK_SUCCESS)
    397         return result;
    398 
    399     for (uint32_t i = 0; i < ext_count; i++)
    400         FilterExtension(ext_names[i]);
    401 
    402     ext_names = extension_filter_.names;
    403     ext_count = extension_filter_.name_count;
    404 
    405     return VK_SUCCESS;
    406 }
    407 
    408 VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
    409     if (is_instance_) {
    410         return Hal::Device().EnumerateInstanceExtensionProperties(
    411             nullptr, &count, nullptr);
    412     } else {
    413         const auto& driver = GetData(physical_dev_).driver;
    414         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
    415                                                          &count, nullptr);
    416     }
    417 }
    418 
    419 VkResult CreateInfoWrapper::EnumerateExtensions(
    420     uint32_t& count,
    421     VkExtensionProperties* props) const {
    422     if (is_instance_) {
    423         return Hal::Device().EnumerateInstanceExtensionProperties(
    424             nullptr, &count, props);
    425     } else {
    426         const auto& driver = GetData(physical_dev_).driver;
    427         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
    428                                                          &count, props);
    429     }
    430 }
    431 
    432 VkResult CreateInfoWrapper::InitExtensionFilter() {
    433     // query extension count
    434     uint32_t count;
    435     VkResult result = QueryExtensionCount(count);
    436     if (result != VK_SUCCESS || count == 0)
    437         return result;
    438 
    439     auto& filter = extension_filter_;
    440     filter.exts =
    441         reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
    442             allocator_.pUserData, sizeof(VkExtensionProperties) * count,
    443             alignof(VkExtensionProperties),
    444             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
    445     if (!filter.exts)
    446         return VK_ERROR_OUT_OF_HOST_MEMORY;
    447 
    448     // enumerate extensions
    449     result = EnumerateExtensions(count, filter.exts);
    450     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
    451         return result;
    452 
    453     if (!count)
    454         return VK_SUCCESS;
    455 
    456     filter.ext_count = count;
    457 
    458     // allocate name array
    459     uint32_t enabled_ext_count = (is_instance_)
    460                                      ? instance_info_.enabledExtensionCount
    461                                      : dev_info_.enabledExtensionCount;
    462     count = std::min(filter.ext_count, enabled_ext_count);
    463     filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
    464         allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
    465         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
    466     if (!filter.names)
    467         return VK_ERROR_OUT_OF_HOST_MEMORY;
    468 
    469     return VK_SUCCESS;
    470 }
    471 
    472 void CreateInfoWrapper::FilterExtension(const char* name) {
    473     auto& filter = extension_filter_;
    474 
    475     ProcHook::Extension ext_bit = GetProcHookExtension(name);
    476     if (is_instance_) {
    477         switch (ext_bit) {
    478             case ProcHook::KHR_android_surface:
    479             case ProcHook::KHR_surface:
    480             case ProcHook::EXT_swapchain_colorspace:
    481             case ProcHook::KHR_get_surface_capabilities2:
    482                 hook_extensions_.set(ext_bit);
    483                 // return now as these extensions do not require HAL support
    484                 return;
    485             case ProcHook::EXT_debug_report:
    486                 // both we and HAL can take part in
    487                 hook_extensions_.set(ext_bit);
    488                 break;
    489             case ProcHook::EXTENSION_UNKNOWN:
    490             case ProcHook::KHR_get_physical_device_properties2:
    491                 // HAL's extensions
    492                 break;
    493             default:
    494                 ALOGW("Ignored invalid instance extension %s", name);
    495                 return;
    496         }
    497     } else {
    498         switch (ext_bit) {
    499             case ProcHook::KHR_swapchain:
    500                 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
    501                 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
    502                 ext_bit = ProcHook::ANDROID_native_buffer;
    503                 break;
    504             case ProcHook::KHR_incremental_present:
    505             case ProcHook::GOOGLE_display_timing:
    506             case ProcHook::KHR_shared_presentable_image:
    507                 hook_extensions_.set(ext_bit);
    508                 // return now as these extensions do not require HAL support
    509                 return;
    510             case ProcHook::EXT_hdr_metadata:
    511                 hook_extensions_.set(ext_bit);
    512                 break;
    513             case ProcHook::EXTENSION_UNKNOWN:
    514                 // HAL's extensions
    515                 break;
    516             default:
    517                 ALOGW("Ignored invalid device extension %s", name);
    518                 return;
    519         }
    520     }
    521 
    522     for (uint32_t i = 0; i < filter.ext_count; i++) {
    523         const VkExtensionProperties& props = filter.exts[i];
    524         // ignore unknown extensions
    525         if (strcmp(name, props.extensionName) != 0)
    526             continue;
    527 
    528         filter.names[filter.name_count++] = name;
    529         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
    530             if (ext_bit == ProcHook::ANDROID_native_buffer)
    531                 hook_extensions_.set(ProcHook::KHR_swapchain);
    532 
    533             hal_extensions_.set(ext_bit);
    534         }
    535 
    536         break;
    537     }
    538 }
    539 
    540 VKAPI_ATTR void* DefaultAllocate(void*,
    541                                  size_t size,
    542                                  size_t alignment,
    543                                  VkSystemAllocationScope) {
    544     void* ptr = nullptr;
    545     // Vulkan requires 'alignment' to be a power of two, but posix_memalign
    546     // additionally requires that it be at least sizeof(void*).
    547     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
    548     ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
    549                     ret, ptr);
    550     return ret == 0 ? ptr : nullptr;
    551 }
    552 
    553 VKAPI_ATTR void* DefaultReallocate(void*,
    554                                    void* ptr,
    555                                    size_t size,
    556                                    size_t alignment,
    557                                    VkSystemAllocationScope) {
    558     if (size == 0) {
    559         free(ptr);
    560         return nullptr;
    561     }
    562 
    563     // TODO(jessehall): Right now we never shrink allocations; if the new
    564     // request is smaller than the existing chunk, we just continue using it.
    565     // Right now the loader never reallocs, so this doesn't matter. If that
    566     // changes, or if this code is copied into some other project, this should
    567     // probably have a heuristic to allocate-copy-free when doing so will save
    568     // "enough" space.
    569     size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
    570     if (size <= old_size)
    571         return ptr;
    572 
    573     void* new_ptr = nullptr;
    574     if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
    575         return nullptr;
    576     if (ptr) {
    577         memcpy(new_ptr, ptr, std::min(old_size, size));
    578         free(ptr);
    579     }
    580     return new_ptr;
    581 }
    582 
    583 VKAPI_ATTR void DefaultFree(void*, void* ptr) {
    584     ALOGD_CALLSTACK("Free: %p", ptr);
    585     free(ptr);
    586 }
    587 
    588 InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
    589     void* data_mem = allocator.pfnAllocation(
    590         allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
    591         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    592     if (!data_mem)
    593         return nullptr;
    594 
    595     return new (data_mem) InstanceData(allocator);
    596 }
    597 
    598 void FreeInstanceData(InstanceData* data,
    599                       const VkAllocationCallbacks& allocator) {
    600     data->~InstanceData();
    601     allocator.pfnFree(allocator.pUserData, data);
    602 }
    603 
    604 DeviceData* AllocateDeviceData(
    605     const VkAllocationCallbacks& allocator,
    606     const DebugReportCallbackList& debug_report_callbacks) {
    607     void* data_mem = allocator.pfnAllocation(
    608         allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
    609         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
    610     if (!data_mem)
    611         return nullptr;
    612 
    613     return new (data_mem) DeviceData(allocator, debug_report_callbacks);
    614 }
    615 
    616 void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
    617     data->~DeviceData();
    618     allocator.pfnFree(allocator.pUserData, data);
    619 }
    620 
    621 }  // anonymous namespace
    622 
    623 bool Debuggable() {
    624     return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
    625 }
    626 
    627 bool OpenHAL() {
    628     return Hal::Open();
    629 }
    630 
    631 const VkAllocationCallbacks& GetDefaultAllocator() {
    632     static const VkAllocationCallbacks kDefaultAllocCallbacks = {
    633         .pUserData = nullptr,
    634         .pfnAllocation = DefaultAllocate,
    635         .pfnReallocation = DefaultReallocate,
    636         .pfnFree = DefaultFree,
    637     };
    638 
    639     return kDefaultAllocCallbacks;
    640 }
    641 
    642 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
    643     const ProcHook* hook = GetProcHook(pName);
    644     if (!hook)
    645         return Hal::Device().GetInstanceProcAddr(instance, pName);
    646 
    647     if (!instance) {
    648         if (hook->type == ProcHook::GLOBAL)
    649             return hook->proc;
    650 
    651         // v0 layers expect
    652         //
    653         //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
    654         //
    655         // to work.
    656         if (strcmp(pName, "vkCreateDevice") == 0)
    657             return hook->proc;
    658 
    659         ALOGE(
    660             "internal vkGetInstanceProcAddr called for %s without an instance",
    661             pName);
    662 
    663         return nullptr;
    664     }
    665 
    666     PFN_vkVoidFunction proc;
    667 
    668     switch (hook->type) {
    669         case ProcHook::INSTANCE:
    670             proc = (GetData(instance).hook_extensions[hook->extension])
    671                        ? hook->proc
    672                        : nullptr;
    673             break;
    674         case ProcHook::DEVICE:
    675             proc = (hook->extension == ProcHook::EXTENSION_CORE)
    676                        ? hook->proc
    677                        : hook->checked_proc;
    678             break;
    679         default:
    680             ALOGE(
    681                 "internal vkGetInstanceProcAddr called for %s with an instance",
    682                 pName);
    683             proc = nullptr;
    684             break;
    685     }
    686 
    687     return proc;
    688 }
    689 
    690 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
    691     const ProcHook* hook = GetProcHook(pName);
    692     if (!hook)
    693         return GetData(device).driver.GetDeviceProcAddr(device, pName);
    694 
    695     if (hook->type != ProcHook::DEVICE) {
    696         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
    697         return nullptr;
    698     }
    699 
    700     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
    701                                                               : nullptr;
    702 }
    703 
    704 VkResult EnumerateInstanceExtensionProperties(
    705     const char* pLayerName,
    706     uint32_t* pPropertyCount,
    707     VkExtensionProperties* pProperties) {
    708 
    709     android::Vector<VkExtensionProperties> loader_extensions;
    710     loader_extensions.push_back({
    711         VK_KHR_SURFACE_EXTENSION_NAME,
    712         VK_KHR_SURFACE_SPEC_VERSION});
    713     loader_extensions.push_back({
    714         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
    715         VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
    716     loader_extensions.push_back({
    717         VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
    718         VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
    719     loader_extensions.push_back({
    720         VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
    721         VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
    722 
    723     static const VkExtensionProperties loader_debug_report_extension = {
    724         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
    725     };
    726 
    727     // enumerate our extensions first
    728     if (!pLayerName && pProperties) {
    729         uint32_t count = std::min(
    730             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
    731 
    732         std::copy_n(loader_extensions.begin(), count, pProperties);
    733 
    734         if (count < loader_extensions.size()) {
    735             *pPropertyCount = count;
    736             return VK_INCOMPLETE;
    737         }
    738 
    739         pProperties += count;
    740         *pPropertyCount -= count;
    741 
    742         if (Hal::Get().GetDebugReportIndex() < 0) {
    743             if (!*pPropertyCount) {
    744                 *pPropertyCount = count;
    745                 return VK_INCOMPLETE;
    746             }
    747 
    748             pProperties[0] = loader_debug_report_extension;
    749             pProperties += 1;
    750             *pPropertyCount -= 1;
    751         }
    752     }
    753 
    754     VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
    755         pLayerName, pPropertyCount, pProperties);
    756 
    757     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
    758         int idx = Hal::Get().GetDebugReportIndex();
    759         if (idx < 0) {
    760             *pPropertyCount += 1;
    761         } else if (pProperties &&
    762                    static_cast<uint32_t>(idx) < *pPropertyCount) {
    763             pProperties[idx].specVersion =
    764                 std::min(pProperties[idx].specVersion,
    765                          loader_debug_report_extension.specVersion);
    766         }
    767 
    768         *pPropertyCount += loader_extensions.size();
    769     }
    770 
    771     return result;
    772 }
    773 
    774 bool QueryPresentationProperties(
    775     VkPhysicalDevice physicalDevice,
    776     VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
    777 {
    778     const InstanceData& data = GetData(physicalDevice);
    779 
    780     // GPDP2 must be present and enabled on the instance.
    781     if (!data.driver.GetPhysicalDeviceProperties2KHR)
    782         return false;
    783 
    784     // Request the android-specific presentation properties via GPDP2
    785     VkPhysicalDeviceProperties2KHR properties = {
    786         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
    787         presentation_properties,
    788         {}
    789     };
    790 
    791 #pragma clang diagnostic push
    792 #pragma clang diagnostic ignored "-Wold-style-cast"
    793     presentation_properties->sType =
    794         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
    795 #pragma clang diagnostic pop
    796     presentation_properties->pNext = nullptr;
    797     presentation_properties->sharedImage = VK_FALSE;
    798 
    799     data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
    800                                                 &properties);
    801 
    802     return true;
    803 }
    804 
    805 VkResult EnumerateDeviceExtensionProperties(
    806     VkPhysicalDevice physicalDevice,
    807     const char* pLayerName,
    808     uint32_t* pPropertyCount,
    809     VkExtensionProperties* pProperties) {
    810     const InstanceData& data = GetData(physicalDevice);
    811     // extensions that are unconditionally exposed by the loader
    812     android::Vector<VkExtensionProperties> loader_extensions;
    813     loader_extensions.push_back({
    814         VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
    815         VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
    816 
    817     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
    818     if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
    819         presentation_properties.sharedImage) {
    820         loader_extensions.push_back({
    821             VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
    822             VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
    823     }
    824 
    825     // conditionally add VK_GOOGLE_display_timing if present timestamps are
    826     // supported by the driver:
    827     const std::string timestamp_property("service.sf.present_timestamp");
    828     android::base::WaitForPropertyCreation(timestamp_property);
    829     if (android::base::GetBoolProperty(timestamp_property, true)) {
    830         loader_extensions.push_back({
    831                 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
    832                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
    833     }
    834 
    835     // enumerate our extensions first
    836     if (!pLayerName && pProperties) {
    837         uint32_t count = std::min(
    838             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
    839 
    840         std::copy_n(loader_extensions.begin(), count, pProperties);
    841 
    842         if (count < loader_extensions.size()) {
    843             *pPropertyCount = count;
    844             return VK_INCOMPLETE;
    845         }
    846 
    847         pProperties += count;
    848         *pPropertyCount -= count;
    849     }
    850 
    851     VkResult result = data.driver.EnumerateDeviceExtensionProperties(
    852         physicalDevice, pLayerName, pPropertyCount, pProperties);
    853 
    854     if (pProperties) {
    855         // map VK_ANDROID_native_buffer to VK_KHR_swapchain
    856         for (uint32_t i = 0; i < *pPropertyCount; i++) {
    857             auto& prop = pProperties[i];
    858 
    859             if (strcmp(prop.extensionName,
    860                        VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
    861                 continue;
    862 
    863             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    864                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
    865             prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
    866         }
    867     }
    868 
    869     // restore loader extension count
    870     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
    871         *pPropertyCount += loader_extensions.size();
    872     }
    873 
    874     return result;
    875 }
    876 
    877 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
    878                         const VkAllocationCallbacks* pAllocator,
    879                         VkInstance* pInstance) {
    880     const VkAllocationCallbacks& data_allocator =
    881         (pAllocator) ? *pAllocator : GetDefaultAllocator();
    882 
    883     if (pCreateInfo->pApplicationInfo &&
    884         pCreateInfo->pApplicationInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
    885 #pragma clang diagnostic push
    886 #pragma clang diagnostic ignored "-Wold-style-cast"
    887         ALOGI(
    888             "Requested Vulkan instance version %d.%d is greater than max "
    889             "supported version (1.0)",
    890             VK_VERSION_MAJOR(pCreateInfo->pApplicationInfo->apiVersion),
    891             VK_VERSION_MINOR(pCreateInfo->pApplicationInfo->apiVersion));
    892 #pragma clang diagnostic pop
    893         return VK_ERROR_INCOMPATIBLE_DRIVER;
    894     }
    895 
    896     CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
    897     VkResult result = wrapper.Validate();
    898     if (result != VK_SUCCESS)
    899         return result;
    900 
    901     InstanceData* data = AllocateInstanceData(data_allocator);
    902     if (!data)
    903         return VK_ERROR_OUT_OF_HOST_MEMORY;
    904 
    905     data->hook_extensions |= wrapper.GetHookExtensions();
    906 
    907     // call into the driver
    908     VkInstance instance;
    909     result = Hal::Device().CreateInstance(
    910         static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
    911         &instance);
    912     if (result != VK_SUCCESS) {
    913         FreeInstanceData(data, data_allocator);
    914         return result;
    915     }
    916 
    917     // initialize InstanceDriverTable
    918     if (!SetData(instance, *data) ||
    919         !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
    920                          wrapper.GetHalExtensions())) {
    921         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
    922             Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
    923         if (data->driver.DestroyInstance)
    924             data->driver.DestroyInstance(instance, pAllocator);
    925 
    926         FreeInstanceData(data, data_allocator);
    927 
    928         return VK_ERROR_INCOMPATIBLE_DRIVER;
    929     }
    930 
    931     data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
    932         Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
    933     if (!data->get_device_proc_addr) {
    934         data->driver.DestroyInstance(instance, pAllocator);
    935         FreeInstanceData(data, data_allocator);
    936 
    937         return VK_ERROR_INCOMPATIBLE_DRIVER;
    938     }
    939 
    940     *pInstance = instance;
    941 
    942     return VK_SUCCESS;
    943 }
    944 
    945 void DestroyInstance(VkInstance instance,
    946                      const VkAllocationCallbacks* pAllocator) {
    947     InstanceData& data = GetData(instance);
    948     data.driver.DestroyInstance(instance, pAllocator);
    949 
    950     VkAllocationCallbacks local_allocator;
    951     if (!pAllocator) {
    952         local_allocator = data.allocator;
    953         pAllocator = &local_allocator;
    954     }
    955 
    956     FreeInstanceData(&data, *pAllocator);
    957 }
    958 
    959 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
    960                       const VkDeviceCreateInfo* pCreateInfo,
    961                       const VkAllocationCallbacks* pAllocator,
    962                       VkDevice* pDevice) {
    963     const InstanceData& instance_data = GetData(physicalDevice);
    964     const VkAllocationCallbacks& data_allocator =
    965         (pAllocator) ? *pAllocator : instance_data.allocator;
    966 
    967     CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
    968     VkResult result = wrapper.Validate();
    969     if (result != VK_SUCCESS)
    970         return result;
    971 
    972     DeviceData* data = AllocateDeviceData(data_allocator,
    973                                           instance_data.debug_report_callbacks);
    974     if (!data)
    975         return VK_ERROR_OUT_OF_HOST_MEMORY;
    976 
    977     data->hook_extensions |= wrapper.GetHookExtensions();
    978 
    979     // call into the driver
    980     VkDevice dev;
    981     result = instance_data.driver.CreateDevice(
    982         physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
    983         pAllocator, &dev);
    984     if (result != VK_SUCCESS) {
    985         FreeDeviceData(data, data_allocator);
    986         return result;
    987     }
    988 
    989     // initialize DeviceDriverTable
    990     if (!SetData(dev, *data) ||
    991         !InitDriverTable(dev, instance_data.get_device_proc_addr,
    992                          wrapper.GetHalExtensions())) {
    993         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
    994             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
    995         if (data->driver.DestroyDevice)
    996             data->driver.DestroyDevice(dev, pAllocator);
    997 
    998         FreeDeviceData(data, data_allocator);
    999 
   1000         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1001     }
   1002 
   1003     // sanity check ANDROID_native_buffer implementation, whose set of
   1004     // entrypoints varies according to the spec version.
   1005     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
   1006         !data->driver.GetSwapchainGrallocUsageANDROID &&
   1007         !data->driver.GetSwapchainGrallocUsage2ANDROID) {
   1008         ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
   1009               " must expose at least one of "
   1010               "vkGetSwapchainGrallocUsageANDROID or "
   1011               "vkGetSwapchainGrallocUsage2ANDROID");
   1012 
   1013         data->driver.DestroyDevice(dev, pAllocator);
   1014         FreeDeviceData(data, data_allocator);
   1015 
   1016         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1017     }
   1018 
   1019     VkPhysicalDeviceProperties properties;
   1020     instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
   1021                                                      &properties);
   1022 
   1023     data->driver_device = dev;
   1024     data->driver_version = properties.driverVersion;
   1025 
   1026     *pDevice = dev;
   1027 
   1028     return VK_SUCCESS;
   1029 }
   1030 
   1031 void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
   1032     DeviceData& data = GetData(device);
   1033     data.driver.DestroyDevice(device, pAllocator);
   1034 
   1035     VkAllocationCallbacks local_allocator;
   1036     if (!pAllocator) {
   1037         local_allocator = data.allocator;
   1038         pAllocator = &local_allocator;
   1039     }
   1040 
   1041     FreeDeviceData(&data, *pAllocator);
   1042 }
   1043 
   1044 VkResult EnumeratePhysicalDevices(VkInstance instance,
   1045                                   uint32_t* pPhysicalDeviceCount,
   1046                                   VkPhysicalDevice* pPhysicalDevices) {
   1047     const auto& data = GetData(instance);
   1048 
   1049     VkResult result = data.driver.EnumeratePhysicalDevices(
   1050         instance, pPhysicalDeviceCount, pPhysicalDevices);
   1051     if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
   1052         for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
   1053             SetData(pPhysicalDevices[i], data);
   1054     }
   1055 
   1056     return result;
   1057 }
   1058 
   1059 void GetDeviceQueue(VkDevice device,
   1060                     uint32_t queueFamilyIndex,
   1061                     uint32_t queueIndex,
   1062                     VkQueue* pQueue) {
   1063     const auto& data = GetData(device);
   1064 
   1065     data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
   1066     SetData(*pQueue, data);
   1067 }
   1068 
   1069 VKAPI_ATTR VkResult
   1070 AllocateCommandBuffers(VkDevice device,
   1071                        const VkCommandBufferAllocateInfo* pAllocateInfo,
   1072                        VkCommandBuffer* pCommandBuffers) {
   1073     const auto& data = GetData(device);
   1074 
   1075     VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
   1076                                                          pCommandBuffers);
   1077     if (result == VK_SUCCESS) {
   1078         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
   1079             SetData(pCommandBuffers[i], data);
   1080     }
   1081 
   1082     return result;
   1083 }
   1084 
   1085 }  // namespace driver
   1086 }  // namespace vulkan
   1087