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