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