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