xref: /aosp_15_r20/frameworks/native/vulkan/libvulkan/driver.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 <com_android_graphics_libvulkan_flags.h>
45 #include "stubhal.h"
46 
47 using namespace android::hardware::configstore;
48 using namespace android::hardware::configstore::V1_0;
49 using namespace com::android::graphics::libvulkan;
50 
51 extern "C" android_namespace_t* android_get_exported_namespace(const char*);
52 
53 // #define ENABLE_ALLOC_CALLSTACKS 1
54 #if ENABLE_ALLOC_CALLSTACKS
55 #include <utils/CallStack.h>
56 #define ALOGD_CALLSTACK(...)                             \
57     do {                                                 \
58         ALOGD(__VA_ARGS__);                              \
59         android::CallStack callstack;                    \
60         callstack.update();                              \
61         callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, "  "); \
62     } while (false)
63 #else
64 #define ALOGD_CALLSTACK(...) \
65     do {                     \
66     } while (false)
67 #endif
68 
69 namespace vulkan {
70 namespace driver {
71 
72 namespace {
73 
74 class Hal {
75    public:
76     static bool Open();
77 
Get()78     static const Hal& Get() { return hal_; }
Device()79     static const hwvulkan_device_t& Device() { return *Get().dev_; }
80 
GetDebugReportIndex() const81     int GetDebugReportIndex() const { return debug_report_index_; }
82 
83    private:
Hal()84     Hal() : dev_(nullptr), debug_report_index_(-1) {}
85     Hal(const Hal&) = delete;
86     Hal& operator=(const Hal&) = delete;
87 
88     bool ShouldUnloadBuiltinDriver();
89     void UnloadBuiltinDriver();
90     bool InitDebugReportIndex();
91 
92     static Hal hal_;
93 
94     const hwvulkan_device_t* dev_;
95     int debug_report_index_;
96 };
97 
98 class CreateInfoWrapper {
99    public:
100     CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
101                       uint32_t icd_api_version,
102                       const VkAllocationCallbacks& allocator);
103     CreateInfoWrapper(VkPhysicalDevice physical_dev,
104                       const VkDeviceCreateInfo& create_info,
105                       uint32_t icd_api_version,
106                       const VkAllocationCallbacks& allocator);
107     ~CreateInfoWrapper();
108 
109     VkResult Validate();
110 
111     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
112     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
113 
114     explicit operator const VkInstanceCreateInfo*() const;
115     explicit operator const VkDeviceCreateInfo*() const;
116 
117    private:
118     struct ExtensionFilter {
119         VkExtensionProperties* exts;
120         uint32_t ext_count;
121 
122         const char** names;
123         uint32_t name_count;
ExtensionFiltervulkan::driver::__anonc4de0b6f0111::CreateInfoWrapper::ExtensionFilter124         ExtensionFilter()
125             : exts(nullptr), ext_count(0), names(nullptr), name_count(0) {}
126     };
127 
128     VkResult SanitizeApiVersion();
129     VkResult SanitizePNext();
130     VkResult SanitizeLayers();
131     VkResult SanitizeExtensions();
132 
133     VkResult QueryExtensionCount(uint32_t& count) const;
134     VkResult EnumerateExtensions(uint32_t& count,
135                                  VkExtensionProperties* props) const;
136     VkResult InitExtensionFilter();
137     void FilterExtension(const char* name);
138 
139     const bool is_instance_;
140     const VkAllocationCallbacks& allocator_;
141     const uint32_t loader_api_version_;
142     const uint32_t icd_api_version_;
143 
144     VkPhysicalDevice physical_dev_;
145 
146     union {
147         VkInstanceCreateInfo instance_info_;
148         VkDeviceCreateInfo dev_info_;
149     };
150 
151     VkApplicationInfo application_info_;
152 
153     ExtensionFilter extension_filter_;
154 
155     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
156     std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
157 };
158 
159 Hal Hal::hal_;
160 
161 const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
162     "ro.hardware.vulkan",
163     "ro.board.platform",
164 }};
165 constexpr int LIB_DL_FLAGS = RTLD_LOCAL | RTLD_NOW;
166 constexpr char RO_VULKAN_APEX_PROPERTY[] = "ro.vulkan.apex";
167 
168 // LoadDriver returns:
169 // * 0 when succeed, or
170 // * -ENOENT when fail to open binary libraries, or
171 // * -EINVAL when fail to find HAL_MODULE_INFO_SYM_AS_STR or
172 //   HWVULKAN_HARDWARE_MODULE_ID in the library.
LoadDriver(android_namespace_t * library_namespace,const char * ns_name,const hwvulkan_module_t ** module)173 int LoadDriver(android_namespace_t* library_namespace,
174                const char* ns_name,
175                const hwvulkan_module_t** module) {
176     ATRACE_CALL();
177 
178     void* so = nullptr;
179     for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
180         std::string lib_name = android::base::GetProperty(key, "");
181         if (lib_name.empty())
182             continue;
183 
184         lib_name = "vulkan." + lib_name + ".so";
185         if (library_namespace) {
186             // load updated driver
187             const android_dlextinfo dlextinfo = {
188                 .flags = ANDROID_DLEXT_USE_NAMESPACE,
189                 .library_namespace = library_namespace,
190             };
191             so = android_dlopen_ext(lib_name.c_str(), LIB_DL_FLAGS, &dlextinfo);
192             if (!so) {
193                 ALOGE("Could not load %s from %s namespace: %s.",
194                       lib_name.c_str(), ns_name, dlerror());
195             }
196         } else {
197             // load built-in driver
198             so = android_load_sphal_library(lib_name.c_str(), LIB_DL_FLAGS);
199         }
200         if (so)
201             break;
202     }
203     if (!so)
204         return -ENOENT;
205 
206     auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
207     if (!hmi) {
208         ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
209         dlclose(so);
210         return -EINVAL;
211     }
212     if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
213         ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
214         dlclose(so);
215         return -EINVAL;
216     }
217     hmi->dso = so;
218     *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
219     return 0;
220 }
221 
LoadDriverFromApex(const hwvulkan_module_t ** module)222 int LoadDriverFromApex(const hwvulkan_module_t** module) {
223     ATRACE_CALL();
224 
225     auto apex_name = android::base::GetProperty(RO_VULKAN_APEX_PROPERTY, "");
226     if (apex_name == "") {
227         return -ENOENT;
228     }
229     // Get linker namespace for Vulkan APEX
230     std::replace(apex_name.begin(), apex_name.end(), '.', '_');
231     auto ns = android_get_exported_namespace(apex_name.c_str());
232     if (!ns) {
233         return -ENOENT;
234     }
235     android::GraphicsEnv::getInstance().setDriverToLoad(
236         android::GpuStatsInfo::Driver::VULKAN);
237     return LoadDriver(ns, apex_name.c_str(), module);
238 }
239 
LoadBuiltinDriver(const hwvulkan_module_t ** module)240 int LoadBuiltinDriver(const hwvulkan_module_t** module) {
241     ATRACE_CALL();
242 
243     android::GraphicsEnv::getInstance().setDriverToLoad(
244         android::GpuStatsInfo::Driver::VULKAN);
245     return LoadDriver(nullptr, nullptr, module);
246 }
247 
LoadUpdatedDriver(const hwvulkan_module_t ** module)248 int LoadUpdatedDriver(const hwvulkan_module_t** module) {
249     ATRACE_CALL();
250 
251     auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
252     if (!ns)
253         return -ENOENT;
254     android::GraphicsEnv::getInstance().setDriverToLoad(
255         android::GpuStatsInfo::Driver::VULKAN_UPDATED);
256     int result = LoadDriver(ns, "updatable gfx driver", module);
257     if (result != 0) {
258         LOG_ALWAYS_FATAL(
259             "couldn't find an updated Vulkan implementation from %s",
260             android::GraphicsEnv::getInstance().getDriverPath().c_str());
261     }
262     return result;
263 }
264 
Open()265 bool Hal::Open() {
266     ATRACE_CALL();
267 
268     const nsecs_t openTime = systemTime();
269 
270     if (hal_.ShouldUnloadBuiltinDriver()) {
271         hal_.UnloadBuiltinDriver();
272     }
273 
274     if (hal_.dev_)
275         return true;
276 
277     // Use a stub device unless we successfully open a real HAL device.
278     hal_.dev_ = &stubhal::kDevice;
279 
280     int result;
281     const hwvulkan_module_t* module = nullptr;
282 
283     result = LoadUpdatedDriver(&module);
284     if (result == -ENOENT) {
285         result = LoadDriverFromApex(&module);
286     }
287     if (result == -ENOENT) {
288         result = LoadBuiltinDriver(&module);
289     }
290     if (result != 0) {
291         android::GraphicsEnv::getInstance().setDriverLoaded(
292             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
293         ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
294         return true;
295     }
296 
297 
298     hwvulkan_device_t* device;
299     ATRACE_BEGIN("hwvulkan module open");
300     result =
301         module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
302                                      reinterpret_cast<hw_device_t**>(&device));
303     ATRACE_END();
304     if (result != 0) {
305         android::GraphicsEnv::getInstance().setDriverLoaded(
306             android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
307         // Any device with a Vulkan HAL should be able to open the device.
308         ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
309               result);
310         return false;
311     }
312 
313     hal_.dev_ = device;
314 
315     hal_.InitDebugReportIndex();
316 
317     android::GraphicsEnv::getInstance().setDriverLoaded(
318         android::GpuStatsInfo::Api::API_VK, true, systemTime() - openTime);
319 
320     return true;
321 }
322 
ShouldUnloadBuiltinDriver()323 bool Hal::ShouldUnloadBuiltinDriver() {
324     // Should not unload since the driver was not loaded
325     if (!hal_.dev_)
326         return false;
327 
328     // Should not unload if stubhal is used on the device
329     if (hal_.dev_ == &stubhal::kDevice)
330         return false;
331 
332     // Unload the driver if updated driver is chosen
333     if (android::GraphicsEnv::getInstance().getDriverNamespace())
334         return true;
335 
336     return false;
337 }
338 
UnloadBuiltinDriver()339 void Hal::UnloadBuiltinDriver() {
340     ATRACE_CALL();
341 
342     ALOGD("Unload builtin Vulkan driver.");
343 
344     if (hal_.dev_->common.close != nullptr)
345     {
346         // Close the opened device
347         int err = hal_.dev_->common.close(
348             const_cast<struct hw_device_t*>(&hal_.dev_->common));
349         ALOG_ASSERT(!err, "hw_device_t::close() failed.");
350     }
351 
352     // Close the opened shared library in the hw_module_t
353     android_unload_sphal_library(hal_.dev_->common.module->dso);
354 
355     hal_.dev_ = nullptr;
356     hal_.debug_report_index_ = -1;
357 }
358 
InitDebugReportIndex()359 bool Hal::InitDebugReportIndex() {
360     ATRACE_CALL();
361 
362     uint32_t count;
363     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
364         VK_SUCCESS) {
365         ALOGE("failed to get HAL instance extension count");
366         return false;
367     }
368 
369     VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
370         malloc(sizeof(VkExtensionProperties) * count));
371     if (!exts) {
372         ALOGE("failed to allocate HAL instance extension array");
373         return false;
374     }
375 
376     if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
377         VK_SUCCESS) {
378         ALOGE("failed to enumerate HAL instance extensions");
379         free(exts);
380         return false;
381     }
382 
383     for (uint32_t i = 0; i < count; i++) {
384         if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
385             0) {
386             debug_report_index_ = static_cast<int>(i);
387             break;
388         }
389     }
390 
391     free(exts);
392 
393     return true;
394 }
395 
CreateInfoWrapper(const VkInstanceCreateInfo & create_info,uint32_t icd_api_version,const VkAllocationCallbacks & allocator)396 CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
397                                      uint32_t icd_api_version,
398                                      const VkAllocationCallbacks& allocator)
399     : is_instance_(true),
400       allocator_(allocator),
401       loader_api_version_(flags::vulkan_1_4_instance_api() ? VK_API_VERSION_1_4 : VK_API_VERSION_1_3),
402       icd_api_version_(icd_api_version),
403       physical_dev_(VK_NULL_HANDLE),
404       instance_info_(create_info),
405       extension_filter_() {}
406 
CreateInfoWrapper(VkPhysicalDevice physical_dev,const VkDeviceCreateInfo & create_info,uint32_t icd_api_version,const VkAllocationCallbacks & allocator)407 CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
408                                      const VkDeviceCreateInfo& create_info,
409                                      uint32_t icd_api_version,
410                                      const VkAllocationCallbacks& allocator)
411     : is_instance_(false),
412       allocator_(allocator),
413       loader_api_version_(flags::vulkan_1_4_instance_api() ? VK_API_VERSION_1_4 : VK_API_VERSION_1_3),
414       icd_api_version_(icd_api_version),
415       physical_dev_(physical_dev),
416       dev_info_(create_info),
417       extension_filter_() {}
418 
~CreateInfoWrapper()419 CreateInfoWrapper::~CreateInfoWrapper() {
420     allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
421     allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
422 }
423 
Validate()424 VkResult CreateInfoWrapper::Validate() {
425     VkResult result = SanitizeApiVersion();
426     if (result == VK_SUCCESS)
427         result = SanitizePNext();
428     if (result == VK_SUCCESS)
429         result = SanitizeLayers();
430     if (result == VK_SUCCESS)
431         result = SanitizeExtensions();
432 
433     return result;
434 }
435 
436 const std::bitset<ProcHook::EXTENSION_COUNT>&
GetHookExtensions() const437 CreateInfoWrapper::GetHookExtensions() const {
438     return hook_extensions_;
439 }
440 
441 const std::bitset<ProcHook::EXTENSION_COUNT>&
GetHalExtensions() const442 CreateInfoWrapper::GetHalExtensions() const {
443     return hal_extensions_;
444 }
445 
operator const VkInstanceCreateInfo*() const446 CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
447     return &instance_info_;
448 }
449 
operator const VkDeviceCreateInfo*() const450 CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
451     return &dev_info_;
452 }
453 
SanitizeApiVersion()454 VkResult CreateInfoWrapper::SanitizeApiVersion() {
455     if (!is_instance_ || !instance_info_.pApplicationInfo)
456         return VK_SUCCESS;
457 
458     if (icd_api_version_ > VK_API_VERSION_1_0 ||
459         instance_info_.pApplicationInfo->apiVersion < VK_API_VERSION_1_1)
460         return VK_SUCCESS;
461 
462     // override apiVersion to avoid error return from 1.0 icd
463     application_info_ = *instance_info_.pApplicationInfo;
464     application_info_.apiVersion = VK_API_VERSION_1_0;
465     instance_info_.pApplicationInfo = &application_info_;
466 
467     return VK_SUCCESS;
468 }
469 
SanitizePNext()470 VkResult CreateInfoWrapper::SanitizePNext() {
471     const struct StructHeader {
472         VkStructureType type;
473         const void* next;
474     } * header;
475 
476     if (is_instance_) {
477         header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
478 
479         // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
480         while (header &&
481                header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
482             header = reinterpret_cast<const StructHeader*>(header->next);
483 
484         instance_info_.pNext = header;
485     } else {
486         header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
487 
488         // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
489         while (header &&
490                header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
491             header = reinterpret_cast<const StructHeader*>(header->next);
492 
493         dev_info_.pNext = header;
494     }
495 
496     return VK_SUCCESS;
497 }
498 
SanitizeLayers()499 VkResult CreateInfoWrapper::SanitizeLayers() {
500     auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
501                                        : dev_info_.ppEnabledLayerNames;
502     auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
503                                        : dev_info_.enabledLayerCount;
504 
505     // remove all layers
506     layer_names = nullptr;
507     layer_count = 0;
508 
509     return VK_SUCCESS;
510 }
511 
SanitizeExtensions()512 VkResult CreateInfoWrapper::SanitizeExtensions() {
513     auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
514                                      : dev_info_.ppEnabledExtensionNames;
515     auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
516                                      : dev_info_.enabledExtensionCount;
517 
518     VkResult result = InitExtensionFilter();
519     if (result != VK_SUCCESS)
520         return result;
521 
522     if (is_instance_ && icd_api_version_ < loader_api_version_) {
523         for (uint32_t i = 0; i < ext_count; i++) {
524             // Upon api downgrade, skip the promoted instance extensions in the
525             // first pass to avoid duplicate extensions.
526             const std::optional<uint32_t> version =
527                 GetInstanceExtensionPromotedVersion(ext_names[i]);
528             if (version && *version > icd_api_version_ &&
529                 *version <= loader_api_version_)
530                 continue;
531 
532             FilterExtension(ext_names[i]);
533         }
534 
535         // Enable the required extensions to support core functionalities.
536         const auto promoted_extensions = GetPromotedInstanceExtensions(
537             icd_api_version_, loader_api_version_);
538         for (const auto& promoted_extension : promoted_extensions)
539             FilterExtension(promoted_extension);
540     } else {
541         for (uint32_t i = 0; i < ext_count; i++)
542             FilterExtension(ext_names[i]);
543     }
544 
545     // Enable device extensions that contain physical-device commands, so that
546     // vkGetInstanceProcAddr will return those physical-device commands.
547     if (is_instance_) {
548         hook_extensions_.set(ProcHook::KHR_swapchain);
549     }
550 
551     const uint32_t api_version =
552         is_instance_ ? loader_api_version_
553                      : std::min(icd_api_version_, loader_api_version_);
554     switch (api_version) {
555         case VK_API_VERSION_1_4:
556             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_4);
557             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_4);
558             [[clang::fallthrough]];
559         case VK_API_VERSION_1_3:
560             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_3);
561             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_3);
562             [[clang::fallthrough]];
563         case VK_API_VERSION_1_2:
564             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_2);
565             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_2);
566             [[clang::fallthrough]];
567         case VK_API_VERSION_1_1:
568             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
569             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
570             [[clang::fallthrough]];
571         case VK_API_VERSION_1_0:
572             hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
573             hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
574             break;
575         default:
576             ALOGE("Unknown API version[%u]", api_version);
577             break;
578     }
579 
580     ext_names = extension_filter_.names;
581     ext_count = extension_filter_.name_count;
582 
583     return VK_SUCCESS;
584 }
585 
QueryExtensionCount(uint32_t & count) const586 VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
587     if (is_instance_) {
588         return Hal::Device().EnumerateInstanceExtensionProperties(
589             nullptr, &count, nullptr);
590     } else {
591         const auto& driver = GetData(physical_dev_).driver;
592         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
593                                                          &count, nullptr);
594     }
595 }
596 
EnumerateExtensions(uint32_t & count,VkExtensionProperties * props) const597 VkResult CreateInfoWrapper::EnumerateExtensions(
598     uint32_t& count,
599     VkExtensionProperties* props) const {
600     if (is_instance_) {
601         return Hal::Device().EnumerateInstanceExtensionProperties(
602             nullptr, &count, props);
603     } else {
604         const auto& driver = GetData(physical_dev_).driver;
605         return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
606                                                          &count, props);
607     }
608 }
609 
InitExtensionFilter()610 VkResult CreateInfoWrapper::InitExtensionFilter() {
611     // query extension count
612     uint32_t count;
613     VkResult result = QueryExtensionCount(count);
614     if (result != VK_SUCCESS || count == 0)
615         return result;
616 
617     auto& filter = extension_filter_;
618     filter.exts =
619         reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
620             allocator_.pUserData, sizeof(VkExtensionProperties) * count,
621             alignof(VkExtensionProperties),
622             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
623     if (!filter.exts)
624         return VK_ERROR_OUT_OF_HOST_MEMORY;
625 
626     // enumerate extensions
627     result = EnumerateExtensions(count, filter.exts);
628     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
629         return result;
630 
631     if (!count)
632         return VK_SUCCESS;
633 
634     filter.ext_count = count;
635 
636     // allocate name array
637     if (is_instance_) {
638         uint32_t enabled_ext_count = instance_info_.enabledExtensionCount;
639 
640         // It requires enabling additional promoted extensions to downgrade api,
641         // so we reserve enough space here.
642         if (icd_api_version_ < loader_api_version_) {
643             enabled_ext_count += CountPromotedInstanceExtensions(
644                 icd_api_version_, loader_api_version_);
645         }
646 
647         count = std::min(filter.ext_count, enabled_ext_count);
648     } else {
649         count = std::min(filter.ext_count, dev_info_.enabledExtensionCount);
650     }
651 
652     if (!count)
653         return VK_SUCCESS;
654 
655     filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
656         allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
657         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
658     if (!filter.names)
659         return VK_ERROR_OUT_OF_HOST_MEMORY;
660 
661     return VK_SUCCESS;
662 }
663 
FilterExtension(const char * name)664 void CreateInfoWrapper::FilterExtension(const char* name) {
665     auto& filter = extension_filter_;
666 
667     ProcHook::Extension ext_bit = GetProcHookExtension(name);
668     if (is_instance_) {
669         switch (ext_bit) {
670             case ProcHook::KHR_android_surface:
671             case ProcHook::KHR_surface:
672             case ProcHook::KHR_surface_protected_capabilities:
673             case ProcHook::EXT_swapchain_colorspace:
674             case ProcHook::KHR_get_surface_capabilities2:
675             case ProcHook::GOOGLE_surfaceless_query:
676             case ProcHook::EXT_surface_maintenance1:
677                 hook_extensions_.set(ext_bit);
678                 // return now as these extensions do not require HAL support
679                 return;
680             case ProcHook::EXT_debug_report:
681                 // both we and HAL can take part in
682                 hook_extensions_.set(ext_bit);
683                 break;
684             case ProcHook::KHR_get_physical_device_properties2:
685             case ProcHook::KHR_device_group_creation:
686             case ProcHook::KHR_external_memory_capabilities:
687             case ProcHook::KHR_external_semaphore_capabilities:
688             case ProcHook::KHR_external_fence_capabilities:
689             case ProcHook::EXTENSION_UNKNOWN:
690                 // Extensions we don't need to do anything about at this level
691                 break;
692 
693             case ProcHook::KHR_bind_memory2:
694             case ProcHook::KHR_incremental_present:
695             case ProcHook::KHR_shared_presentable_image:
696             case ProcHook::KHR_swapchain:
697             case ProcHook::KHR_swapchain_mutable_format:
698             case ProcHook::EXT_hdr_metadata:
699             case ProcHook::EXT_swapchain_maintenance1:
700             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
701             case ProcHook::ANDROID_native_buffer:
702             case ProcHook::GOOGLE_display_timing:
703             case ProcHook::KHR_external_fence_fd:
704             case ProcHook::EXTENSION_CORE_1_0:
705             case ProcHook::EXTENSION_CORE_1_1:
706             case ProcHook::EXTENSION_CORE_1_2:
707             case ProcHook::EXTENSION_CORE_1_3:
708             case ProcHook::EXTENSION_CORE_1_4:
709             case ProcHook::EXTENSION_COUNT:
710                 // Device and meta extensions. If we ever get here it's a bug in
711                 // our code. But enumerating them lets us avoid having a default
712                 // case, and default hides other bugs.
713                 ALOGE(
714                     "CreateInfoWrapper::FilterExtension: invalid instance "
715                     "extension '%s'. FIX ME",
716                     name);
717                 return;
718 
719             // Don't use a default case. Without it, -Wswitch will tell us
720             // at compile time if someone adds a new ProcHook extension but
721             // doesn't handle it above. That's a real bug that has
722             // not-immediately-obvious effects.
723             //
724             // default:
725             //     break;
726         }
727     } else {
728         switch (ext_bit) {
729             case ProcHook::KHR_swapchain:
730                 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
731                 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
732                 ext_bit = ProcHook::ANDROID_native_buffer;
733                 break;
734             case ProcHook::KHR_incremental_present:
735             case ProcHook::KHR_shared_presentable_image:
736             case ProcHook::GOOGLE_display_timing:
737                 hook_extensions_.set(ext_bit);
738                 // return now as these extensions do not require HAL support
739                 return;
740             case ProcHook::EXT_swapchain_maintenance1:
741                 // map VK_KHR_swapchain_maintenance1 to KHR_external_fence_fd
742                 name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
743                 ext_bit = ProcHook::KHR_external_fence_fd;
744                 break;
745             case ProcHook::EXT_hdr_metadata:
746             case ProcHook::KHR_bind_memory2:
747                 hook_extensions_.set(ext_bit);
748                 break;
749             case ProcHook::ANDROID_external_memory_android_hardware_buffer:
750             case ProcHook::KHR_external_fence_fd:
751             case ProcHook::KHR_swapchain_mutable_format:
752             case ProcHook::EXTENSION_UNKNOWN:
753                 // Extensions we don't need to do anything about at this level
754                 break;
755 
756             case ProcHook::KHR_android_surface:
757             case ProcHook::KHR_get_physical_device_properties2:
758             case ProcHook::KHR_device_group_creation:
759             case ProcHook::KHR_external_memory_capabilities:
760             case ProcHook::KHR_external_semaphore_capabilities:
761             case ProcHook::KHR_external_fence_capabilities:
762             case ProcHook::KHR_get_surface_capabilities2:
763             case ProcHook::KHR_surface:
764             case ProcHook::KHR_surface_protected_capabilities:
765             case ProcHook::EXT_debug_report:
766             case ProcHook::EXT_swapchain_colorspace:
767             case ProcHook::EXT_surface_maintenance1:
768             case ProcHook::GOOGLE_surfaceless_query:
769             case ProcHook::ANDROID_native_buffer:
770             case ProcHook::EXTENSION_CORE_1_0:
771             case ProcHook::EXTENSION_CORE_1_1:
772             case ProcHook::EXTENSION_CORE_1_2:
773             case ProcHook::EXTENSION_CORE_1_3:
774             case ProcHook::EXTENSION_CORE_1_4:
775             case ProcHook::EXTENSION_COUNT:
776                 // Instance and meta extensions. If we ever get here it's a bug
777                 // in our code. But enumerating them lets us avoid having a
778                 // default case, and default hides other bugs.
779                 ALOGE(
780                     "CreateInfoWrapper::FilterExtension: invalid device "
781                     "extension '%s'. FIX ME",
782                     name);
783                 return;
784 
785             // Don't use a default case. Without it, -Wswitch will tell us
786             // at compile time if someone adds a new ProcHook extension but
787             // doesn't handle it above. That's a real bug that has
788             // not-immediately-obvious effects.
789             //
790             // default:
791             //     break;
792         }
793     }
794 
795     for (uint32_t i = 0; i < filter.ext_count; i++) {
796         const VkExtensionProperties& props = filter.exts[i];
797         // ignore unknown extensions
798         if (strcmp(name, props.extensionName) != 0)
799             continue;
800 
801         if (ext_bit != ProcHook::EXTENSION_UNKNOWN &&
802                 hal_extensions_.test(ext_bit)) {
803             ALOGI("CreateInfoWrapper::FilterExtension: already have '%s'.", name);
804             continue;
805         }
806 
807         // Ignore duplicate extensions (see: b/288929054)
808         bool duplicate_entry = false;
809         for (uint32_t j = 0; j < filter.name_count; j++) {
810             if (strcmp(name, filter.names[j]) == 0) {
811                 duplicate_entry = true;
812                 break;
813             }
814         }
815         if (duplicate_entry == true)
816             continue;
817 
818         filter.names[filter.name_count++] = name;
819         if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
820             if (ext_bit == ProcHook::ANDROID_native_buffer)
821                 hook_extensions_.set(ProcHook::KHR_swapchain);
822             if (ext_bit == ProcHook::KHR_external_fence_fd)
823                 hook_extensions_.set(ProcHook::EXT_swapchain_maintenance1);
824 
825             hal_extensions_.set(ext_bit);
826         }
827 
828         break;
829     }
830 }
831 
DefaultAllocate(void *,size_t size,size_t alignment,VkSystemAllocationScope)832 VKAPI_ATTR void* DefaultAllocate(void*,
833                                  size_t size,
834                                  size_t alignment,
835                                  VkSystemAllocationScope) {
836     void* ptr = nullptr;
837     // Vulkan requires 'alignment' to be a power of two, but posix_memalign
838     // additionally requires that it be at least sizeof(void*).
839     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
840     ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
841                     ret, ptr);
842     return ret == 0 ? ptr : nullptr;
843 }
844 
DefaultReallocate(void *,void * ptr,size_t size,size_t alignment,VkSystemAllocationScope)845 VKAPI_ATTR void* DefaultReallocate(void*,
846                                    void* ptr,
847                                    size_t size,
848                                    size_t alignment,
849                                    VkSystemAllocationScope) {
850     if (size == 0) {
851         free(ptr);
852         return nullptr;
853     }
854 
855     // TODO(b/143295633): Right now we never shrink allocations; if the new
856     // request is smaller than the existing chunk, we just continue using it.
857     // Right now the loader never reallocs, so this doesn't matter. If that
858     // changes, or if this code is copied into some other project, this should
859     // probably have a heuristic to allocate-copy-free when doing so will save
860     // "enough" space.
861     size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
862     if (size <= old_size)
863         return ptr;
864 
865     void* new_ptr = nullptr;
866     if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
867         return nullptr;
868     if (ptr) {
869         memcpy(new_ptr, ptr, std::min(old_size, size));
870         free(ptr);
871     }
872     return new_ptr;
873 }
874 
DefaultFree(void *,void * ptr)875 VKAPI_ATTR void DefaultFree(void*, void* ptr) {
876     ALOGD_CALLSTACK("Free: %p", ptr);
877     free(ptr);
878 }
879 
AllocateInstanceData(const VkAllocationCallbacks & allocator)880 InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
881     void* data_mem = allocator.pfnAllocation(
882         allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
883         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
884     if (!data_mem)
885         return nullptr;
886 
887     return new (data_mem) InstanceData(allocator);
888 }
889 
FreeInstanceData(InstanceData * data,const VkAllocationCallbacks & allocator)890 void FreeInstanceData(InstanceData* data,
891                       const VkAllocationCallbacks& allocator) {
892     data->~InstanceData();
893     allocator.pfnFree(allocator.pUserData, data);
894 }
895 
AllocateDeviceData(const VkAllocationCallbacks & allocator,const DebugReportCallbackList & debug_report_callbacks)896 DeviceData* AllocateDeviceData(
897     const VkAllocationCallbacks& allocator,
898     const DebugReportCallbackList& debug_report_callbacks) {
899     void* data_mem = allocator.pfnAllocation(
900         allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
901         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
902     if (!data_mem)
903         return nullptr;
904 
905     return new (data_mem) DeviceData(allocator, debug_report_callbacks);
906 }
907 
FreeDeviceData(DeviceData * data,const VkAllocationCallbacks & allocator)908 void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
909     data->~DeviceData();
910     allocator.pfnFree(allocator.pUserData, data);
911 }
912 
913 }  // anonymous namespace
914 
OpenHAL()915 bool OpenHAL() {
916     return Hal::Open();
917 }
918 
GetDefaultAllocator()919 const VkAllocationCallbacks& GetDefaultAllocator() {
920     static const VkAllocationCallbacks kDefaultAllocCallbacks = {
921         .pUserData = nullptr,
922         .pfnAllocation = DefaultAllocate,
923         .pfnReallocation = DefaultReallocate,
924         .pfnFree = DefaultFree,
925     };
926 
927     return kDefaultAllocCallbacks;
928 }
929 
GetInstanceProcAddr(VkInstance instance,const char * pName)930 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
931     const ProcHook* hook = GetProcHook(pName);
932     if (!hook)
933         return Hal::Device().GetInstanceProcAddr(instance, pName);
934 
935     if (!instance) {
936         if (hook->type == ProcHook::GLOBAL)
937             return hook->proc;
938 
939         // v0 layers expect
940         //
941         //   vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
942         //
943         // to work.
944         if (strcmp(pName, "vkCreateDevice") == 0)
945             return hook->proc;
946 
947         ALOGE(
948             "internal vkGetInstanceProcAddr called for %s without an instance",
949             pName);
950 
951         return nullptr;
952     }
953 
954     PFN_vkVoidFunction proc;
955 
956     switch (hook->type) {
957         case ProcHook::INSTANCE:
958             proc = (GetData(instance).hook_extensions[hook->extension])
959                        ? hook->proc
960                        : nullptr;
961             break;
962         case ProcHook::DEVICE:
963             proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
964                        ? hook->proc
965                        : hook->checked_proc;
966             break;
967         default:
968             ALOGE(
969                 "internal vkGetInstanceProcAddr called for %s with an instance",
970                 pName);
971             proc = nullptr;
972             break;
973     }
974 
975     return proc;
976 }
977 
GetDeviceProcAddr(VkDevice device,const char * pName)978 PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
979     const ProcHook* hook = GetProcHook(pName);
980     PFN_vkVoidFunction drv_func = GetData(device).driver.GetDeviceProcAddr(device, pName);
981 
982     if (!hook)
983         return drv_func;
984 
985     if (hook->type != ProcHook::DEVICE) {
986         ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
987         return nullptr;
988     }
989 
990     // Don't hook if we don't have a device entry function below for the core function.
991     if (!drv_func && (hook->extension >= ProcHook::EXTENSION_CORE_1_0))
992         return nullptr;
993 
994     return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
995                                                               : nullptr;
996 }
997 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)998 VkResult EnumerateInstanceExtensionProperties(
999     const char* pLayerName,
1000     uint32_t* pPropertyCount,
1001     VkExtensionProperties* pProperties) {
1002     std::vector<VkExtensionProperties> loader_extensions;
1003     loader_extensions.push_back(
1004         {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION});
1005     loader_extensions.push_back(
1006         {VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
1007          VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION});
1008     loader_extensions.push_back({
1009         VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1010         VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
1011     loader_extensions.push_back({
1012         VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
1013         VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
1014     loader_extensions.push_back(
1015         {VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
1016          VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
1017     loader_extensions.push_back({VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME,
1018                                  VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION});
1019     loader_extensions.push_back({
1020         VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME,
1021         VK_EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION});
1022 
1023     static const VkExtensionProperties loader_debug_report_extension = {
1024         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
1025     };
1026 
1027     // enumerate our extensions first
1028     if (!pLayerName && pProperties) {
1029         uint32_t count = std::min(
1030             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
1031 
1032         std::copy_n(loader_extensions.data(), count, pProperties);
1033 
1034         if (count < loader_extensions.size()) {
1035             *pPropertyCount = count;
1036             return VK_INCOMPLETE;
1037         }
1038 
1039         pProperties += count;
1040         *pPropertyCount -= count;
1041 
1042         if (Hal::Get().GetDebugReportIndex() < 0) {
1043             if (!*pPropertyCount) {
1044                 *pPropertyCount = count;
1045                 return VK_INCOMPLETE;
1046             }
1047 
1048             pProperties[0] = loader_debug_report_extension;
1049             pProperties += 1;
1050             *pPropertyCount -= 1;
1051         }
1052     }
1053 
1054     ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
1055     VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
1056         pLayerName, pPropertyCount, pProperties);
1057     ATRACE_END();
1058 
1059     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1060         int idx = Hal::Get().GetDebugReportIndex();
1061         if (idx < 0) {
1062             *pPropertyCount += 1;
1063         } else if (pProperties &&
1064                    static_cast<uint32_t>(idx) < *pPropertyCount) {
1065             pProperties[idx].specVersion =
1066                 std::min(pProperties[idx].specVersion,
1067                          loader_debug_report_extension.specVersion);
1068         }
1069 
1070         *pPropertyCount += loader_extensions.size();
1071     }
1072 
1073     return result;
1074 }
1075 
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesANDROID * presentation_properties)1076 void QueryPresentationProperties(
1077     VkPhysicalDevice physicalDevice,
1078     VkPhysicalDevicePresentationPropertiesANDROID* presentation_properties) {
1079     ATRACE_CALL();
1080 
1081     // Request the android-specific presentation properties via GPDP2
1082     VkPhysicalDeviceProperties2 properties = {
1083         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1084         presentation_properties,
1085         {},
1086     };
1087 
1088 #pragma clang diagnostic push
1089 #pragma clang diagnostic ignored "-Wold-style-cast"
1090     presentation_properties->sType =
1091         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
1092 #pragma clang diagnostic pop
1093     presentation_properties->pNext = nullptr;
1094     presentation_properties->sharedImage = VK_FALSE;
1095 
1096     const auto& driver = GetData(physicalDevice).driver;
1097 
1098     if (driver.GetPhysicalDeviceProperties2) {
1099         // >= 1.1 driver, supports core GPDP2 entrypoint.
1100         driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
1101     } else if (driver.GetPhysicalDeviceProperties2KHR) {
1102         // Old driver, but may support presentation properties
1103         // if we have the GPDP2 extension. Otherwise, no presentation
1104         // properties supported.
1105         driver.GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1106     }
1107 }
1108 
GetAndroidNativeBufferSpecVersion9Support(VkPhysicalDevice physicalDevice,bool & support)1109 VkResult GetAndroidNativeBufferSpecVersion9Support(
1110     VkPhysicalDevice physicalDevice,
1111     bool& support) {
1112     support = false;
1113 
1114     const InstanceData& data = GetData(physicalDevice);
1115 
1116     // Call to get propertyCount
1117     uint32_t propertyCount = 0;
1118     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1119     VkResult result = data.driver.EnumerateDeviceExtensionProperties(
1120         physicalDevice, nullptr, &propertyCount, nullptr);
1121     ATRACE_END();
1122 
1123     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1124         return result;
1125     }
1126 
1127     // Call to enumerate properties
1128     std::vector<VkExtensionProperties> properties(propertyCount);
1129     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1130     result = data.driver.EnumerateDeviceExtensionProperties(
1131         physicalDevice, nullptr, &propertyCount, properties.data());
1132     ATRACE_END();
1133 
1134     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1135         return result;
1136     }
1137 
1138     for (uint32_t i = 0; i < propertyCount; i++) {
1139         auto& prop = properties[i];
1140 
1141         if (strcmp(prop.extensionName,
1142                    VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1143             continue;
1144 
1145         if (prop.specVersion >= 9) {
1146             support = true;
1147             return result;
1148         }
1149     }
1150 
1151     return result;
1152 }
1153 
CanSupportSwapchainMaintenance1Extension(VkPhysicalDevice physicalDevice)1154 bool CanSupportSwapchainMaintenance1Extension(VkPhysicalDevice physicalDevice) {
1155     const auto& driver = GetData(physicalDevice).driver;
1156     if (!driver.GetPhysicalDeviceExternalFenceProperties)
1157         return false;
1158 
1159     // Requires support for external fences imported from sync fds.
1160     // This is _almost_ universal on Android, but may be missing on
1161     // some extremely old drivers, or on strange implementations like
1162     // cuttlefish.
1163     VkPhysicalDeviceExternalFenceInfo fenceInfo = {
1164         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
1165         nullptr,
1166         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
1167     };
1168     VkExternalFenceProperties fenceProperties = {
1169         VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
1170         nullptr,
1171         0, 0, 0
1172     };
1173 
1174     GetPhysicalDeviceExternalFenceProperties(physicalDevice, &fenceInfo, &fenceProperties);
1175     if (fenceProperties.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT)
1176         return true;
1177 
1178     return false;
1179 }
1180 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1181 VkResult EnumerateDeviceExtensionProperties(
1182     VkPhysicalDevice physicalDevice,
1183     const char* pLayerName,
1184     uint32_t* pPropertyCount,
1185     VkExtensionProperties* pProperties) {
1186     const InstanceData& data = GetData(physicalDevice);
1187     // extensions that are unconditionally exposed by the loader
1188     std::vector<VkExtensionProperties> loader_extensions;
1189     loader_extensions.push_back({
1190         VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
1191         VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
1192 
1193     bool hdrBoardConfig = android::sysprop::has_HDR_display(false);
1194     if (hdrBoardConfig) {
1195         loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
1196                                      VK_EXT_HDR_METADATA_SPEC_VERSION});
1197     }
1198 
1199     VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
1200     QueryPresentationProperties(physicalDevice, &presentation_properties);
1201     if (presentation_properties.sharedImage) {
1202         loader_extensions.push_back({
1203             VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
1204             VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
1205     }
1206 
1207     // conditionally add VK_GOOGLE_display_timing if present timestamps are
1208     // supported by the driver:
1209     if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
1210         loader_extensions.push_back({
1211                 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
1212                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
1213     }
1214 
1215     // Conditionally add VK_EXT_IMAGE_COMPRESSION_CONTROL* if feature and ANB
1216     // support is provided by the driver
1217     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT
1218         swapchainCompFeats = {};
1219     swapchainCompFeats.sType =
1220         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT;
1221     swapchainCompFeats.pNext = nullptr;
1222     swapchainCompFeats.imageCompressionControlSwapchain = false;
1223     VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
1224     imageCompFeats.sType =
1225         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
1226     imageCompFeats.pNext = &swapchainCompFeats;
1227     imageCompFeats.imageCompressionControl = false;
1228 
1229     VkPhysicalDeviceFeatures2 feats2 = {};
1230     feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1231     feats2.pNext = &imageCompFeats;
1232 
1233     const auto& driver = GetData(physicalDevice).driver;
1234     if (driver.GetPhysicalDeviceFeatures2 ||
1235         driver.GetPhysicalDeviceFeatures2KHR) {
1236         GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
1237     }
1238 
1239     bool anb9 = false;
1240     VkResult result =
1241         GetAndroidNativeBufferSpecVersion9Support(physicalDevice, anb9);
1242 
1243     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1244         return result;
1245     }
1246 
1247     if (anb9 && imageCompFeats.imageCompressionControl) {
1248         loader_extensions.push_back(
1249             {VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME,
1250              VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION});
1251     }
1252     if (anb9 && swapchainCompFeats.imageCompressionControlSwapchain) {
1253         loader_extensions.push_back(
1254             {VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME,
1255              VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION});
1256     }
1257 
1258     if (CanSupportSwapchainMaintenance1Extension(physicalDevice)) {
1259         loader_extensions.push_back({
1260                 VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME,
1261                 VK_EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION});
1262     }
1263 
1264     VkPhysicalDeviceProperties pDeviceProperties;
1265     data.driver.GetPhysicalDeviceProperties(physicalDevice, &pDeviceProperties);
1266     if (flags::swapchain_mutable_format_ext() &&
1267         pDeviceProperties.apiVersion >= VK_API_VERSION_1_2) {
1268         loader_extensions.push_back(
1269             {VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME,
1270              VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION});
1271     }
1272 
1273     // enumerate our extensions first
1274     if (!pLayerName && pProperties) {
1275         uint32_t count = std::min(
1276             *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
1277 
1278         std::copy_n(loader_extensions.data(), count, pProperties);
1279 
1280         if (count < loader_extensions.size()) {
1281             *pPropertyCount = count;
1282             return VK_INCOMPLETE;
1283         }
1284 
1285         pProperties += count;
1286         *pPropertyCount -= count;
1287     }
1288 
1289     ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
1290     result = data.driver.EnumerateDeviceExtensionProperties(
1291         physicalDevice, pLayerName, pPropertyCount, pProperties);
1292     ATRACE_END();
1293 
1294     if (pProperties) {
1295         // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1296         for (uint32_t i = 0; i < *pPropertyCount; i++) {
1297             auto& prop = pProperties[i];
1298 
1299             if (strcmp(prop.extensionName,
1300                        VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1301                 continue;
1302 
1303             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1304                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
1305 
1306             if (prop.specVersion >= 8) {
1307                 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1308             } else {
1309                 prop.specVersion = 68;
1310             }
1311         }
1312     }
1313 
1314     // restore loader extension count
1315     if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1316         *pPropertyCount += loader_extensions.size();
1317     }
1318 
1319     return result;
1320 }
1321 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1322 VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1323                         const VkAllocationCallbacks* pAllocator,
1324                         VkInstance* pInstance) {
1325     const VkAllocationCallbacks& data_allocator =
1326         (pAllocator) ? *pAllocator : GetDefaultAllocator();
1327 
1328     VkResult result = VK_SUCCESS;
1329     uint32_t icd_api_version = VK_API_VERSION_1_0;
1330     PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1331         reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
1332             Hal::Device().GetInstanceProcAddr(nullptr,
1333                                               "vkEnumerateInstanceVersion"));
1334     if (pfn_enumerate_instance_version) {
1335         ATRACE_BEGIN("pfn_enumerate_instance_version");
1336         result = (*pfn_enumerate_instance_version)(&icd_api_version);
1337         ATRACE_END();
1338         if (result != VK_SUCCESS)
1339             return result;
1340 
1341         icd_api_version ^= VK_API_VERSION_PATCH(icd_api_version);
1342     }
1343 
1344     CreateInfoWrapper wrapper(*pCreateInfo, icd_api_version, data_allocator);
1345     result = wrapper.Validate();
1346     if (result != VK_SUCCESS)
1347         return result;
1348 
1349     InstanceData* data = AllocateInstanceData(data_allocator);
1350     if (!data)
1351         return VK_ERROR_OUT_OF_HOST_MEMORY;
1352 
1353     data->hook_extensions |= wrapper.GetHookExtensions();
1354 
1355     // call into the driver
1356     VkInstance instance;
1357     ATRACE_BEGIN("driver.CreateInstance");
1358     result = Hal::Device().CreateInstance(
1359         static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1360         &instance);
1361     ATRACE_END();
1362     if (result != VK_SUCCESS) {
1363         FreeInstanceData(data, data_allocator);
1364         return result;
1365     }
1366 
1367     // initialize InstanceDriverTable
1368     if (!SetData(instance, *data) ||
1369         !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
1370                          wrapper.GetHalExtensions())) {
1371         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
1372             Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
1373         if (data->driver.DestroyInstance)
1374             data->driver.DestroyInstance(instance, pAllocator);
1375 
1376         FreeInstanceData(data, data_allocator);
1377 
1378         return VK_ERROR_INCOMPATIBLE_DRIVER;
1379     }
1380 
1381     data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
1382         Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
1383     if (!data->get_device_proc_addr) {
1384         data->driver.DestroyInstance(instance, pAllocator);
1385         FreeInstanceData(data, data_allocator);
1386 
1387         return VK_ERROR_INCOMPATIBLE_DRIVER;
1388     }
1389 
1390     // TODO(b/259516419) avoid getting stats from hwui
1391     // const bool reportStats = (pCreateInfo->pApplicationInfo == nullptr )
1392     //         || (strcmp("android framework",
1393     //         pCreateInfo->pApplicationInfo->pEngineName) != 0);
1394     const bool reportStats = true;
1395     if (reportStats) {
1396         // Set stats for Vulkan api version requested with application info
1397         if (pCreateInfo->pApplicationInfo) {
1398             const uint32_t vulkanApiVersion =
1399                 pCreateInfo->pApplicationInfo->apiVersion;
1400             android::GraphicsEnv::getInstance().setTargetStats(
1401                 android::GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION,
1402                 vulkanApiVersion);
1403 
1404             if (pCreateInfo->pApplicationInfo->pEngineName) {
1405                 android::GraphicsEnv::getInstance().addVulkanEngineName(
1406                     pCreateInfo->pApplicationInfo->pEngineName);
1407             }
1408         }
1409 
1410         // Update stats for the extensions requested
1411         android::GraphicsEnv::getInstance().setVulkanInstanceExtensions(
1412             pCreateInfo->enabledExtensionCount,
1413             pCreateInfo->ppEnabledExtensionNames);
1414     }
1415 
1416     *pInstance = instance;
1417 
1418     return VK_SUCCESS;
1419 }
1420 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1421 void DestroyInstance(VkInstance instance,
1422                      const VkAllocationCallbacks* pAllocator) {
1423     InstanceData& data = GetData(instance);
1424     data.driver.DestroyInstance(instance, pAllocator);
1425 
1426     VkAllocationCallbacks local_allocator;
1427     if (!pAllocator) {
1428         local_allocator = data.allocator;
1429         pAllocator = &local_allocator;
1430     }
1431 
1432     FreeInstanceData(&data, *pAllocator);
1433 }
1434 
CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1435 VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1436                       const VkDeviceCreateInfo* pCreateInfo,
1437                       const VkAllocationCallbacks* pAllocator,
1438                       VkDevice* pDevice) {
1439     const InstanceData& instance_data = GetData(physicalDevice);
1440     const VkAllocationCallbacks& data_allocator =
1441         (pAllocator) ? *pAllocator : instance_data.allocator;
1442 
1443     VkPhysicalDeviceProperties properties;
1444     ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1445     instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1446                                                      &properties);
1447     ATRACE_END();
1448 
1449     CreateInfoWrapper wrapper(
1450         physicalDevice, *pCreateInfo,
1451         properties.apiVersion ^ VK_API_VERSION_PATCH(properties.apiVersion),
1452         data_allocator);
1453     VkResult result = wrapper.Validate();
1454     if (result != VK_SUCCESS)
1455         return result;
1456 
1457     ATRACE_BEGIN("AllocateDeviceData");
1458     DeviceData* data = AllocateDeviceData(data_allocator,
1459                                           instance_data.debug_report_callbacks);
1460     ATRACE_END();
1461     if (!data)
1462         return VK_ERROR_OUT_OF_HOST_MEMORY;
1463 
1464     data->hook_extensions |= wrapper.GetHookExtensions();
1465 
1466     // call into the driver
1467     VkDevice dev;
1468     ATRACE_BEGIN("driver.CreateDevice");
1469     result = instance_data.driver.CreateDevice(
1470         physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1471         pAllocator, &dev);
1472     ATRACE_END();
1473     if (result != VK_SUCCESS) {
1474         FreeDeviceData(data, data_allocator);
1475         return result;
1476     }
1477 
1478     // initialize DeviceDriverTable
1479     if (!SetData(dev, *data) ||
1480         !InitDriverTable(dev, instance_data.get_device_proc_addr,
1481                          wrapper.GetHalExtensions())) {
1482         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1483             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1484         if (data->driver.DestroyDevice)
1485             data->driver.DestroyDevice(dev, pAllocator);
1486 
1487         FreeDeviceData(data, data_allocator);
1488 
1489         return VK_ERROR_INCOMPATIBLE_DRIVER;
1490     }
1491 
1492     // Confirming ANDROID_native_buffer implementation, whose set of
1493     // entrypoints varies according to the spec version.
1494     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1495         !data->driver.GetSwapchainGrallocUsageANDROID &&
1496         !data->driver.GetSwapchainGrallocUsage2ANDROID &&
1497         !data->driver.GetSwapchainGrallocUsage3ANDROID &&
1498         !data->driver.GetSwapchainGrallocUsage4ANDROID) {
1499         ALOGE(
1500             "Driver's implementation of ANDROID_native_buffer is broken;"
1501             " must expose at least one of "
1502             "vkGetSwapchainGrallocUsageANDROID or "
1503             "vkGetSwapchainGrallocUsage2ANDROID or "
1504             "vkGetSwapchainGrallocUsage3ANDROID or "
1505             "vkGetSwapchainGrallocUsage4ANDROID");
1506 
1507         data->driver.DestroyDevice(dev, pAllocator);
1508         FreeDeviceData(data, data_allocator);
1509 
1510         return VK_ERROR_INCOMPATIBLE_DRIVER;
1511     }
1512 
1513     if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1514         // Log that the app is hitting software Vulkan implementation
1515         android::GraphicsEnv::getInstance().setTargetStats(
1516             android::GpuStatsInfo::Stats::CPU_VULKAN_IN_USE);
1517     }
1518 
1519     data->driver_device = dev;
1520     data->driver_physical_device = physicalDevice;
1521 
1522     *pDevice = dev;
1523 
1524     // TODO(b/259516419) avoid getting stats from hwui
1525     const bool reportStats = true;
1526     if (reportStats) {
1527         android::GraphicsEnv::getInstance().setTargetStats(
1528             android::GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE);
1529 
1530         // Set stats for creating a Vulkan device and report features in use
1531         const VkPhysicalDeviceFeatures* pEnabledFeatures =
1532             pCreateInfo->pEnabledFeatures;
1533         if (!pEnabledFeatures) {
1534             // Use features from the chained VkPhysicalDeviceFeatures2
1535             // structure, if given
1536             const VkPhysicalDeviceFeatures2* features2 =
1537                 reinterpret_cast<const VkPhysicalDeviceFeatures2*>(
1538                     pCreateInfo->pNext);
1539             while (features2 &&
1540                    features2->sType !=
1541                        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) {
1542                 features2 = reinterpret_cast<const VkPhysicalDeviceFeatures2*>(
1543                     features2->pNext);
1544             }
1545             if (features2) {
1546                 pEnabledFeatures = &features2->features;
1547             }
1548         }
1549         const VkBool32* pFeatures =
1550             reinterpret_cast<const VkBool32*>(pEnabledFeatures);
1551         if (pFeatures) {
1552             // VkPhysicalDeviceFeatures consists of VkBool32 values, go over all
1553             // of them using pointer arithmetic here and save the features in a
1554             // 64-bit bitfield
1555             static_assert(
1556                 (sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32)) <= 64,
1557                 "VkPhysicalDeviceFeatures has too many elements for bitfield "
1558                 "packing");
1559             static_assert(
1560                 (sizeof(VkPhysicalDeviceFeatures) % sizeof(VkBool32)) == 0,
1561                 "VkPhysicalDeviceFeatures has invalid size for bitfield "
1562                 "packing");
1563             const int numFeatures =
1564                 sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
1565 
1566             uint64_t enableFeatureBits = 0;
1567             for (int i = 0; i < numFeatures; i++) {
1568                 if (pFeatures[i] != VK_FALSE) {
1569                     enableFeatureBits |= (uint64_t(1) << i);
1570                 }
1571             }
1572             android::GraphicsEnv::getInstance().setTargetStats(
1573                 android::GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED,
1574                 enableFeatureBits);
1575         }
1576 
1577         // Update stats for the extensions requested
1578         android::GraphicsEnv::getInstance().setVulkanDeviceExtensions(
1579             pCreateInfo->enabledExtensionCount,
1580             pCreateInfo->ppEnabledExtensionNames);
1581     }
1582 
1583     return VK_SUCCESS;
1584 }
1585 
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1586 void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1587     DeviceData& data = GetData(device);
1588     data.driver.DestroyDevice(device, pAllocator);
1589 
1590     VkAllocationCallbacks local_allocator;
1591     if (!pAllocator) {
1592         local_allocator = data.allocator;
1593         pAllocator = &local_allocator;
1594     }
1595 
1596     FreeDeviceData(&data, *pAllocator);
1597 }
1598 
EnumeratePhysicalDevices(VkInstance instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)1599 VkResult EnumeratePhysicalDevices(VkInstance instance,
1600                                   uint32_t* pPhysicalDeviceCount,
1601                                   VkPhysicalDevice* pPhysicalDevices) {
1602     ATRACE_CALL();
1603 
1604     const auto& data = GetData(instance);
1605 
1606     VkResult result = data.driver.EnumeratePhysicalDevices(
1607         instance, pPhysicalDeviceCount, pPhysicalDevices);
1608     if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1609         for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1610             SetData(pPhysicalDevices[i], data);
1611     }
1612 
1613     return result;
1614 }
1615 
EnumeratePhysicalDeviceGroups(VkInstance instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)1616 VkResult EnumeratePhysicalDeviceGroups(
1617     VkInstance instance,
1618     uint32_t* pPhysicalDeviceGroupCount,
1619     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
1620     ATRACE_CALL();
1621 
1622     VkResult result = VK_SUCCESS;
1623     const auto& data = GetData(instance);
1624 
1625     if (!data.driver.EnumeratePhysicalDeviceGroups &&
1626         !data.driver.EnumeratePhysicalDeviceGroupsKHR) {
1627         uint32_t device_count = 0;
1628         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1629         if (result < 0)
1630             return result;
1631 
1632         if (!pPhysicalDeviceGroupProperties) {
1633             *pPhysicalDeviceGroupCount = device_count;
1634             return result;
1635         }
1636 
1637         if (!device_count) {
1638             *pPhysicalDeviceGroupCount = 0;
1639             return result;
1640         }
1641         device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1642         if (!device_count)
1643             return VK_INCOMPLETE;
1644 
1645         std::vector<VkPhysicalDevice> devices(device_count);
1646         *pPhysicalDeviceGroupCount = device_count;
1647         result =
1648             EnumeratePhysicalDevices(instance, &device_count, devices.data());
1649         if (result < 0)
1650             return result;
1651 
1652         for (uint32_t i = 0; i < device_count; ++i) {
1653             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1654             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1655             pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1656         }
1657     } else {
1658         if (data.driver.EnumeratePhysicalDeviceGroups) {
1659             result = data.driver.EnumeratePhysicalDeviceGroups(
1660                 instance, pPhysicalDeviceGroupCount,
1661                 pPhysicalDeviceGroupProperties);
1662         } else {
1663             result = data.driver.EnumeratePhysicalDeviceGroupsKHR(
1664                 instance, pPhysicalDeviceGroupCount,
1665                 pPhysicalDeviceGroupProperties);
1666         }
1667         if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1668             *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1669             for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1670                 for (uint32_t j = 0;
1671                      j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1672                      j++) {
1673                     SetData(
1674                         pPhysicalDeviceGroupProperties[i].physicalDevices[j],
1675                         data);
1676                 }
1677             }
1678         }
1679     }
1680 
1681     return result;
1682 }
1683 
GetDeviceQueue(VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)1684 void GetDeviceQueue(VkDevice device,
1685                     uint32_t queueFamilyIndex,
1686                     uint32_t queueIndex,
1687                     VkQueue* pQueue) {
1688     ATRACE_CALL();
1689 
1690     const auto& data = GetData(device);
1691 
1692     data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1693     SetData(*pQueue, data);
1694 }
1695 
GetDeviceQueue2(VkDevice device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)1696 void GetDeviceQueue2(VkDevice device,
1697                      const VkDeviceQueueInfo2* pQueueInfo,
1698                      VkQueue* pQueue) {
1699     ATRACE_CALL();
1700 
1701     const auto& data = GetData(device);
1702 
1703     data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
1704     if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
1705 }
1706 
AllocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)1707 VkResult AllocateCommandBuffers(
1708     VkDevice device,
1709     const VkCommandBufferAllocateInfo* pAllocateInfo,
1710     VkCommandBuffer* pCommandBuffers) {
1711     ATRACE_CALL();
1712 
1713     const auto& data = GetData(device);
1714 
1715     VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1716                                                          pCommandBuffers);
1717     if (result == VK_SUCCESS) {
1718         for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1719             SetData(pCommandBuffers[i], data);
1720     }
1721 
1722     return result;
1723 }
1724 
QueueSubmit(VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)1725 VkResult QueueSubmit(VkQueue queue,
1726                      uint32_t submitCount,
1727                      const VkSubmitInfo* pSubmits,
1728                      VkFence fence) {
1729     ATRACE_CALL();
1730 
1731     const auto& data = GetData(queue);
1732 
1733     return data.driver.QueueSubmit(queue, submitCount, pSubmits, fence);
1734 }
1735 
GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)1736 void GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
1737                                 VkPhysicalDeviceFeatures2* pFeatures) {
1738     ATRACE_CALL();
1739 
1740     const auto& driver = GetData(physicalDevice).driver;
1741 
1742     if (driver.GetPhysicalDeviceFeatures2) {
1743         driver.GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
1744     } else {
1745         driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
1746     }
1747 
1748     // Conditionally add imageCompressionControlSwapchain if
1749     // imageCompressionControl is supported Check for imageCompressionControl in
1750     // the pChain
1751     bool imageCompressionControl = false;
1752     bool imageCompressionControlInChain = false;
1753     bool imageCompressionControlSwapchainInChain = false;
1754     VkPhysicalDeviceFeatures2* pFeats = pFeatures;
1755     while (pFeats) {
1756         switch (pFeats->sType) {
1757             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT: {
1758                 const VkPhysicalDeviceImageCompressionControlFeaturesEXT*
1759                     compressionFeat = reinterpret_cast<
1760                         const VkPhysicalDeviceImageCompressionControlFeaturesEXT*>(
1761                         pFeats);
1762                 imageCompressionControl =
1763                     compressionFeat->imageCompressionControl;
1764                 imageCompressionControlInChain = true;
1765             } break;
1766 
1767             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
1768                 VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
1769                     compressionFeat = reinterpret_cast<
1770                         VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
1771                         pFeats);
1772                 compressionFeat->imageCompressionControlSwapchain = false;
1773                 imageCompressionControlSwapchainInChain = true;
1774             } break;
1775 
1776             case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT: {
1777                 auto smf = reinterpret_cast<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *>(
1778                         pFeats);
1779                 smf->swapchainMaintenance1 = true;
1780             } break;
1781 
1782             default:
1783                 break;
1784         }
1785         pFeats = reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
1786     }
1787 
1788     if (!imageCompressionControlSwapchainInChain) {
1789         return;
1790     }
1791 
1792     // If not in pchain, explicitly query for imageCompressionControl
1793     if (!imageCompressionControlInChain) {
1794         VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
1795         imageCompFeats.sType =
1796             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
1797         imageCompFeats.pNext = nullptr;
1798         imageCompFeats.imageCompressionControl = false;
1799 
1800         VkPhysicalDeviceFeatures2 feats2 = {};
1801         feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1802         feats2.pNext = &imageCompFeats;
1803 
1804         if (driver.GetPhysicalDeviceFeatures2) {
1805             driver.GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
1806         } else {
1807             driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, &feats2);
1808         }
1809 
1810         imageCompressionControl = imageCompFeats.imageCompressionControl;
1811     }
1812 
1813     // Only enumerate imageCompressionControlSwapchin if imageCompressionControl
1814     if (imageCompressionControl) {
1815         pFeats = pFeatures;
1816         while (pFeats) {
1817             switch (pFeats->sType) {
1818                 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
1819                     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
1820                         compressionFeat = reinterpret_cast<
1821                             VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
1822                             pFeats);
1823                     compressionFeat->imageCompressionControlSwapchain = true;
1824                 } break;
1825 
1826                 default:
1827                     break;
1828             }
1829             pFeats =
1830                 reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
1831         }
1832     }
1833 }
1834 
GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)1835 void GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1836                                   VkPhysicalDeviceProperties2* pProperties) {
1837     ATRACE_CALL();
1838 
1839     const auto& driver = GetData(physicalDevice).driver;
1840 
1841     if (driver.GetPhysicalDeviceProperties2) {
1842         driver.GetPhysicalDeviceProperties2(physicalDevice, pProperties);
1843         return;
1844     }
1845 
1846     driver.GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties);
1847 }
1848 
GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)1849 void GetPhysicalDeviceFormatProperties2(
1850     VkPhysicalDevice physicalDevice,
1851     VkFormat format,
1852     VkFormatProperties2* pFormatProperties) {
1853     ATRACE_CALL();
1854 
1855     const auto& driver = GetData(physicalDevice).driver;
1856 
1857     if (driver.GetPhysicalDeviceFormatProperties2) {
1858         driver.GetPhysicalDeviceFormatProperties2(physicalDevice, format,
1859                                                   pFormatProperties);
1860         return;
1861     }
1862 
1863     driver.GetPhysicalDeviceFormatProperties2KHR(physicalDevice, format,
1864                                                  pFormatProperties);
1865 }
1866 
GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)1867 VkResult GetPhysicalDeviceImageFormatProperties2(
1868     VkPhysicalDevice physicalDevice,
1869     const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1870     VkImageFormatProperties2* pImageFormatProperties) {
1871     ATRACE_CALL();
1872 
1873     const auto& driver = GetData(physicalDevice).driver;
1874 
1875     if (driver.GetPhysicalDeviceImageFormatProperties2) {
1876         return driver.GetPhysicalDeviceImageFormatProperties2(
1877             physicalDevice, pImageFormatInfo, pImageFormatProperties);
1878     }
1879 
1880     return driver.GetPhysicalDeviceImageFormatProperties2KHR(
1881         physicalDevice, pImageFormatInfo, pImageFormatProperties);
1882 }
1883 
GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1884 void GetPhysicalDeviceQueueFamilyProperties2(
1885     VkPhysicalDevice physicalDevice,
1886     uint32_t* pQueueFamilyPropertyCount,
1887     VkQueueFamilyProperties2* pQueueFamilyProperties) {
1888     ATRACE_CALL();
1889 
1890     const auto& driver = GetData(physicalDevice).driver;
1891 
1892     if (driver.GetPhysicalDeviceQueueFamilyProperties2) {
1893         driver.GetPhysicalDeviceQueueFamilyProperties2(
1894             physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1895         return;
1896     }
1897 
1898     driver.GetPhysicalDeviceQueueFamilyProperties2KHR(
1899         physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
1900 }
1901 
GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1902 void GetPhysicalDeviceMemoryProperties2(
1903     VkPhysicalDevice physicalDevice,
1904     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
1905     ATRACE_CALL();
1906 
1907     const auto& driver = GetData(physicalDevice).driver;
1908 
1909     if (driver.GetPhysicalDeviceMemoryProperties2) {
1910         driver.GetPhysicalDeviceMemoryProperties2(physicalDevice,
1911                                                   pMemoryProperties);
1912         return;
1913     }
1914 
1915     driver.GetPhysicalDeviceMemoryProperties2KHR(physicalDevice,
1916                                                  pMemoryProperties);
1917 }
1918 
GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)1919 void GetPhysicalDeviceSparseImageFormatProperties2(
1920     VkPhysicalDevice physicalDevice,
1921     const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
1922     uint32_t* pPropertyCount,
1923     VkSparseImageFormatProperties2* pProperties) {
1924     ATRACE_CALL();
1925 
1926     const auto& driver = GetData(physicalDevice).driver;
1927 
1928     if (driver.GetPhysicalDeviceSparseImageFormatProperties2) {
1929         driver.GetPhysicalDeviceSparseImageFormatProperties2(
1930             physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1931         return;
1932     }
1933 
1934     driver.GetPhysicalDeviceSparseImageFormatProperties2KHR(
1935         physicalDevice, pFormatInfo, pPropertyCount, pProperties);
1936 }
1937 
GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)1938 void GetPhysicalDeviceExternalBufferProperties(
1939     VkPhysicalDevice physicalDevice,
1940     const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
1941     VkExternalBufferProperties* pExternalBufferProperties) {
1942     ATRACE_CALL();
1943 
1944     const auto& driver = GetData(physicalDevice).driver;
1945 
1946     if (driver.GetPhysicalDeviceExternalBufferProperties) {
1947         driver.GetPhysicalDeviceExternalBufferProperties(
1948             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1949         return;
1950     }
1951 
1952     if (driver.GetPhysicalDeviceExternalBufferPropertiesKHR) {
1953         driver.GetPhysicalDeviceExternalBufferPropertiesKHR(
1954             physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
1955         return;
1956     }
1957 
1958     memset(&pExternalBufferProperties->externalMemoryProperties, 0,
1959            sizeof(VkExternalMemoryProperties));
1960 }
1961 
GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)1962 void GetPhysicalDeviceExternalSemaphoreProperties(
1963     VkPhysicalDevice physicalDevice,
1964     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
1965     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
1966     ATRACE_CALL();
1967 
1968     const auto& driver = GetData(physicalDevice).driver;
1969 
1970     if (driver.GetPhysicalDeviceExternalSemaphoreProperties) {
1971         driver.GetPhysicalDeviceExternalSemaphoreProperties(
1972             physicalDevice, pExternalSemaphoreInfo,
1973             pExternalSemaphoreProperties);
1974         return;
1975     }
1976 
1977     if (driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR) {
1978         driver.GetPhysicalDeviceExternalSemaphorePropertiesKHR(
1979             physicalDevice, pExternalSemaphoreInfo,
1980             pExternalSemaphoreProperties);
1981         return;
1982     }
1983 
1984     pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
1985     pExternalSemaphoreProperties->compatibleHandleTypes = 0;
1986     pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
1987 }
1988 
GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)1989 void GetPhysicalDeviceExternalFenceProperties(
1990     VkPhysicalDevice physicalDevice,
1991     const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
1992     VkExternalFenceProperties* pExternalFenceProperties) {
1993     ATRACE_CALL();
1994 
1995     const auto& driver = GetData(physicalDevice).driver;
1996 
1997     if (driver.GetPhysicalDeviceExternalFenceProperties) {
1998         driver.GetPhysicalDeviceExternalFenceProperties(
1999             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
2000         return;
2001     }
2002 
2003     if (driver.GetPhysicalDeviceExternalFencePropertiesKHR) {
2004         driver.GetPhysicalDeviceExternalFencePropertiesKHR(
2005             physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
2006         return;
2007     }
2008 
2009     pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2010     pExternalFenceProperties->compatibleHandleTypes = 0;
2011     pExternalFenceProperties->externalFenceFeatures = 0;
2012 }
2013 
2014 }  // namespace driver
2015 }  // namespace vulkan
2016