OSDN Git Service

d7fdab558669896267c70da31e12699c8cfea70e
[android-x86/frameworks-native.git] / vulkan / libvulkan / driver.cpp
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 "driver.h"
20
21 #include <dlfcn.h>
22 #include <malloc.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <SurfaceFlingerProperties.h>
27 #include <android-base/properties.h>
28 #include <android/dlext.h>
29 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
30 #include <configstore/Utils.h>
31 #include <graphicsenv/GraphicsEnv.h>
32 #include <log/log.h>
33 #include <sys/prctl.h>
34 #include <utils/Timers.h>
35 #include <utils/Trace.h>
36 #include <vndksupport/linker.h>
37
38 #include <algorithm>
39 #include <array>
40 #include <climits>
41 #include <new>
42 #include <vector>
43
44 #include "stubhal.h"
45
46 using namespace android::hardware::configstore;
47 using namespace android::hardware::configstore::V1_0;
48
49 // #define ENABLE_ALLOC_CALLSTACKS 1
50 #if ENABLE_ALLOC_CALLSTACKS
51 #include <utils/CallStack.h>
52 #define ALOGD_CALLSTACK(...)                             \
53     do {                                                 \
54         ALOGD(__VA_ARGS__);                              \
55         android::CallStack callstack;                    \
56         callstack.update();                              \
57         callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
58     } while (false)
59 #else
60 #define ALOGD_CALLSTACK(...) \
61     do {                     \
62     } while (false)
63 #endif
64
65 namespace vulkan {
66 namespace driver {
67
68 namespace {
69
70 class Hal {
71    public:
72     static bool Open();
73
74     static const Hal& Get() { return hal_; }
75     static const hwvulkan_device_t& Device() { return *Get().dev_; }
76
77     int GetDebugReportIndex() const { return debug_report_index_; }
78
79    private:
80     Hal() : dev_(nullptr), debug_report_index_(-1) {}
81     Hal(const Hal&) = delete;
82     Hal& operator=(const Hal&) = delete;
83
84     bool ShouldUnloadBuiltinDriver();
85     void UnloadBuiltinDriver();
86     bool InitDebugReportIndex();
87
88     static Hal hal_;
89
90     const hwvulkan_device_t* dev_;
91     int debug_report_index_;
92 };
93
94 class CreateInfoWrapper {
95    public:
96     CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
97                       uint32_t icd_api_version,
98                       const VkAllocationCallbacks& allocator);
99     CreateInfoWrapper(VkPhysicalDevice physical_dev,
100                       const VkDeviceCreateInfo& create_info,
101                       uint32_t icd_api_version,
102                       const VkAllocationCallbacks& allocator);
103     ~CreateInfoWrapper();
104
105     VkResult Validate();
106
107     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
108     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
109
110     explicit operator const VkInstanceCreateInfo*() const;
111     explicit operator const VkDeviceCreateInfo*() const;
112
113    private:
114     struct ExtensionFilter {
115         VkExtensionProperties* exts;
116         uint32_t ext_count;
117
118         const char** names;
119         uint32_t name_count;
120         ExtensionFilter()
121             : exts(nullptr), ext_count(0), names(nullptr), name_count(0) {}
122     };
123
124     VkResult SanitizeApiVersion();
125     VkResult SanitizePNext();
126     VkResult SanitizeLayers();
127     VkResult SanitizeExtensions();
128
129     VkResult QueryExtensionCount(uint32_t& count) const;
130     VkResult EnumerateExtensions(uint32_t& count,
131                                  VkExtensionProperties* props) const;
132     VkResult InitExtensionFilter();
133     void FilterExtension(const char* name);
134
135     const bool is_instance_;
136     const VkAllocationCallbacks& allocator_;
137     const uint32_t loader_api_version_;
138     const uint32_t icd_api_version_;
139
140     VkPhysicalDevice physical_dev_;
141
142     union {
143         VkInstanceCreateInfo instance_info_;
144         VkDeviceCreateInfo dev_info_;
145     };
146
147     VkApplicationInfo application_info_;
148
149     ExtensionFilter extension_filter_;
150
151     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
152     std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
153 };
154
155 Hal Hal::hal_;
156
157 const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
158     "ro.hardware.vulkan",
159     "ro.board.platform",
160 }};
161 constexpr int LIB_DL_FLAGS = RTLD_LOCAL | RTLD_NOW;
162
163 // LoadDriver returns:
164 // * 0 when succeed, or
165 // * -ENOENT when fail to open binary libraries, or
166 // * -EINVAL when fail to find HAL_MODULE_INFO_SYM_AS_STR or
167 //   HWVULKAN_HARDWARE_MODULE_ID in the library.
168 int LoadDriver(android_namespace_t* library_namespace,
169                const hwvulkan_module_t** module) {
170     ATRACE_CALL();
171
172     void* so = nullptr;
173     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
174         std::string lib_name = android::base::GetProperty(key, "");
175         if (lib_name.empty())
176             continue;
177
178         lib_name = "vulkan." + lib_name + ".so";
179         if (library_namespace) {
180             // load updated driver
181             const android_dlextinfo dlextinfo = {
182                 .flags = ANDROID_DLEXT_USE_NAMESPACE,
183                 .library_namespace = library_namespace,
184             };
185             so = android_dlopen_ext(lib_name.c_str(), LIB_DL_FLAGS, &dlextinfo);
186             ALOGE("Could not load %s from updatable gfx driver namespace: %s.",
187                   lib_name.c_str(), dlerror());
188         } else {
189             // load built-in driver
190             so = android_load_sphal_library(lib_name.c_str(), LIB_DL_FLAGS);
191         }
192         if (so)
193             break;
194     }
195     if (!so)
196         return -ENOENT;
197
198     auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
199     if (!hmi) {
200         ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
201         dlclose(so);
202         return -EINVAL;
203     }
204     if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
205         ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
206         dlclose(so);
207         return -EINVAL;
208     }
209     hmi->dso = so;
210     *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
211     return 0;
212 }
213
214 int LoadBuiltinDriver(const hwvulkan_module_t** module) {
215     ATRACE_CALL();
216
217     android::GraphicsEnv::getInstance().setDriverToLoad(
218         android::GpuStatsInfo::Driver::VULKAN);
219     return LoadDriver(nullptr, module);
220 }
221
222 int LoadUpdatedDriver(const hwvulkan_module_t** module) {
223     ATRACE_CALL();
224
225     auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
226     if (!ns)
227         return -ENOENT;
228     android::GraphicsEnv::getInstance().setDriverToLoad(
229         android::GpuStatsInfo::Driver::VULKAN_UPDATED);
230     int result = LoadDriver(ns, module);
231     if (result != 0) {
232         LOG_ALWAYS_FATAL(
233             "couldn't find an updated Vulkan implementation from %s",
234             android::GraphicsEnv::getInstance().getDriverPath().c_str());
235     }
236     return result;
237 }
238
239 bool Hal::Open() {
240     ATRACE_CALL();
241
242     const nsecs_t openTime = systemTime();
243
244     if (hal_.ShouldUnloadBuiltinDriver()) {
245         hal_.UnloadBuiltinDriver();
246     }
247
248     if (hal_.dev_)
249         return true;
250
251     // Use a stub device unless we successfully open a real HAL device.
252     hal_.dev_ = &stubhal::kDevice;
253
254     int result;
255     const hwvulkan_module_t* module = nullptr;
256
257     result = LoadUpdatedDriver(&module);
258     if (result == -ENOENT) {
259         result = LoadBuiltinDriver(&module);
260     }
261     if (result != 0) {
262         android::GraphicsEnv::getInstance().setDriverLoaded(
263             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
264         ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
265         return true;
266     }
267
268
269     hwvulkan_device_t* device;
270     ATRACE_BEGIN("hwvulkan module open");
271     result =
272         module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
273                                      reinterpret_cast<hw_device_t**>(&device));
274     ATRACE_END();
275     if (result != 0) {
276         android::GraphicsEnv::getInstance().setDriverLoaded(
277             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
278         // Any device with a Vulkan HAL should be able to open the device.
279         ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
280               result);
281         return false;
282     }
283
284     hal_.dev_ = device;
285
286     hal_.InitDebugReportIndex();
287
288     android::GraphicsEnv::getInstance().setDriverLoaded(
289         android::GpuStatsInfo::Api::API_VK, true, systemTime() - openTime);
290
291     return true;
292 }
293
294 bool Hal::ShouldUnloadBuiltinDriver() {
295     // Should not unload since the driver was not loaded
296     if (!hal_.dev_)
297         return false;
298
299     // Should not unload if stubhal is used on the device
300     if (hal_.dev_ == &stubhal::kDevice)
301         return false;
302
303     // Unload the driver if updated driver is chosen
304     if (android::GraphicsEnv::getInstance().getDriverNamespace())
305         return true;
306
307     return false;
308 }
309
310 void Hal::UnloadBuiltinDriver() {
311     ATRACE_CALL();
312
313     ALOGD("Unload builtin Vulkan driver.");
314
315     // Close the opened device
316     ALOG_ASSERT(!hal_.dev_->common.close(hal_.dev_->common),
317                 "hw_device_t::close() failed.");
318
319     // Close the opened shared library in the hw_module_t
320     android_unload_sphal_library(hal_.dev_->common.module->dso);
321
322     hal_.dev_ = nullptr;
323     hal_.debug_report_index_ = -1;
324 }
325
326 bool Hal::InitDebugReportIndex() {
327     ATRACE_CALL();
328
329     uint32_t count;
330     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
331         VK_SUCCESS) {
332         ALOGE("failed to get HAL instance extension count");
333         return false;
334     }
335
336     VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
337         malloc(sizeof(VkExtensionProperties) * count));
338     if (!exts) {
339         ALOGE("failed to allocate HAL instance extension array");
340         return false;
341     }
342
343     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
344         VK_SUCCESS) {
345         ALOGE("failed to enumerate HAL instance extensions");
346         free(exts);
347         return false;
348     }
349
350     for (uint32_t i = 0; i < count; i++) {
351         if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
352             0) {
353             debug_report_index_ = static_cast<int>(i);
354             break;
355         }
356     }
357
358     free(exts);
359
360     return true;
361 }
362
363 CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
364                                      uint32_t icd_api_version,
365                                      const VkAllocationCallbacks& allocator)
366     : is_instance_(true),
367       allocator_(allocator),
368       loader_api_version_(VK_API_VERSION_1_1),
369       icd_api_version_(icd_api_version),
370       physical_dev_(VK_NULL_HANDLE),
371       instance_info_(create_info),
372       extension_filter_() {}
373
374 CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
375                                      const VkDeviceCreateInfo& create_info,
376                                      uint32_t icd_api_version,
377                                      const VkAllocationCallbacks& allocator)
378     : is_instance_(false),
379       allocator_(allocator),
380       loader_api_version_(VK_API_VERSION_1_1),
381       icd_api_version_(icd_api_version),
382       physical_dev_(physical_dev),
383       dev_info_(create_info),
384       extension_filter_() {}
385
386 CreateInfoWrapper::~CreateInfoWrapper() {
387     allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
388     allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
389 }
390
391 VkResult CreateInfoWrapper::Validate() {
392     VkResult result = SanitizeApiVersion();
393     if (result == VK_SUCCESS)
394         result = SanitizePNext();
395     if (result == VK_SUCCESS)
396         result = SanitizeLayers();
397     if (result == VK_SUCCESS)
398         result = SanitizeExtensions();
399
400     return result;
401 }
402
403 const std::bitset<ProcHook::EXTENSION_COUNT>&
404 CreateInfoWrapper::GetHookExtensions() const {
405     return hook_extensions_;
406 }
407
408 const std::bitset<ProcHook::EXTENSION_COUNT>&
409 CreateInfoWrapper::GetHalExtensions() const {
410     return hal_extensions_;
411 }
412
413 CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
414     return &instance_info_;
415 }
416
417 CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
418     return &dev_info_;
419 }
420
421 VkResult CreateInfoWrapper::SanitizeApiVersion() {
422     if (!is_instance_ || !instance_info_.pApplicationInfo)
423         return VK_SUCCESS;
424
425     if (icd_api_version_ > VK_API_VERSION_1_0 ||
426         instance_info_.pApplicationInfo->apiVersion < VK_API_VERSION_1_1)
427         return VK_SUCCESS;
428
429     // override apiVersion to avoid error return from 1.0 icd
430     application_info_ = *instance_info_.pApplicationInfo;
431     application_info_.apiVersion = VK_API_VERSION_1_0;
432     instance_info_.pApplicationInfo = &application_info_;
433
434     return VK_SUCCESS;
435 }
436
437 VkResult CreateInfoWrapper::SanitizePNext() {
438     const struct StructHeader {
439         VkStructureType type;
440         const void* next;
441     } * header;
442
443     if (is_instance_) {
444         header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
445
446         // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
447         while (header &&
448                header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
449             header = reinterpret_cast<const StructHeader*>(header->next);
450
451         instance_info_.pNext = header;
452     } else {
453         header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
454
455         // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
456         while (header &&
457                header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
458             header = reinterpret_cast<const StructHeader*>(header->next);
459
460         dev_info_.pNext = header;
461     }
462
463     return VK_SUCCESS;
464 }
465
466 VkResult CreateInfoWrapper::SanitizeLayers() {
467     auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
468                                        : dev_info_.ppEnabledLayerNames;
469     auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
470                                        : dev_info_.enabledLayerCount;
471
472     // remove all layers
473     layer_names = nullptr;
474     layer_count = 0;
475
476     return VK_SUCCESS;
477 }
478
479 VkResult CreateInfoWrapper::SanitizeExtensions() {
480     auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
481                                      : dev_info_.ppEnabledExtensionNames;
482     auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
483                                      : dev_info_.enabledExtensionCount;
484
485     VkResult result = InitExtensionFilter();
486     if (result != VK_SUCCESS)
487         return result;
488
489     if (is_instance_ && icd_api_version_ < loader_api_version_) {
490         for (uint32_t i = 0; i < ext_count; i++) {
491             // Upon api downgrade, skip the promoted instance extensions in the
492             // first pass to avoid duplicate extensions.
493             const std::optional<uint32_t> version =
494                 GetInstanceExtensionPromotedVersion(ext_names[i]);
495             if (version && *version > icd_api_version_ &&
496                 *version <= loader_api_version_)
497                 continue;
498
499             FilterExtension(ext_names[i]);
500         }
501
502         // Enable the required extensions to support core functionalities.
503         const auto promoted_extensions = GetPromotedInstanceExtensions(
504             icd_api_version_, loader_api_version_);
505         for (const auto& promoted_extension : promoted_extensions)
506             FilterExtension(promoted_extension);
507     } else {
508         for (uint32_t i = 0; i < ext_count; i++)
509             FilterExtension(ext_names[i]);
510     }
511
512     // Enable device extensions that contain physical-device commands, so that
513     // vkGetInstanceProcAddr will return those physical-device commands.
514     if (is_instance_) {
515         hook_extensions_.set(ProcHook::KHR_swapchain);
516     }
517
518     const uint32_t api_version =
519         is_instance_ ? loader_api_version_
520                      : std::min(icd_api_version_, loader_api_version_);
521     switch (api_version) {
522         case VK_API_VERSION_1_1:
523             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
524             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
525             [[clang::fallthrough]];
526         case VK_API_VERSION_1_0:
527             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
528             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
529             break;
530         default:
531             ALOGE("Unknown API version[%u]", api_version);
532             break;
533     }
534
535     ext_names = extension_filter_.names;
536     ext_count = extension_filter_.name_count;
537
538     return VK_SUCCESS;
539 }
540
541 VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
542     if (is_instance_) {
543         return Hal::Device().EnumerateInstanceExtensionProperties(
544             nullptr, &count, nullptr);
545     } else {
546         const auto& driver = GetData(physical_dev_).driver;
547         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
548                                                          &count, nullptr);
549     }
550 }
551
552 VkResult CreateInfoWrapper::EnumerateExtensions(
553     uint32_t& count,
554     VkExtensionProperties* props) const {
555     if (is_instance_) {
556         return Hal::Device().EnumerateInstanceExtensionProperties(
557             nullptr, &count, props);
558     } else {
559         const auto& driver = GetData(physical_dev_).driver;
560         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
561                                                          &count, props);
562     }
563 }
564
565 VkResult CreateInfoWrapper::InitExtensionFilter() {
566     // query extension count
567     uint32_t count;
568     VkResult result = QueryExtensionCount(count);
569     if (result != VK_SUCCESS || count == 0)
570         return result;
571
572     auto& filter = extension_filter_;
573     filter.exts =
574         reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
575             allocator_.pUserData, sizeof(VkExtensionProperties) * count,
576             alignof(VkExtensionProperties),
577             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
578     if (!filter.exts)
579         return VK_ERROR_OUT_OF_HOST_MEMORY;
580
581     // enumerate extensions
582     result = EnumerateExtensions(count, filter.exts);
583     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
584         return result;
585
586     if (!count)
587         return VK_SUCCESS;
588
589     filter.ext_count = count;
590
591     // allocate name array
592     if (is_instance_) {
593         uint32_t enabled_ext_count = instance_info_.enabledExtensionCount;
594
595         // It requires enabling additional promoted extensions to downgrade api,
596         // so we reserve enough space here.
597         if (icd_api_version_ < loader_api_version_) {
598             enabled_ext_count += CountPromotedInstanceExtensions(
599                 icd_api_version_, loader_api_version_);
600         }
601
602         count = std::min(filter.ext_count, enabled_ext_count);
603     } else {
604         count = std::min(filter.ext_count, dev_info_.enabledExtensionCount);
605     }
606
607     if (!count)
608         return VK_SUCCESS;
609
610     filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
611         allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
612         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
613     if (!filter.names)
614         return VK_ERROR_OUT_OF_HOST_MEMORY;
615
616     return VK_SUCCESS;
617 }
618
619 void CreateInfoWrapper::FilterExtension(const char* name) {
620     auto& filter = extension_filter_;
621
622     ProcHook::Extension ext_bit = GetProcHookExtension(name);
623     if (is_instance_) {
624         switch (ext_bit) {
625             case ProcHook::KHR_android_surface:
626             case ProcHook::KHR_surface:
627             case ProcHook::EXT_swapchain_colorspace:
628             case ProcHook::KHR_get_surface_capabilities2:
629                 hook_extensions_.set(ext_bit);
630                 // return now as these extensions do not require HAL support
631                 return;
632             case ProcHook::EXT_debug_report:
633                 // both we and HAL can take part in
634                 hook_extensions_.set(ext_bit);
635                 break;
636             case ProcHook::KHR_get_physical_device_properties2:
637             case ProcHook::KHR_device_group_creation:
638             case ProcHook::KHR_external_memory_capabilities:
639             case ProcHook::KHR_external_semaphore_capabilities:
640             case ProcHook::KHR_external_fence_capabilities:
641             case ProcHook::EXTENSION_UNKNOWN:
642                 // Extensions we don't need to do anything about at this level
643                 break;
644
645             case ProcHook::KHR_bind_memory2:
646             case ProcHook::KHR_incremental_present:
647             case ProcHook::KHR_shared_presentable_image:
648             case ProcHook::KHR_swapchain:
649             case ProcHook::EXT_hdr_metadata:
650             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
651             case ProcHook::ANDROID_native_buffer:
652             case ProcHook::GOOGLE_display_timing:
653             case ProcHook::EXTENSION_CORE_1_0:
654             case ProcHook::EXTENSION_CORE_1_1:
655             case ProcHook::EXTENSION_CORE_1_2:
656             case ProcHook::EXTENSION_COUNT:
657                 // Device and meta extensions. If we ever get here it's a bug in
658                 // our code. But enumerating them lets us avoid having a default
659                 // case, and default hides other bugs.
660                 ALOGE(
661                     "CreateInfoWrapper::FilterExtension: invalid instance "
662                     "extension '%s'. FIX ME",
663                     name);
664                 return;
665
666             // Don't use a default case. Without it, -Wswitch will tell us
667             // at compile time if someone adds a new ProcHook extension but
668             // doesn't handle it above. That's a real bug that has
669             // not-immediately-obvious effects.
670             //
671             // default:
672             //     break;
673         }
674     } else {
675         switch (ext_bit) {
676             case ProcHook::KHR_swapchain:
677                 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
678                 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
679                 ext_bit = ProcHook::ANDROID_native_buffer;
680                 break;
681             case ProcHook::KHR_incremental_present:
682             case ProcHook::GOOGLE_display_timing:
683             case ProcHook::KHR_shared_presentable_image:
684                 hook_extensions_.set(ext_bit);
685                 // return now as these extensions do not require HAL support
686                 return;
687             case ProcHook::EXT_hdr_metadata:
688             case ProcHook::KHR_bind_memory2:
689                 hook_extensions_.set(ext_bit);
690                 break;
691             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
692             case ProcHook::EXTENSION_UNKNOWN:
693                 // Extensions we don't need to do anything about at this level
694                 break;
695
696             case ProcHook::KHR_android_surface:
697             case ProcHook::KHR_get_physical_device_properties2:
698             case ProcHook::KHR_device_group_creation:
699             case ProcHook::KHR_external_memory_capabilities:
700             case ProcHook::KHR_external_semaphore_capabilities:
701             case ProcHook::KHR_external_fence_capabilities:
702             case ProcHook::KHR_get_surface_capabilities2:
703             case ProcHook::KHR_surface:
704             case ProcHook::EXT_debug_report:
705             case ProcHook::EXT_swapchain_colorspace:
706             case ProcHook::ANDROID_native_buffer:
707             case ProcHook::EXTENSION_CORE_1_0:
708             case ProcHook::EXTENSION_CORE_1_1:
709             case ProcHook::EXTENSION_CORE_1_2:
710             case ProcHook::EXTENSION_COUNT:
711                 // Instance and meta extensions. If we ever get here it's a bug
712                 // in our code. But enumerating them lets us avoid having a
713                 // default case, and default hides other bugs.
714                 ALOGE(
715                     "CreateInfoWrapper::FilterExtension: invalid device "
716                     "extension '%s'. FIX ME",
717                     name);
718                 return;
719
720             // Don't use a default case. Without it, -Wswitch will tell us
721             // at compile time if someone adds a new ProcHook extension but
722             // doesn't handle it above. That's a real bug that has
723             // not-immediately-obvious effects.
724             //
725             // default:
726             //     break;
727         }
728     }
729
730     for (uint32_t i = 0; i < filter.ext_count; i++) {
731         const VkExtensionProperties& props = filter.exts[i];
732         // ignore unknown extensions
733         if (strcmp(name, props.extensionName) != 0)
734             continue;
735
736         filter.names[filter.name_count++] = name;
737         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
738             if (ext_bit == ProcHook::ANDROID_native_buffer)
739                 hook_extensions_.set(ProcHook::KHR_swapchain);
740
741             hal_extensions_.set(ext_bit);
742         }
743
744         break;
745     }
746 }
747
748 VKAPI_ATTR void* DefaultAllocate(void*,
749                                  size_t size,
750                                  size_t alignment,
751                                  VkSystemAllocationScope) {
752     void* ptr = nullptr;
753     // Vulkan requires 'alignment' to be a power of two, but posix_memalign
754     // additionally requires that it be at least sizeof(void*).
755     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
756     ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
757                     ret, ptr);
758     return ret == 0 ? ptr : nullptr;
759 }
760
761 VKAPI_ATTR void* DefaultReallocate(void*,
762                                    void* ptr,
763                                    size_t size,
764                                    size_t alignment,
765                                    VkSystemAllocationScope) {
766     if (size == 0) {
767         free(ptr);
768         return nullptr;
769     }
770
771     // TODO(b/143295633): Right now we never shrink allocations; if the new
772     // request is smaller than the existing chunk, we just continue using it.
773     // Right now the loader never reallocs, so this doesn't matter. If that
774     // changes, or if this code is copied into some other project, this should
775     // probably have a heuristic to allocate-copy-free when doing so will save
776     // "enough" space.
777     size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
778     if (size <= old_size)
779         return ptr;
780
781     void* new_ptr = nullptr;
782     if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
783         return nullptr;
784     if (ptr) {
785         memcpy(new_ptr, ptr, std::min(old_size, size));
786         free(ptr);
787     }
788     return new_ptr;
789 }
790
791 VKAPI_ATTR void DefaultFree(void*, void* ptr) {
792     ALOGD_CALLSTACK("Free: %p", ptr);
793     free(ptr);
794 }
795
796 InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
797     void* data_mem = allocator.pfnAllocation(
798         allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
799         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
800     if (!data_mem)
801         return nullptr;
802
803     return new (data_mem) InstanceData(allocator);
804 }
805
806 void FreeInstanceData(InstanceData* data,
807                       const VkAllocationCallbacks& allocator) {
808     data->~InstanceData();
809     allocator.pfnFree(allocator.pUserData, data);
810 }
811
812 DeviceData* AllocateDeviceData(
813     const VkAllocationCallbacks& allocator,
814     const DebugReportCallbackList& debug_report_callbacks) {
815     void* data_mem = allocator.pfnAllocation(
816         allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
817         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
818     if (!data_mem)
819         return nullptr;
820
821     return new (data_mem) DeviceData(allocator, debug_report_callbacks);
822 }
823
824 void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
825     data->~DeviceData();
826     allocator.pfnFree(allocator.pUserData, data);
827 }
828
829 }  // anonymous namespace
830
831 bool OpenHAL() {
832     return Hal::Open();
833 }
834
835 const VkAllocationCallbacks& GetDefaultAllocator() {
836     static const VkAllocationCallbacks kDefaultAllocCallbacks = {
837         .pUserData = nullptr,
838         .pfnAllocation = DefaultAllocate,
839         .pfnReallocation = DefaultReallocate,
840         .pfnFree = DefaultFree,
841     };
842
843     return kDefaultAllocCallbacks;
844 }
845
846 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
847     const ProcHook* hook = GetProcHook(pName);
848     if (!hook)
849         return Hal::Device().GetInstanceProcAddr(instance, pName);
850
851     if (!instance) {
852         if (hook->type == ProcHook::GLOBAL)
853             return hook->proc;
854
855         // v0 layers expect
856         //
857         //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
858         //
859         // to work.
860         if (strcmp(pName, "vkCreateDevice") == 0)
861             return hook->proc;
862
863         ALOGE(
864             "internal vkGetInstanceProcAddr called for %s without an instance",
865             pName);
866
867         return nullptr;
868     }
869
870     PFN_vkVoidFunction proc;
871
872     switch (hook->type) {
873         case ProcHook::INSTANCE:
874             proc = (GetData(instance).hook_extensions[hook->extension])
875                        ? hook->proc
876                        : nullptr;
877             break;
878         case ProcHook::DEVICE:
879             proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
880                        ? hook->proc
881                        : hook->checked_proc;
882             break;
883         default:
884             ALOGE(
885                 "internal vkGetInstanceProcAddr called for %s with an instance",
886                 pName);
887             proc = nullptr;
888             break;
889     }
890
891     return proc;
892 }
893
894 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
895     const ProcHook* hook = GetProcHook(pName);
896     if (!hook)
897         return GetData(device).driver.GetDeviceProcAddr(device, pName);
898
899     if (hook->type != ProcHook::DEVICE) {
900         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
901         return nullptr;
902     }
903
904     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
905                                                               : nullptr;
906 }
907
908 VkResult EnumerateInstanceExtensionProperties(
909     const char* pLayerName,
910     uint32_t* pPropertyCount,
911     VkExtensionProperties* pProperties) {
912     std::vector<VkExtensionProperties> loader_extensions;
913     loader_extensions.push_back({
914         VK_KHR_SURFACE_EXTENSION_NAME,
915         VK_KHR_SURFACE_SPEC_VERSION});
916     loader_extensions.push_back({
917         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
918         VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
919     loader_extensions.push_back({
920         VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
921         VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
922     loader_extensions.push_back({
923         VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
924         VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
925
926     static const VkExtensionProperties loader_debug_report_extension = {
927         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
928     };
929
930     // enumerate our extensions first
931     if (!pLayerName && pProperties) {
932         uint32_t count = std::min(
933             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
934
935         std::copy_n(loader_extensions.data(), count, pProperties);
936
937         if (count < loader_extensions.size()) {
938             *pPropertyCount = count;
939             return VK_INCOMPLETE;
940         }
941
942         pProperties += count;
943         *pPropertyCount -= count;
944
945         if (Hal::Get().GetDebugReportIndex() < 0) {
946             if (!*pPropertyCount) {
947                 *pPropertyCount = count;
948                 return VK_INCOMPLETE;
949             }
950
951             pProperties[0] = loader_debug_report_extension;
952             pProperties += 1;
953             *pPropertyCount -= 1;
954         }
955     }
956
957     ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
958     VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
959         pLayerName, pPropertyCount, pProperties);
960     ATRACE_END();
961
962     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
963         int idx = Hal::Get().GetDebugReportIndex();
964         if (idx < 0) {
965             *pPropertyCount += 1;
966         } else if (pProperties &&
967                    static_cast<uint32_t>(idx) < *pPropertyCount) {
968             pProperties[idx].specVersion =
969                 std::min(pProperties[idx].specVersion,
970                          loader_debug_report_extension.specVersion);
971         }
972
973         *pPropertyCount += loader_extensions.size();
974     }
975
976     return result;
977 }
978
979 void QueryPresentationProperties(
980     VkPhysicalDevice physicalDevice,
981     VkPhysicalDevicePresentationPropertiesANDROID* presentation_properties) {
982     // Request the android-specific presentation properties via GPDP2
983     VkPhysicalDeviceProperties2 properties = {
984         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
985         presentation_properties,
986         {},
987     };
988
989 #pragma clang diagnostic push
990 #pragma clang diagnostic ignored "-Wold-style-cast"
991     presentation_properties->sType =
992         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
993 #pragma clang diagnostic pop
994     presentation_properties->pNext = nullptr;
995     presentation_properties->sharedImage = VK_FALSE;
996
997     GetPhysicalDeviceProperties2(physicalDevice, &properties);
998 }
999
1000 VkResult EnumerateDeviceExtensionProperties(
1001     VkPhysicalDevice physicalDevice,
1002     const char* pLayerName,
1003     uint32_t* pPropertyCount,
1004     VkExtensionProperties* pProperties) {
1005     const InstanceData& data = GetData(physicalDevice);
1006     // extensions that are unconditionally exposed by the loader
1007     std::vector<VkExtensionProperties> loader_extensions;
1008     loader_extensions.push_back({
1009         VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
1010         VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
1011
1012     bool hdrBoardConfig = android::sysprop::has_HDR_display(false);
1013     if (hdrBoardConfig) {
1014         loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
1015                                      VK_EXT_HDR_METADATA_SPEC_VERSION});
1016     }
1017
1018     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
1019     QueryPresentationProperties(physicalDevice, &presentation_properties);
1020     if (presentation_properties.sharedImage) {
1021         loader_extensions.push_back({
1022             VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
1023             VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
1024     }
1025
1026     // conditionally add VK_GOOGLE_display_timing if present timestamps are
1027     // supported by the driver:
1028     if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
1029         loader_extensions.push_back({
1030                 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
1031                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
1032     }
1033
1034     // enumerate our extensions first
1035     if (!pLayerName && pProperties) {
1036         uint32_t count = std::min(
1037             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
1038
1039         std::copy_n(loader_extensions.data(), count, pProperties);
1040
1041         if (count < loader_extensions.size()) {
1042             *pPropertyCount = count;
1043             return VK_INCOMPLETE;
1044         }
1045
1046         pProperties += count;
1047         *pPropertyCount -= count;
1048     }
1049
1050     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1051     VkResult result = data.driver.EnumerateDeviceExtensionProperties(
1052         physicalDevice, pLayerName, pPropertyCount, pProperties);
1053     ATRACE_END();
1054
1055     if (pProperties) {
1056         // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1057         for (uint32_t i = 0; i < *pPropertyCount; i++) {
1058             auto& prop = pProperties[i];
1059
1060             if (strcmp(prop.extensionName,
1061                        VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1062                 continue;
1063
1064             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1065                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
1066
1067             if (prop.specVersion >= 8) {
1068                 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1069             } else {
1070                 prop.specVersion = 68;
1071             }
1072         }
1073     }
1074
1075     // restore loader extension count
1076     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1077         *pPropertyCount += loader_extensions.size();
1078     }
1079
1080     return result;
1081 }
1082
1083 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1084                         const VkAllocationCallbacks* pAllocator,
1085                         VkInstance* pInstance) {
1086     const VkAllocationCallbacks& data_allocator =
1087         (pAllocator) ? *pAllocator : GetDefaultAllocator();
1088
1089     VkResult result = VK_SUCCESS;
1090     uint32_t icd_api_version = VK_API_VERSION_1_0;
1091     PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1092         reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
1093             Hal::Device().GetInstanceProcAddr(nullptr,
1094                                               "vkEnumerateInstanceVersion"));
1095     if (pfn_enumerate_instance_version) {
1096         ATRACE_BEGIN("pfn_enumerate_instance_version");
1097         result = (*pfn_enumerate_instance_version)(&icd_api_version);
1098         ATRACE_END();
1099         if (result != VK_SUCCESS)
1100             return result;
1101
1102         icd_api_version ^= VK_VERSION_PATCH(icd_api_version);
1103     }
1104
1105     CreateInfoWrapper wrapper(*pCreateInfo, icd_api_version, data_allocator);
1106     result = wrapper.Validate();
1107     if (result != VK_SUCCESS)
1108         return result;
1109
1110     InstanceData* data = AllocateInstanceData(data_allocator);
1111     if (!data)
1112         return VK_ERROR_OUT_OF_HOST_MEMORY;
1113
1114     data->hook_extensions |= wrapper.GetHookExtensions();
1115
1116     // call into the driver
1117     VkInstance instance;
1118     ATRACE_BEGIN("driver.CreateInstance");
1119     result = Hal::Device().CreateInstance(
1120         static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1121         &instance);
1122     ATRACE_END();
1123     if (result != VK_SUCCESS) {
1124         FreeInstanceData(data, data_allocator);
1125         return result;
1126     }
1127
1128     // initialize InstanceDriverTable
1129     if (!SetData(instance, *data) ||
1130         !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
1131                          wrapper.GetHalExtensions())) {
1132         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
1133             Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
1134         if (data->driver.DestroyInstance)
1135             data->driver.DestroyInstance(instance, pAllocator);
1136
1137         FreeInstanceData(data, data_allocator);
1138
1139         return VK_ERROR_INCOMPATIBLE_DRIVER;
1140     }
1141
1142     data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
1143         Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
1144     if (!data->get_device_proc_addr) {
1145         data->driver.DestroyInstance(instance, pAllocator);
1146         FreeInstanceData(data, data_allocator);
1147
1148         return VK_ERROR_INCOMPATIBLE_DRIVER;
1149     }
1150
1151     *pInstance = instance;
1152
1153     return VK_SUCCESS;
1154 }
1155
1156 void DestroyInstance(VkInstance instance,
1157                      const VkAllocationCallbacks* pAllocator) {
1158     InstanceData& data = GetData(instance);
1159     data.driver.DestroyInstance(instance, pAllocator);
1160
1161     VkAllocationCallbacks local_allocator;
1162     if (!pAllocator) {
1163         local_allocator = data.allocator;
1164         pAllocator = &local_allocator;
1165     }
1166
1167     FreeInstanceData(&data, *pAllocator);
1168 }
1169
1170 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1171                       const VkDeviceCreateInfo* pCreateInfo,
1172                       const VkAllocationCallbacks* pAllocator,
1173                       VkDevice* pDevice) {
1174     const InstanceData& instance_data = GetData(physicalDevice);
1175     const VkAllocationCallbacks& data_allocator =
1176         (pAllocator) ? *pAllocator : instance_data.allocator;
1177
1178     VkPhysicalDeviceProperties properties;
1179     ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1180     instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1181                                                      &properties);
1182     ATRACE_END();
1183
1184     CreateInfoWrapper wrapper(
1185         physicalDevice, *pCreateInfo,
1186         properties.apiVersion ^ VK_VERSION_PATCH(properties.apiVersion),
1187         data_allocator);
1188     VkResult result = wrapper.Validate();
1189     if (result != VK_SUCCESS)
1190         return result;
1191
1192     ATRACE_BEGIN("AllocateDeviceData");
1193     DeviceData* data = AllocateDeviceData(data_allocator,
1194                                           instance_data.debug_report_callbacks);
1195     ATRACE_END();
1196     if (!data)
1197         return VK_ERROR_OUT_OF_HOST_MEMORY;
1198
1199     data->hook_extensions |= wrapper.GetHookExtensions();
1200
1201     // call into the driver
1202     VkDevice dev;
1203     ATRACE_BEGIN("driver.CreateDevice");
1204     result = instance_data.driver.CreateDevice(
1205         physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1206         pAllocator, &dev);
1207     ATRACE_END();
1208     if (result != VK_SUCCESS) {
1209         FreeDeviceData(data, data_allocator);
1210         return result;
1211     }
1212
1213     // initialize DeviceDriverTable
1214     if (!SetData(dev, *data) ||
1215         !InitDriverTable(dev, instance_data.get_device_proc_addr,
1216                          wrapper.GetHalExtensions())) {
1217         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1218             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1219         if (data->driver.DestroyDevice)
1220             data->driver.DestroyDevice(dev, pAllocator);
1221
1222         FreeDeviceData(data, data_allocator);
1223
1224         return VK_ERROR_INCOMPATIBLE_DRIVER;
1225     }
1226
1227     // sanity check ANDROID_native_buffer implementation, whose set of
1228     // entrypoints varies according to the spec version.
1229     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1230         !data->driver.GetSwapchainGrallocUsageANDROID &&
1231         !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1232         ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1233               " must expose at least one of "
1234               "vkGetSwapchainGrallocUsageANDROID or "
1235               "vkGetSwapchainGrallocUsage2ANDROID");
1236
1237         data->driver.DestroyDevice(dev, pAllocator);
1238         FreeDeviceData(data, data_allocator);
1239
1240         return VK_ERROR_INCOMPATIBLE_DRIVER;
1241     }
1242
1243     if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1244         // Log that the app is hitting software Vulkan implementation
1245         android::GraphicsEnv::getInstance().setTargetStats(
1246             android::GpuStatsInfo::Stats::CPU_VULKAN_IN_USE);
1247     }
1248
1249     data->driver_device = dev;
1250
1251     *pDevice = dev;
1252
1253     return VK_SUCCESS;
1254 }
1255
1256 void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1257     DeviceData& data = GetData(device);
1258     data.driver.DestroyDevice(device, pAllocator);
1259
1260     VkAllocationCallbacks local_allocator;
1261     if (!pAllocator) {
1262         local_allocator = data.allocator;
1263         pAllocator = &local_allocator;
1264     }
1265
1266     FreeDeviceData(&data, *pAllocator);
1267 }
1268
1269 VkResult EnumeratePhysicalDevices(VkInstance instance,
1270                                   uint32_t* pPhysicalDeviceCount,
1271                                   VkPhysicalDevice* pPhysicalDevices) {
1272     ATRACE_CALL();
1273
1274     const auto& data = GetData(instance);
1275
1276     VkResult result = data.driver.EnumeratePhysicalDevices(
1277         instance, pPhysicalDeviceCount, pPhysicalDevices);
1278     if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1279         for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1280             SetData(pPhysicalDevices[i], data);
1281     }
1282
1283     return result;
1284 }
1285
1286 VkResult EnumeratePhysicalDeviceGroups(
1287     VkInstance instance,
1288     uint32_t* pPhysicalDeviceGroupCount,
1289     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
1290     ATRACE_CALL();
1291
1292     VkResult result = VK_SUCCESS;
1293     const auto& data = GetData(instance);
1294
1295     if (!data.driver.EnumeratePhysicalDeviceGroups &&
1296         !data.driver.EnumeratePhysicalDeviceGroupsKHR) {
1297         uint32_t device_count = 0;
1298         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1299         if (result < 0)
1300             return result;
1301
1302         if (!pPhysicalDeviceGroupProperties) {
1303             *pPhysicalDeviceGroupCount = device_count;
1304             return result;
1305         }
1306
1307         if (!device_count) {
1308             *pPhysicalDeviceGroupCount = 0;
1309             return result;
1310         }
1311         device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1312         if (!device_count)
1313             return VK_INCOMPLETE;
1314
1315         std::vector<VkPhysicalDevice> devices(device_count);
1316         *pPhysicalDeviceGroupCount = device_count;
1317         result =
1318             EnumeratePhysicalDevices(instance, &device_count, devices.data());
1319         if (result < 0)
1320             return result;
1321
1322         for (uint32_t i = 0; i < device_count; ++i) {
1323             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1324             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1325             pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1326         }
1327     } else {
1328         if (data.driver.EnumeratePhysicalDeviceGroups) {
1329             result = data.driver.EnumeratePhysicalDeviceGroups(
1330                 instance, pPhysicalDeviceGroupCount,
1331                 pPhysicalDeviceGroupProperties);
1332         } else {
1333             result = data.driver.EnumeratePhysicalDeviceGroupsKHR(
1334                 instance, pPhysicalDeviceGroupCount,
1335                 pPhysicalDeviceGroupProperties);
1336         }
1337         if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1338             *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1339             for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1340                 for (uint32_t j = 0;
1341                      j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1342                      j++) {
1343                     SetData(
1344                         pPhysicalDeviceGroupProperties[i].physicalDevices[j],
1345                         data);
1346                 }
1347             }
1348         }
1349     }
1350
1351     return result;
1352 }
1353
1354 void GetDeviceQueue(VkDevice device,
1355                     uint32_t queueFamilyIndex,
1356                     uint32_t queueIndex,
1357                     VkQueue* pQueue) {
1358     ATRACE_CALL();
1359
1360     const auto& data = GetData(device);
1361
1362     data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1363     SetData(*pQueue, data);
1364 }
1365
1366 void GetDeviceQueue2(VkDevice device,
1367                      const VkDeviceQueueInfo2* pQueueInfo,
1368                      VkQueue* pQueue) {
1369     ATRACE_CALL();
1370
1371     const auto& data = GetData(device);
1372
1373     data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
1374     if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
1375 }
1376
1377 VkResult AllocateCommandBuffers(
1378     VkDevice device,
1379     const VkCommandBufferAllocateInfo* pAllocateInfo,
1380     VkCommandBuffer* pCommandBuffers) {
1381     ATRACE_CALL();
1382
1383     const auto& data = GetData(device);
1384
1385     VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1386                                                          pCommandBuffers);
1387     if (result == VK_SUCCESS) {
1388         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1389             SetData(pCommandBuffers[i], data);
1390     }
1391
1392     return result;
1393 }
1394
1395 VkResult QueueSubmit(VkQueue queue,
1396                      uint32_t submitCount,
1397                      const VkSubmitInfo* pSubmits,
1398                      VkFence fence) {
1399     ATRACE_CALL();
1400
1401     const auto& data = GetData(queue);
1402
1403     return data.driver.QueueSubmit(queue, submitCount, pSubmits, fence);
1404 }
1405
1406 void GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
1407                                 VkPhysicalDeviceFeatures2* pFeatures) {
1408     ATRACE_CALL();
1409
1410     const auto& driver = GetData(physicalDevice).driver;
1411
1412     if (driver.GetPhysicalDeviceFeatures2) {
1413         driver.GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
1414         return;
1415     }
1416
1417     driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
1418 }
1419
1420 void GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1421                                   VkPhysicalDeviceProperties2* pProperties) {
1422     ATRACE_CALL();
1423
1424     const auto& driver = GetData(physicalDevice).driver;
1425
1426     if (driver.GetPhysicalDeviceProperties2) {
1427         driver.GetPhysicalDeviceProperties2(physicalDevice, pProperties);
1428         return;
1429     }
1430
1431     driver.GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
1432 }
1433
1434 void GetPhysicalDeviceFormatProperties2(
1435     VkPhysicalDevice physicalDevice,
1436     VkFormat format,
1437     VkFormatProperties2* pFormatProperties) {
1438     ATRACE_CALL();
1439
1440     const auto& driver = GetData(physicalDevice).driver;
1441
1442     if (driver.GetPhysicalDeviceFormatProperties2) {
1443         driver.GetPhysicalDeviceFormatProperties2(physicalDevice, format,
1444                                                   pFormatProperties);
1445         return;
1446     }
1447
1448     driver.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format,
1449                                                  pFormatProperties);
1450 }
1451
1452 VkResult GetPhysicalDeviceImageFormatProperties2(
1453     VkPhysicalDevice physicalDevice,
1454     const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1455     VkImageFormatProperties2* pImageFormatProperties) {
1456     ATRACE_CALL();
1457
1458     const auto& driver = GetData(physicalDevice).driver;
1459
1460     if (driver.GetPhysicalDeviceImageFormatProperties2) {
1461         return driver.GetPhysicalDeviceImageFormatProperties2(
1462             physicalDevice, pImageFormatInfo, pImageFormatProperties);
1463     }
1464
1465     return driver.GetPhysicalDeviceImageFormatProperties2KHR(
1466         physicalDevice, pImageFormatInfo, pImageFormatProperties);
1467 }
1468
1469 void GetPhysicalDeviceQueueFamilyProperties2(
1470     VkPhysicalDevice physicalDevice,
1471     uint32_t* pQueueFamilyPropertyCount,
1472     VkQueueFamilyProperties2* pQueueFamilyProperties) {
1473     ATRACE_CALL();
1474
1475     const auto& driver = GetData(physicalDevice).driver;
1476
1477     if (driver.GetPhysicalDeviceQueueFamilyProperties2) {
1478         driver.GetPhysicalDeviceQueueFamilyProperties2(
1479             physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1480         return;
1481     }
1482
1483     driver.GetPhysicalDeviceQueueFamilyProperties2KHR(
1484         physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1485 }
1486
1487 void GetPhysicalDeviceMemoryProperties2(
1488     VkPhysicalDevice physicalDevice,
1489     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
1490     ATRACE_CALL();
1491
1492     const auto& driver = GetData(physicalDevice).driver;
1493
1494     if (driver.GetPhysicalDeviceMemoryProperties2) {
1495         driver.GetPhysicalDeviceMemoryProperties2(physicalDevice,
1496                                                   pMemoryProperties);
1497         return;
1498     }
1499
1500     driver.GetPhysicalDeviceMemoryProperties2KHR(physicalDevice,
1501                                                  pMemoryProperties);
1502 }
1503
1504 void GetPhysicalDeviceSparseImageFormatProperties2(
1505     VkPhysicalDevice physicalDevice,
1506     const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
1507     uint32_t* pPropertyCount,
1508     VkSparseImageFormatProperties2* pProperties) {
1509     ATRACE_CALL();
1510
1511     const auto& driver = GetData(physicalDevice).driver;
1512
1513     if (driver.GetPhysicalDeviceSparseImageFormatProperties2) {
1514         driver.GetPhysicalDeviceSparseImageFormatProperties2(
1515             physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1516         return;
1517     }
1518
1519     driver.GetPhysicalDeviceSparseImageFormatProperties2KHR(
1520         physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1521 }
1522
1523 void GetPhysicalDeviceExternalBufferProperties(
1524     VkPhysicalDevice physicalDevice,
1525     const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
1526     VkExternalBufferProperties* pExternalBufferProperties) {
1527     ATRACE_CALL();
1528
1529     const auto& driver = GetData(physicalDevice).driver;
1530
1531     if (driver.GetPhysicalDeviceExternalBufferProperties) {
1532         driver.GetPhysicalDeviceExternalBufferProperties(
1533             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1534         return;
1535     }
1536
1537     if (driver.GetPhysicalDeviceExternalBufferPropertiesKHR) {
1538         driver.GetPhysicalDeviceExternalBufferPropertiesKHR(
1539             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1540         return;
1541     }
1542
1543     memset(&pExternalBufferProperties->externalMemoryProperties, 0,
1544            sizeof(VkExternalMemoryProperties));
1545 }
1546
1547 void GetPhysicalDeviceExternalSemaphoreProperties(
1548     VkPhysicalDevice physicalDevice,
1549     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
1550     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
1551     ATRACE_CALL();
1552
1553     const auto& driver = GetData(physicalDevice).driver;
1554
1555     if (driver.GetPhysicalDeviceExternalSemaphoreProperties) {
1556         driver.GetPhysicalDeviceExternalSemaphoreProperties(
1557             physicalDevice, pExternalSemaphoreInfo,
1558             pExternalSemaphoreProperties);
1559         return;
1560     }
1561
1562     if (driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR) {
1563         driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
1564             physicalDevice, pExternalSemaphoreInfo,
1565             pExternalSemaphoreProperties);
1566         return;
1567     }
1568
1569     pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
1570     pExternalSemaphoreProperties->compatibleHandleTypes = 0;
1571     pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
1572 }
1573
1574 void GetPhysicalDeviceExternalFenceProperties(
1575     VkPhysicalDevice physicalDevice,
1576     const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
1577     VkExternalFenceProperties* pExternalFenceProperties) {
1578     ATRACE_CALL();
1579
1580     const auto& driver = GetData(physicalDevice).driver;
1581
1582     if (driver.GetPhysicalDeviceExternalFenceProperties) {
1583         driver.GetPhysicalDeviceExternalFenceProperties(
1584             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
1585         return;
1586     }
1587
1588     if (driver.GetPhysicalDeviceExternalFencePropertiesKHR) {
1589         driver.GetPhysicalDeviceExternalFencePropertiesKHR(
1590             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
1591         return;
1592     }
1593
1594     pExternalFenceProperties->exportFromImportedHandleTypes = 0;
1595     pExternalFenceProperties->compatibleHandleTypes = 0;
1596     pExternalFenceProperties->externalFenceFeatures = 0;
1597 }
1598
1599 }  // namespace driver
1600 }  // namespace vulkan