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