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