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