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