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