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