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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     18 
     19 #include <malloc.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include <sys/prctl.h>
     23 
     24 #include <dlfcn.h>
     25 #include <algorithm>
     26 #include <array>
     27 #include <new>
     28 
     29 #include <log/log.h>
     30 
     31 #include <android/dlext.h>
     32 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
     33 #include <configstore/Utils.h>
     34 #include <cutils/properties.h>
     35 #include <graphicsenv/GraphicsEnv.h>
     36 #include <utils/Timers.h>
     37 #include <utils/Trace.h>
     38 #include <utils/Vector.h>
     39 
     40 #include "android-base/properties.h"
     41 
     42 #include "driver.h"
     43 #include "stubhal.h"
     44 
     45 using namespace android::hardware::configstore;
     46 using namespace android::hardware::configstore::V1_0;
     47 
     48 // TODO(b/37049319) Get this from a header once one exists
     49 extern "C" {
     50 android_namespace_t* android_get_exported_namespace(const char*);
     51 }
     52 
     53 // #define ENABLE_ALLOC_CALLSTACKS 1
     54 #if ENABLE_ALLOC_CALLSTACKS
     55 #include <utils/CallStack.h>
     56 #define ALOGD_CALLSTACK(...)                             \
     57     do {                                                 \
     58         ALOGD(__VA_ARGS__);                              \
     59         android::CallStack callstack;                    \
     60         callstack.update();                              \
     61         callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
     62     } while (false)
     63 #else
     64 #define ALOGD_CALLSTACK(...) \
     65     do {                     \
     66     } while (false)
     67 #endif
     68 
     69 namespace vulkan {
     70 namespace driver {
     71 
     72 namespace {
     73 
     74 class Hal {
     75    public:
     76     static bool Open();
     77 
     78     static const Hal& Get() { return hal_; }
     79     static const hwvulkan_device_t& Device() { return *Get().dev_; }
     80 
     81     int GetDebugReportIndex() const { return debug_report_index_; }
     82 
     83    private:
     84     Hal() : dev_(nullptr), debug_report_index_(-1) {}
     85     Hal(const Hal&) = delete;
     86     Hal& operator=(const Hal&) = delete;
     87 
     88     bool InitDebugReportIndex();
     89 
     90     static Hal hal_;
     91 
     92     const hwvulkan_device_t* dev_;
     93     int debug_report_index_;
     94 };
     95 
     96 class CreateInfoWrapper {
     97    public:
     98     CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
     99                       const VkAllocationCallbacks& allocator);
    100     CreateInfoWrapper(VkPhysicalDevice physical_dev,
    101                       const VkDeviceCreateInfo& create_info,
    102                       const VkAllocationCallbacks& allocator);
    103     ~CreateInfoWrapper();
    104 
    105     VkResult Validate();
    106     void DowngradeApiVersion();
    107 
    108     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
    109     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
    110 
    111     explicit operator const VkInstanceCreateInfo*() const;
    112     explicit operator const VkDeviceCreateInfo*() const;
    113 
    114    private:
    115     struct ExtensionFilter {
    116         VkExtensionProperties* exts;
    117         uint32_t ext_count;
    118 
    119         const char** names;
    120         uint32_t name_count;
    121     };
    122 
    123     VkResult SanitizePNext();
    124 
    125     VkResult SanitizeLayers();
    126     VkResult SanitizeExtensions();
    127 
    128     VkResult QueryExtensionCount(uint32_t& count) const;
    129     VkResult EnumerateExtensions(uint32_t& count,
    130                                  VkExtensionProperties* props) const;
    131     VkResult InitExtensionFilter();
    132     void FilterExtension(const char* name);
    133 
    134     const bool is_instance_;
    135     const VkAllocationCallbacks& allocator_;
    136 
    137     VkPhysicalDevice physical_dev_;
    138 
    139     union {
    140         VkInstanceCreateInfo instance_info_;
    141         VkDeviceCreateInfo dev_info_;
    142     };
    143 
    144     VkApplicationInfo application_info_;
    145 
    146     ExtensionFilter extension_filter_;
    147 
    148     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
    149     std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
    150 };
    151 
    152 Hal Hal::hal_;
    153 
    154 void* LoadLibrary(const android_dlextinfo& dlextinfo,
    155                   const char* subname,
    156                   int subname_len) {
    157     ATRACE_CALL();
    158 
    159     const char kLibFormat[] = "vulkan.%*s.so";
    160     char* name = static_cast<char*>(
    161         alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
    162     sprintf(name, kLibFormat, subname_len, subname);
    163     return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
    164 }
    165 
    166 const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
    167     "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
    168     "ro.board.platform",
    169 }};
    170 
    171 int LoadDriver(android_namespace_t* library_namespace,
    172                const hwvulkan_module_t** module) {
    173     ATRACE_CALL();
    174 
    175     const android_dlextinfo dlextinfo = {
    176         .flags = ANDROID_DLEXT_USE_NAMESPACE,
    177         .library_namespace = library_namespace,
    178     };
    179     void* so = nullptr;
    180     char prop[PROPERTY_VALUE_MAX];
    181     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
    182         int prop_len = property_get(key, prop, nullptr);
    183         if (prop_len > 0) {
    184             so = LoadLibrary(dlextinfo, prop, prop_len);
    185             if (so)
    186                 break;
    187         }
    188     }
    189     if (!so)
    190         return -ENOENT;
    191 
    192     auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
    193     if (!hmi) {
    194         ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
    195         dlclose(so);
    196         return -EINVAL;
    197     }
    198     if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
    199         ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
    200         dlclose(so);
    201         return -EINVAL;
    202     }
    203     hmi->dso = so;
    204     *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
    205     return 0;
    206 }
    207 
    208 int LoadBuiltinDriver(const hwvulkan_module_t** module) {
    209     ATRACE_CALL();
    210 
    211     auto ns = android_get_exported_namespace("sphal");
    212     if (!ns)
    213         return -ENOENT;
    214     android::GraphicsEnv::getInstance().setDriverToLoad(
    215         android::GraphicsEnv::Driver::VULKAN);
    216     return LoadDriver(ns, module);
    217 }
    218 
    219 int LoadUpdatedDriver(const hwvulkan_module_t** module) {
    220     ATRACE_CALL();
    221 
    222     auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
    223     if (!ns)
    224         return -ENOENT;
    225     android::GraphicsEnv::getInstance().setDriverToLoad(
    226         android::GraphicsEnv::Driver::VULKAN_UPDATED);
    227     return LoadDriver(ns, module);
    228 }
    229 
    230 bool Hal::Open() {
    231     ATRACE_CALL();
    232 
    233     const nsecs_t openTime = systemTime();
    234 
    235     ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
    236 
    237     // Use a stub device unless we successfully open a real HAL device.
    238     hal_.dev_ = &stubhal::kDevice;
    239 
    240     int result;
    241     const hwvulkan_module_t* module = nullptr;
    242 
    243     result = LoadUpdatedDriver(&module);
    244     if (result == -ENOENT) {
    245         result = LoadBuiltinDriver(&module);
    246         if (result != 0) {
    247             // -ENOENT means the sphal namespace doesn't exist, not that there
    248             // is a problem with the driver.
    249             ALOGW_IF(
    250                 result != -ENOENT,
    251                 "Failed to load Vulkan driver into sphal namespace. This "
    252                 "usually means the driver has forbidden library dependencies."
    253                 "Please fix, this will soon stop working.");
    254             result =
    255                 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
    256                               reinterpret_cast<const hw_module_t**>(&module));
    257         }
    258     }
    259     if (result != 0) {
    260         android::GraphicsEnv::getInstance().setDriverLoaded(
    261             android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
    262         ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
    263         return true;
    264     }
    265 
    266 
    267     hwvulkan_device_t* device;
    268     ATRACE_BEGIN("hwvulkan module open");
    269     result =
    270         module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
    271                                      reinterpret_cast<hw_device_t**>(&device));
    272     ATRACE_END();
    273     if (result != 0) {
    274         android::GraphicsEnv::getInstance().setDriverLoaded(
    275             android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
    276         // Any device with a Vulkan HAL should be able to open the device.
    277         ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
    278               result);
    279         return false;
    280     }
    281 
    282     hal_.dev_ = device;
    283 
    284     hal_.InitDebugReportIndex();
    285 
    286     android::GraphicsEnv::getInstance().setDriverLoaded(
    287         android::GraphicsEnv::Api::API_VK, true, systemTime() - openTime);
    288 
    289     return true;
    290 }
    291 
    292 bool Hal::InitDebugReportIndex() {
    293     ATRACE_CALL();
    294 
    295     uint32_t count;
    296     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
    297         VK_SUCCESS) {
    298         ALOGE("failed to get HAL instance extension count");
    299         return false;
    300     }
    301 
    302     VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
    303         malloc(sizeof(VkExtensionProperties) * count));
    304     if (!exts) {
    305         ALOGE("failed to allocate HAL instance extension array");
    306         return false;
    307     }
    308 
    309     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
    310         VK_SUCCESS) {
    311         ALOGE("failed to enumerate HAL instance extensions");
    312         free(exts);
    313         return false;
    314     }
    315 
    316     for (uint32_t i = 0; i < count; i++) {
    317         if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
    318             0) {
    319             debug_report_index_ = static_cast<int>(i);
    320             break;
    321         }
    322     }
    323 
    324     free(exts);
    325 
    326     return true;
    327 }
    328 
    329 CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
    330                                      const VkAllocationCallbacks& allocator)
    331     : is_instance_(true),
    332       allocator_(allocator),
    333       physical_dev_(VK_NULL_HANDLE),
    334       instance_info_(create_info),
    335       extension_filter_() {
    336     hook_extensions_.set(ProcHook::EXTENSION_CORE);
    337     hal_extensions_.set(ProcHook::EXTENSION_CORE);
    338 }
    339 
    340 CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
    341                                      const VkDeviceCreateInfo& create_info,
    342                                      const VkAllocationCallbacks& allocator)
    343     : is_instance_(false),
    344       allocator_(allocator),
    345       physical_dev_(physical_dev),
    346       dev_info_(create_info),
    347       extension_filter_() {
    348     hook_extensions_.set(ProcHook::EXTENSION_CORE);
    349     hal_extensions_.set(ProcHook::EXTENSION_CORE);
    350 }
    351 
    352 CreateInfoWrapper::~CreateInfoWrapper() {
    353     allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
    354     allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
    355 }
    356 
    357 VkResult CreateInfoWrapper::Validate() {
    358     VkResult result = SanitizePNext();
    359     if (result == VK_SUCCESS)
    360         result = SanitizeLayers();
    361     if (result == VK_SUCCESS)
    362         result = SanitizeExtensions();
    363 
    364     return result;
    365 }
    366 
    367 const std::bitset<ProcHook::EXTENSION_COUNT>&
    368 CreateInfoWrapper::GetHookExtensions() const {
    369     return hook_extensions_;
    370 }
    371 
    372 const std::bitset<ProcHook::EXTENSION_COUNT>&
    373 CreateInfoWrapper::GetHalExtensions() const {
    374     return hal_extensions_;
    375 }
    376 
    377 CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
    378     return &instance_info_;
    379 }
    380 
    381 CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
    382     return &dev_info_;
    383 }
    384 
    385 VkResult CreateInfoWrapper::SanitizePNext() {
    386     const struct StructHeader {
    387         VkStructureType type;
    388         const void* next;
    389     } * header;
    390 
    391     if (is_instance_) {
    392         header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
    393 
    394         // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
    395         while (header &&
    396                header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
    397             header = reinterpret_cast<const StructHeader*>(header->next);
    398 
    399         instance_info_.pNext = header;
    400     } else {
    401         header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
    402 
    403         // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
    404         while (header &&
    405                header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
    406             header = reinterpret_cast<const StructHeader*>(header->next);
    407 
    408         dev_info_.pNext = header;
    409     }
    410 
    411     return VK_SUCCESS;
    412 }
    413 
    414 VkResult CreateInfoWrapper::SanitizeLayers() {
    415     auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
    416                                        : dev_info_.ppEnabledLayerNames;
    417     auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
    418                                        : dev_info_.enabledLayerCount;
    419 
    420     // remove all layers
    421     layer_names = nullptr;
    422     layer_count = 0;
    423 
    424     return VK_SUCCESS;
    425 }
    426 
    427 VkResult CreateInfoWrapper::SanitizeExtensions() {
    428     auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
    429                                      : dev_info_.ppEnabledExtensionNames;
    430     auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
    431                                      : dev_info_.enabledExtensionCount;
    432     if (!ext_count)
    433         return VK_SUCCESS;
    434 
    435     VkResult result = InitExtensionFilter();
    436     if (result != VK_SUCCESS)
    437         return result;
    438 
    439     for (uint32_t i = 0; i < ext_count; i++)
    440         FilterExtension(ext_names[i]);
    441 
    442     // Enable device extensions that contain physical-device commands, so that
    443     // vkGetInstanceProcAddr will return those physical-device commands.
    444     if (is_instance_) {
    445         hook_extensions_.set(ProcHook::KHR_swapchain);
    446     }
    447 
    448     ext_names = extension_filter_.names;
    449     ext_count = extension_filter_.name_count;
    450 
    451     return VK_SUCCESS;
    452 }
    453 
    454 VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
    455     if (is_instance_) {
    456         return Hal::Device().EnumerateInstanceExtensionProperties(
    457             nullptr, &count, nullptr);
    458     } else {
    459         const auto& driver = GetData(physical_dev_).driver;
    460         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
    461                                                          &count, nullptr);
    462     }
    463 }
    464 
    465 VkResult CreateInfoWrapper::EnumerateExtensions(
    466     uint32_t& count,
    467     VkExtensionProperties* props) const {
    468     if (is_instance_) {
    469         return Hal::Device().EnumerateInstanceExtensionProperties(
    470             nullptr, &count, props);
    471     } else {
    472         const auto& driver = GetData(physical_dev_).driver;
    473         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
    474                                                          &count, props);
    475     }
    476 }
    477 
    478 VkResult CreateInfoWrapper::InitExtensionFilter() {
    479     // query extension count
    480     uint32_t count;
    481     VkResult result = QueryExtensionCount(count);
    482     if (result != VK_SUCCESS || count == 0)
    483         return result;
    484 
    485     auto& filter = extension_filter_;
    486     filter.exts =
    487         reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
    488             allocator_.pUserData, sizeof(VkExtensionProperties) * count,
    489             alignof(VkExtensionProperties),
    490             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
    491     if (!filter.exts)
    492         return VK_ERROR_OUT_OF_HOST_MEMORY;
    493 
    494     // enumerate extensions
    495     result = EnumerateExtensions(count, filter.exts);
    496     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
    497         return result;
    498 
    499     if (!count)
    500         return VK_SUCCESS;
    501 
    502     filter.ext_count = count;
    503 
    504     // allocate name array
    505     uint32_t enabled_ext_count = (is_instance_)
    506                                      ? instance_info_.enabledExtensionCount
    507                                      : dev_info_.enabledExtensionCount;
    508     count = std::min(filter.ext_count, enabled_ext_count);
    509     filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
    510         allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
    511         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
    512     if (!filter.names)
    513         return VK_ERROR_OUT_OF_HOST_MEMORY;
    514 
    515     return VK_SUCCESS;
    516 }
    517 
    518 void CreateInfoWrapper::FilterExtension(const char* name) {
    519     auto& filter = extension_filter_;
    520 
    521     ProcHook::Extension ext_bit = GetProcHookExtension(name);
    522     if (is_instance_) {
    523         switch (ext_bit) {
    524             case ProcHook::KHR_android_surface:
    525             case ProcHook::KHR_surface:
    526             case ProcHook::EXT_swapchain_colorspace:
    527             case ProcHook::KHR_get_surface_capabilities2:
    528                 hook_extensions_.set(ext_bit);
    529                 // return now as these extensions do not require HAL support
    530                 return;
    531             case ProcHook::EXT_debug_report:
    532                 // both we and HAL can take part in
    533                 hook_extensions_.set(ext_bit);
    534                 break;
    535             case ProcHook::KHR_get_physical_device_properties2:
    536             case ProcHook::EXTENSION_UNKNOWN:
    537                 // Extensions we don't need to do anything about at this level
    538                 break;
    539 
    540             case ProcHook::KHR_bind_memory2:
    541             case ProcHook::KHR_incremental_present:
    542             case ProcHook::KHR_shared_presentable_image:
    543             case ProcHook::KHR_swapchain:
    544             case ProcHook::EXT_hdr_metadata:
    545             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
    546             case ProcHook::ANDROID_native_buffer:
    547             case ProcHook::GOOGLE_display_timing:
    548             case ProcHook::EXTENSION_CORE:
    549             case ProcHook::EXTENSION_COUNT:
    550                 // Device and meta extensions. If we ever get here it's a bug in
    551                 // our code. But enumerating them lets us avoid having a default
    552                 // case, and default hides other bugs.
    553                 ALOGE(
    554                     "CreateInfoWrapper::FilterExtension: invalid instance "
    555                     "extension '%s'. FIX ME",
    556                     name);
    557                 return;
    558 
    559             // Don't use a default case. Without it, -Wswitch will tell us
    560             // at compile time if someone adds a new ProcHook extension but
    561             // doesn't handle it above. That's a real bug that has
    562             // not-immediately-obvious effects.
    563             //
    564             // default:
    565             //     break;
    566         }
    567     } else {
    568         switch (ext_bit) {
    569             case ProcHook::KHR_swapchain:
    570                 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
    571                 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
    572                 ext_bit = ProcHook::ANDROID_native_buffer;
    573                 break;
    574             case ProcHook::KHR_incremental_present:
    575             case ProcHook::GOOGLE_display_timing:
    576             case ProcHook::KHR_shared_presentable_image:
    577                 hook_extensions_.set(ext_bit);
    578                 // return now as these extensions do not require HAL support
    579                 return;
    580             case ProcHook::EXT_hdr_metadata:
    581             case ProcHook::KHR_bind_memory2:
    582                 hook_extensions_.set(ext_bit);
    583                 break;
    584             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
    585             case ProcHook::EXTENSION_UNKNOWN:
    586                 // Extensions we don't need to do anything about at this level
    587                 break;
    588 
    589             case ProcHook::KHR_android_surface:
    590             case ProcHook::KHR_get_physical_device_properties2:
    591             case ProcHook::KHR_get_surface_capabilities2:
    592             case ProcHook::KHR_surface:
    593             case ProcHook::EXT_debug_report:
    594             case ProcHook::EXT_swapchain_colorspace:
    595             case ProcHook::ANDROID_native_buffer:
    596             case ProcHook::EXTENSION_CORE:
    597             case ProcHook::EXTENSION_COUNT:
    598                 // Instance and meta extensions. If we ever get here it's a bug
    599                 // in our code. But enumerating them lets us avoid having a
    600                 // default case, and default hides other bugs.
    601                 ALOGE(
    602                     "CreateInfoWrapper::FilterExtension: invalid device "
    603                     "extension '%s'. FIX ME",
    604                     name);
    605                 return;
    606 
    607             // Don't use a default case. Without it, -Wswitch will tell us
    608             // at compile time if someone adds a new ProcHook extension but
    609             // doesn't handle it above. That's a real bug that has
    610             // not-immediately-obvious effects.
    611             //
    612             // default:
    613             //     break;
    614         }
    615     }
    616 
    617     for (uint32_t i = 0; i < filter.ext_count; i++) {
    618         const VkExtensionProperties& props = filter.exts[i];
    619         // ignore unknown extensions
    620         if (strcmp(name, props.extensionName) != 0)
    621             continue;
    622 
    623         filter.names[filter.name_count++] = name;
    624         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
    625             if (ext_bit == ProcHook::ANDROID_native_buffer)
    626                 hook_extensions_.set(ProcHook::KHR_swapchain);
    627 
    628             hal_extensions_.set(ext_bit);
    629         }
    630 
    631         break;
    632     }
    633 }
    634 
    635 void CreateInfoWrapper::DowngradeApiVersion() {
    636     // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
    637     if (instance_info_.pApplicationInfo) {
    638         application_info_ = *instance_info_.pApplicationInfo;
    639         instance_info_.pApplicationInfo = &application_info_;
    640         application_info_.apiVersion = VK_API_VERSION_1_0;
    641     }
    642 }
    643 
    644 VKAPI_ATTR void* DefaultAllocate(void*,
    645                                  size_t size,
    646                                  size_t alignment,
    647                                  VkSystemAllocationScope) {
    648     void* ptr = nullptr;
    649     // Vulkan requires 'alignment' to be a power of two, but posix_memalign
    650     // additionally requires that it be at least sizeof(void*).
    651     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
    652     ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
    653                     ret, ptr);
    654     return ret == 0 ? ptr : nullptr;
    655 }
    656 
    657 VKAPI_ATTR void* DefaultReallocate(void*,
    658                                    void* ptr,
    659                                    size_t size,
    660                                    size_t alignment,
    661                                    VkSystemAllocationScope) {
    662     if (size == 0) {
    663         free(ptr);
    664         return nullptr;
    665     }
    666 
    667     // TODO(jessehall): Right now we never shrink allocations; if the new
    668     // request is smaller than the existing chunk, we just continue using it.
    669     // Right now the loader never reallocs, so this doesn't matter. If that
    670     // changes, or if this code is copied into some other project, this should
    671     // probably have a heuristic to allocate-copy-free when doing so will save
    672     // "enough" space.
    673     size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
    674     if (size <= old_size)
    675         return ptr;
    676 
    677     void* new_ptr = nullptr;
    678     if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
    679         return nullptr;
    680     if (ptr) {
    681         memcpy(new_ptr, ptr, std::min(old_size, size));
    682         free(ptr);
    683     }
    684     return new_ptr;
    685 }
    686 
    687 VKAPI_ATTR void DefaultFree(void*, void* ptr) {
    688     ALOGD_CALLSTACK("Free: %p", ptr);
    689     free(ptr);
    690 }
    691 
    692 InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
    693     void* data_mem = allocator.pfnAllocation(
    694         allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
    695         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    696     if (!data_mem)
    697         return nullptr;
    698 
    699     return new (data_mem) InstanceData(allocator);
    700 }
    701 
    702 void FreeInstanceData(InstanceData* data,
    703                       const VkAllocationCallbacks& allocator) {
    704     data->~InstanceData();
    705     allocator.pfnFree(allocator.pUserData, data);
    706 }
    707 
    708 DeviceData* AllocateDeviceData(
    709     const VkAllocationCallbacks& allocator,
    710     const DebugReportCallbackList& debug_report_callbacks) {
    711     void* data_mem = allocator.pfnAllocation(
    712         allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
    713         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
    714     if (!data_mem)
    715         return nullptr;
    716 
    717     return new (data_mem) DeviceData(allocator, debug_report_callbacks);
    718 }
    719 
    720 void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
    721     data->~DeviceData();
    722     allocator.pfnFree(allocator.pUserData, data);
    723 }
    724 
    725 }  // anonymous namespace
    726 
    727 bool Debuggable() {
    728     return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
    729 }
    730 
    731 bool OpenHAL() {
    732     return Hal::Open();
    733 }
    734 
    735 const VkAllocationCallbacks& GetDefaultAllocator() {
    736     static const VkAllocationCallbacks kDefaultAllocCallbacks = {
    737         .pUserData = nullptr,
    738         .pfnAllocation = DefaultAllocate,
    739         .pfnReallocation = DefaultReallocate,
    740         .pfnFree = DefaultFree,
    741     };
    742 
    743     return kDefaultAllocCallbacks;
    744 }
    745 
    746 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
    747     const ProcHook* hook = GetProcHook(pName);
    748     if (!hook)
    749         return Hal::Device().GetInstanceProcAddr(instance, pName);
    750 
    751     if (!instance) {
    752         if (hook->type == ProcHook::GLOBAL)
    753             return hook->proc;
    754 
    755         // v0 layers expect
    756         //
    757         //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
    758         //
    759         // to work.
    760         if (strcmp(pName, "vkCreateDevice") == 0)
    761             return hook->proc;
    762 
    763         ALOGE(
    764             "internal vkGetInstanceProcAddr called for %s without an instance",
    765             pName);
    766 
    767         return nullptr;
    768     }
    769 
    770     PFN_vkVoidFunction proc;
    771 
    772     switch (hook->type) {
    773         case ProcHook::INSTANCE:
    774             proc = (GetData(instance).hook_extensions[hook->extension])
    775                        ? hook->proc
    776                        : nullptr;
    777             break;
    778         case ProcHook::DEVICE:
    779             proc = (hook->extension == ProcHook::EXTENSION_CORE)
    780                        ? hook->proc
    781                        : hook->checked_proc;
    782             break;
    783         default:
    784             ALOGE(
    785                 "internal vkGetInstanceProcAddr called for %s with an instance",
    786                 pName);
    787             proc = nullptr;
    788             break;
    789     }
    790 
    791     return proc;
    792 }
    793 
    794 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
    795     const ProcHook* hook = GetProcHook(pName);
    796     if (!hook)
    797         return GetData(device).driver.GetDeviceProcAddr(device, pName);
    798 
    799     if (hook->type != ProcHook::DEVICE) {
    800         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
    801         return nullptr;
    802     }
    803 
    804     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
    805                                                               : nullptr;
    806 }
    807 
    808 VkResult EnumerateInstanceExtensionProperties(
    809     const char* pLayerName,
    810     uint32_t* pPropertyCount,
    811     VkExtensionProperties* pProperties) {
    812 
    813     android::Vector<VkExtensionProperties> loader_extensions;
    814     loader_extensions.push_back({
    815         VK_KHR_SURFACE_EXTENSION_NAME,
    816         VK_KHR_SURFACE_SPEC_VERSION});
    817     loader_extensions.push_back({
    818         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
    819         VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
    820     loader_extensions.push_back({
    821         VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
    822         VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
    823     loader_extensions.push_back({
    824         VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
    825         VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
    826 
    827     static const VkExtensionProperties loader_debug_report_extension = {
    828         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
    829     };
    830 
    831     // enumerate our extensions first
    832     if (!pLayerName && pProperties) {
    833         uint32_t count = std::min(
    834             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
    835 
    836         std::copy_n(loader_extensions.begin(), count, pProperties);
    837 
    838         if (count < loader_extensions.size()) {
    839             *pPropertyCount = count;
    840             return VK_INCOMPLETE;
    841         }
    842 
    843         pProperties += count;
    844         *pPropertyCount -= count;
    845 
    846         if (Hal::Get().GetDebugReportIndex() < 0) {
    847             if (!*pPropertyCount) {
    848                 *pPropertyCount = count;
    849                 return VK_INCOMPLETE;
    850             }
    851 
    852             pProperties[0] = loader_debug_report_extension;
    853             pProperties += 1;
    854             *pPropertyCount -= 1;
    855         }
    856     }
    857 
    858     ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
    859     VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
    860         pLayerName, pPropertyCount, pProperties);
    861     ATRACE_END();
    862 
    863     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
    864         int idx = Hal::Get().GetDebugReportIndex();
    865         if (idx < 0) {
    866             *pPropertyCount += 1;
    867         } else if (pProperties &&
    868                    static_cast<uint32_t>(idx) < *pPropertyCount) {
    869             pProperties[idx].specVersion =
    870                 std::min(pProperties[idx].specVersion,
    871                          loader_debug_report_extension.specVersion);
    872         }
    873 
    874         *pPropertyCount += loader_extensions.size();
    875     }
    876 
    877     return result;
    878 }
    879 
    880 bool QueryPresentationProperties(
    881     VkPhysicalDevice physicalDevice,
    882     VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
    883 {
    884     const InstanceData& data = GetData(physicalDevice);
    885 
    886     // GPDP2 must be present and enabled on the instance.
    887     if (!data.driver.GetPhysicalDeviceProperties2KHR &&
    888         !data.driver.GetPhysicalDeviceProperties2)
    889         return false;
    890 
    891     // Request the android-specific presentation properties via GPDP2
    892     VkPhysicalDeviceProperties2KHR properties = {
    893         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
    894         presentation_properties,
    895         {}
    896     };
    897 
    898 #pragma clang diagnostic push
    899 #pragma clang diagnostic ignored "-Wold-style-cast"
    900     presentation_properties->sType =
    901         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
    902 #pragma clang diagnostic pop
    903     presentation_properties->pNext = nullptr;
    904     presentation_properties->sharedImage = VK_FALSE;
    905 
    906     if (data.driver.GetPhysicalDeviceProperties2KHR) {
    907         data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
    908                                                     &properties);
    909     } else {
    910         data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
    911     }
    912 
    913     return true;
    914 }
    915 
    916 VkResult EnumerateDeviceExtensionProperties(
    917     VkPhysicalDevice physicalDevice,
    918     const char* pLayerName,
    919     uint32_t* pPropertyCount,
    920     VkExtensionProperties* pProperties) {
    921     const InstanceData& data = GetData(physicalDevice);
    922     // extensions that are unconditionally exposed by the loader
    923     android::Vector<VkExtensionProperties> loader_extensions;
    924     loader_extensions.push_back({
    925         VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
    926         VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
    927 
    928     bool hdrBoardConfig =
    929         getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
    930             false);
    931     if (hdrBoardConfig) {
    932         loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
    933                                      VK_EXT_HDR_METADATA_SPEC_VERSION});
    934     }
    935 
    936     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
    937     if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
    938         presentation_properties.sharedImage) {
    939         loader_extensions.push_back({
    940             VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
    941             VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
    942     }
    943 
    944     // conditionally add VK_GOOGLE_display_timing if present timestamps are
    945     // supported by the driver:
    946     const std::string timestamp_property("service.sf.present_timestamp");
    947     android::base::WaitForPropertyCreation(timestamp_property);
    948     if (android::base::GetBoolProperty(timestamp_property, true)) {
    949         loader_extensions.push_back({
    950                 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
    951                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
    952     }
    953 
    954     // enumerate our extensions first
    955     if (!pLayerName && pProperties) {
    956         uint32_t count = std::min(
    957             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
    958 
    959         std::copy_n(loader_extensions.begin(), count, pProperties);
    960 
    961         if (count < loader_extensions.size()) {
    962             *pPropertyCount = count;
    963             return VK_INCOMPLETE;
    964         }
    965 
    966         pProperties += count;
    967         *pPropertyCount -= count;
    968     }
    969 
    970     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
    971     VkResult result = data.driver.EnumerateDeviceExtensionProperties(
    972         physicalDevice, pLayerName, pPropertyCount, pProperties);
    973     ATRACE_END();
    974 
    975     if (pProperties) {
    976         // map VK_ANDROID_native_buffer to VK_KHR_swapchain
    977         for (uint32_t i = 0; i < *pPropertyCount; i++) {
    978             auto& prop = pProperties[i];
    979 
    980             if (strcmp(prop.extensionName,
    981                        VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
    982                 continue;
    983 
    984             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    985                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
    986 
    987             if (prop.specVersion >= 8) {
    988                 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
    989             } else {
    990                 prop.specVersion = 68;
    991             }
    992         }
    993     }
    994 
    995     // restore loader extension count
    996     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
    997         *pPropertyCount += loader_extensions.size();
    998     }
    999 
   1000     return result;
   1001 }
   1002 
   1003 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
   1004                         const VkAllocationCallbacks* pAllocator,
   1005                         VkInstance* pInstance) {
   1006     const VkAllocationCallbacks& data_allocator =
   1007         (pAllocator) ? *pAllocator : GetDefaultAllocator();
   1008 
   1009     CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
   1010     VkResult result = wrapper.Validate();
   1011     if (result != VK_SUCCESS)
   1012         return result;
   1013 
   1014     ATRACE_BEGIN("AllocateInstanceData");
   1015     InstanceData* data = AllocateInstanceData(data_allocator);
   1016     ATRACE_END();
   1017     if (!data)
   1018         return VK_ERROR_OUT_OF_HOST_MEMORY;
   1019 
   1020     data->hook_extensions |= wrapper.GetHookExtensions();
   1021 
   1022     ATRACE_BEGIN("autoDowngradeApiVersion");
   1023 #pragma clang diagnostic push
   1024 #pragma clang diagnostic ignored "-Wold-style-cast"
   1025     uint32_t api_version = ((pCreateInfo->pApplicationInfo)
   1026                                 ? pCreateInfo->pApplicationInfo->apiVersion
   1027                                 : VK_API_VERSION_1_0);
   1028     uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
   1029     uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
   1030     uint32_t icd_api_version;
   1031     PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
   1032         reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
   1033             Hal::Device().GetInstanceProcAddr(nullptr,
   1034                                               "vkEnumerateInstanceVersion"));
   1035     if (!pfn_enumerate_instance_version) {
   1036         icd_api_version = VK_API_VERSION_1_0;
   1037     } else {
   1038         ATRACE_BEGIN("pfn_enumerate_instance_version");
   1039         result = (*pfn_enumerate_instance_version)(&icd_api_version);
   1040         ATRACE_END();
   1041     }
   1042     uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
   1043     uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
   1044 
   1045     if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
   1046         ((api_major_version > 1) || (api_minor_version > 0))) {
   1047         api_version = VK_API_VERSION_1_0;
   1048         wrapper.DowngradeApiVersion();
   1049     }
   1050 #pragma clang diagnostic pop
   1051     ATRACE_END();
   1052 
   1053     // call into the driver
   1054     VkInstance instance;
   1055     ATRACE_BEGIN("driver.CreateInstance");
   1056     result = Hal::Device().CreateInstance(
   1057         static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
   1058         &instance);
   1059     ATRACE_END();
   1060     if (result != VK_SUCCESS) {
   1061         FreeInstanceData(data, data_allocator);
   1062         return result;
   1063     }
   1064 
   1065     // initialize InstanceDriverTable
   1066     if (!SetData(instance, *data) ||
   1067         !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
   1068                          wrapper.GetHalExtensions())) {
   1069         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
   1070             Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
   1071         if (data->driver.DestroyInstance)
   1072             data->driver.DestroyInstance(instance, pAllocator);
   1073 
   1074         FreeInstanceData(data, data_allocator);
   1075 
   1076         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1077     }
   1078 
   1079     data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
   1080         Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
   1081     if (!data->get_device_proc_addr) {
   1082         data->driver.DestroyInstance(instance, pAllocator);
   1083         FreeInstanceData(data, data_allocator);
   1084 
   1085         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1086     }
   1087 
   1088     *pInstance = instance;
   1089 
   1090     return VK_SUCCESS;
   1091 }
   1092 
   1093 void DestroyInstance(VkInstance instance,
   1094                      const VkAllocationCallbacks* pAllocator) {
   1095     InstanceData& data = GetData(instance);
   1096     data.driver.DestroyInstance(instance, pAllocator);
   1097 
   1098     VkAllocationCallbacks local_allocator;
   1099     if (!pAllocator) {
   1100         local_allocator = data.allocator;
   1101         pAllocator = &local_allocator;
   1102     }
   1103 
   1104     FreeInstanceData(&data, *pAllocator);
   1105 }
   1106 
   1107 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
   1108                       const VkDeviceCreateInfo* pCreateInfo,
   1109                       const VkAllocationCallbacks* pAllocator,
   1110                       VkDevice* pDevice) {
   1111     const InstanceData& instance_data = GetData(physicalDevice);
   1112     const VkAllocationCallbacks& data_allocator =
   1113         (pAllocator) ? *pAllocator : instance_data.allocator;
   1114 
   1115     CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
   1116     VkResult result = wrapper.Validate();
   1117     if (result != VK_SUCCESS)
   1118         return result;
   1119 
   1120     ATRACE_BEGIN("AllocateDeviceData");
   1121     DeviceData* data = AllocateDeviceData(data_allocator,
   1122                                           instance_data.debug_report_callbacks);
   1123     ATRACE_END();
   1124     if (!data)
   1125         return VK_ERROR_OUT_OF_HOST_MEMORY;
   1126 
   1127     data->hook_extensions |= wrapper.GetHookExtensions();
   1128 
   1129     // call into the driver
   1130     VkDevice dev;
   1131     ATRACE_BEGIN("driver.CreateDevice");
   1132     result = instance_data.driver.CreateDevice(
   1133         physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
   1134         pAllocator, &dev);
   1135     ATRACE_END();
   1136     if (result != VK_SUCCESS) {
   1137         FreeDeviceData(data, data_allocator);
   1138         return result;
   1139     }
   1140 
   1141     // initialize DeviceDriverTable
   1142     if (!SetData(dev, *data) ||
   1143         !InitDriverTable(dev, instance_data.get_device_proc_addr,
   1144                          wrapper.GetHalExtensions())) {
   1145         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
   1146             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
   1147         if (data->driver.DestroyDevice)
   1148             data->driver.DestroyDevice(dev, pAllocator);
   1149 
   1150         FreeDeviceData(data, data_allocator);
   1151 
   1152         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1153     }
   1154 
   1155     // sanity check ANDROID_native_buffer implementation, whose set of
   1156     // entrypoints varies according to the spec version.
   1157     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
   1158         !data->driver.GetSwapchainGrallocUsageANDROID &&
   1159         !data->driver.GetSwapchainGrallocUsage2ANDROID) {
   1160         ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
   1161               " must expose at least one of "
   1162               "vkGetSwapchainGrallocUsageANDROID or "
   1163               "vkGetSwapchainGrallocUsage2ANDROID");
   1164 
   1165         data->driver.DestroyDevice(dev, pAllocator);
   1166         FreeDeviceData(data, data_allocator);
   1167 
   1168         return VK_ERROR_INCOMPATIBLE_DRIVER;
   1169     }
   1170 
   1171     VkPhysicalDeviceProperties properties;
   1172     ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
   1173     instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
   1174                                                      &properties);
   1175     ATRACE_END();
   1176 
   1177     if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
   1178         // Log that the app is hitting software Vulkan implementation
   1179         android::GraphicsEnv::getInstance().setCpuVulkanInUse();
   1180     }
   1181 
   1182     data->driver_device = dev;
   1183     data->driver_version = properties.driverVersion;
   1184 
   1185     *pDevice = dev;
   1186 
   1187     return VK_SUCCESS;
   1188 }
   1189 
   1190 void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
   1191     DeviceData& data = GetData(device);
   1192     data.driver.DestroyDevice(device, pAllocator);
   1193 
   1194     VkAllocationCallbacks local_allocator;
   1195     if (!pAllocator) {
   1196         local_allocator = data.allocator;
   1197         pAllocator = &local_allocator;
   1198     }
   1199 
   1200     FreeDeviceData(&data, *pAllocator);
   1201 }
   1202 
   1203 VkResult EnumeratePhysicalDevices(VkInstance instance,
   1204                                   uint32_t* pPhysicalDeviceCount,
   1205                                   VkPhysicalDevice* pPhysicalDevices) {
   1206     ATRACE_CALL();
   1207 
   1208     const auto& data = GetData(instance);
   1209 
   1210     VkResult result = data.driver.EnumeratePhysicalDevices(
   1211         instance, pPhysicalDeviceCount, pPhysicalDevices);
   1212     if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
   1213         for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
   1214             SetData(pPhysicalDevices[i], data);
   1215     }
   1216 
   1217     return result;
   1218 }
   1219 
   1220 VkResult EnumeratePhysicalDeviceGroups(
   1221     VkInstance instance,
   1222     uint32_t* pPhysicalDeviceGroupCount,
   1223     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
   1224     ATRACE_CALL();
   1225 
   1226     VkResult result = VK_SUCCESS;
   1227     const auto& data = GetData(instance);
   1228 
   1229     if (!data.driver.EnumeratePhysicalDeviceGroups) {
   1230         uint32_t device_count = 0;
   1231         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
   1232         if (result < 0)
   1233             return result;
   1234 
   1235         if (!pPhysicalDeviceGroupProperties) {
   1236             *pPhysicalDeviceGroupCount = device_count;
   1237             return result;
   1238         }
   1239 
   1240         if (!device_count) {
   1241             *pPhysicalDeviceGroupCount = 0;
   1242             return result;
   1243         }
   1244         device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
   1245         if (!device_count)
   1246             return VK_INCOMPLETE;
   1247 
   1248         android::Vector<VkPhysicalDevice> devices;
   1249         devices.resize(device_count);
   1250         *pPhysicalDeviceGroupCount = device_count;
   1251         result = EnumeratePhysicalDevices(instance, &device_count,
   1252                                           devices.editArray());
   1253         if (result < 0)
   1254             return result;
   1255 
   1256         for (uint32_t i = 0; i < device_count; ++i) {
   1257             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
   1258             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
   1259             pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
   1260         }
   1261     } else {
   1262         result = data.driver.EnumeratePhysicalDeviceGroups(
   1263             instance, pPhysicalDeviceGroupCount,
   1264             pPhysicalDeviceGroupProperties);
   1265         if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
   1266             *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
   1267             for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
   1268                 for (uint32_t j = 0;
   1269                      j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
   1270                      j++) {
   1271                     SetData(
   1272                         pPhysicalDeviceGroupProperties[i].physicalDevices[j],
   1273                         data);
   1274                 }
   1275             }
   1276         }
   1277     }
   1278 
   1279     return result;
   1280 }
   1281 
   1282 void GetDeviceQueue(VkDevice device,
   1283                     uint32_t queueFamilyIndex,
   1284                     uint32_t queueIndex,
   1285                     VkQueue* pQueue) {
   1286     ATRACE_CALL();
   1287 
   1288     const auto& data = GetData(device);
   1289 
   1290     data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
   1291     SetData(*pQueue, data);
   1292 }
   1293 
   1294 void GetDeviceQueue2(VkDevice device,
   1295                      const VkDeviceQueueInfo2* pQueueInfo,
   1296                      VkQueue* pQueue) {
   1297     ATRACE_CALL();
   1298 
   1299     const auto& data = GetData(device);
   1300 
   1301     data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
   1302     if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
   1303 }
   1304 
   1305 VKAPI_ATTR VkResult
   1306 AllocateCommandBuffers(VkDevice device,
   1307                        const VkCommandBufferAllocateInfo* pAllocateInfo,
   1308                        VkCommandBuffer* pCommandBuffers) {
   1309     ATRACE_CALL();
   1310 
   1311     const auto& data = GetData(device);
   1312 
   1313     VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
   1314                                                          pCommandBuffers);
   1315     if (result == VK_SUCCESS) {
   1316         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
   1317             SetData(pCommandBuffers[i], data);
   1318     }
   1319 
   1320     return result;
   1321 }
   1322 
   1323 }  // namespace driver
   1324 }  // namespace vulkan
   1325