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