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