19d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu/* 29d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Copyright 2016 The Android Open Source Project 39d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * 49d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Licensed under the Apache License, Version 2.0 (the "License"); 59d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * you may not use this file except in compliance with the License. 69d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * You may obtain a copy of the License at 79d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * 89d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * http://www.apache.org/licenses/LICENSE-2.0 99d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * 109d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * Unless required by applicable law or agreed to in writing, software 119d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * distributed under the License is distributed on an "AS IS" BASIS, 129d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * See the License for the specific language governing permissions and 149d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu * limitations under the License. 159d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu */ 169d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu 17dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <stdlib.h> 18dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <string.h> 19dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <algorithm> 20ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu#include <array> 214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu#include <new> 22dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <malloc.h> 239d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu#include <sys/prctl.h> 249d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu 259d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu#include "driver.h" 26b7c4e3b7c97c952ba26f061d74d2038e6c94e689Jesse Hall#include "stubhal.h" 279d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu 28dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu// #define ENABLE_ALLOC_CALLSTACKS 1 29dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#if ENABLE_ALLOC_CALLSTACKS 30dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#include <utils/CallStack.h> 31dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#define ALOGD_CALLSTACK(...) \ 32dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu do { \ 33dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu ALOGD(__VA_ARGS__); \ 34dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu android::CallStack callstack; \ 35dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu callstack.update(); \ 36dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \ 37dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu } while (false) 38dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#else 39dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#define ALOGD_CALLSTACK(...) \ 40dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu do { \ 41dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu } while (false) 42dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu#endif 43dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 449d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wunamespace vulkan { 459d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wunamespace driver { 469d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu 47136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wunamespace { 48136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu 4931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wuclass Hal { 5031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu public: 5131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu static bool Open(); 5231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 5331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu static const Hal& Get() { return hal_; } 5431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu static const hwvulkan_device_t& Device() { return *Get().dev_; } 5531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 56319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu int GetDebugReportIndex() const { return debug_report_index_; } 57319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 5831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu private: 59319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu Hal() : dev_(nullptr), debug_report_index_(-1) {} 6031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu Hal(const Hal&) = delete; 6131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu Hal& operator=(const Hal&) = delete; 6231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 63319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu bool InitDebugReportIndex(); 64319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 6531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu static Hal hal_; 6631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 6731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu const hwvulkan_device_t* dev_; 68319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu int debug_report_index_; 6931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu}; 7031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuclass CreateInfoWrapper { 724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu public: 7331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu CreateInfoWrapper(const VkInstanceCreateInfo& create_info, 74ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks& allocator); 754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu CreateInfoWrapper(VkPhysicalDevice physical_dev, 764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkDeviceCreateInfo& create_info, 774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkAllocationCallbacks& allocator); 784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ~CreateInfoWrapper(); 794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 803e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult Validate(); 814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 823e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const; 833e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const; 844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 85ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu explicit operator const VkInstanceCreateInfo*() const; 864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu explicit operator const VkDeviceCreateInfo*() const; 874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu private: 894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu struct ExtensionFilter { 904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkExtensionProperties* exts; 914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu uint32_t ext_count; 924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const char** names; 944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu uint32_t name_count; 954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu }; 964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 973e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult SanitizePNext(); 984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 993e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult SanitizeLayers(); 1003e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult SanitizeExtensions(); 1014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 1023e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult QueryExtensionCount(uint32_t& count) const; 1033e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult EnumerateExtensions(uint32_t& count, 1043e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkExtensionProperties* props) const; 1053e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult InitExtensionFilter(); 1063e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu void FilterExtension(const char* name); 1074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 1084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const bool is_instance_; 1094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkAllocationCallbacks& allocator_; 1104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 11131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu VkPhysicalDevice physical_dev_; 1124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 1134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu union { 1144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkInstanceCreateInfo instance_info_; 1154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkDeviceCreateInfo dev_info_; 1164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu }; 1174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 1184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ExtensionFilter extension_filter_; 1194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 1204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_; 1214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_; 1224901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu}; 1234901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 12431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I WuHal Hal::hal_; 12531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 12631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wubool Hal::Open() { 127dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once"); 12831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 12931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu // Use a stub device unless we successfully open a real HAL device. 13031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu hal_.dev_ = &stubhal::kDevice; 13131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 13231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu const hwvulkan_module_t* module; 13331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu int result = 13431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module)); 13531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu if (result != 0) { 13631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu ALOGI("no Vulkan HAL present, using stub HAL"); 13731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return true; 13831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu } 13931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 14031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu hwvulkan_device_t* device; 14131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu result = 14231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu module->common.methods->open(&module->common, HWVULKAN_DEVICE_0, 14331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu reinterpret_cast<hw_device_t**>(&device)); 14431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu if (result != 0) { 14531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu // Any device with a Vulkan HAL should be able to open the device. 14631b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result), 14731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu result); 14831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return false; 14931b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu } 15031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 15131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu hal_.dev_ = device; 15231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 153319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu hal_.InitDebugReportIndex(); 154319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 155319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu return true; 156319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu} 157319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 158319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wubool Hal::InitDebugReportIndex() { 159319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu uint32_t count; 160319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) != 161319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu VK_SUCCESS) { 162319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu ALOGE("failed to get HAL instance extension count"); 163319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu return false; 164319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 165319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 166319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>( 167319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu malloc(sizeof(VkExtensionProperties) * count)); 168319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (!exts) { 169319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu ALOGE("failed to allocate HAL instance extension array"); 170319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu return false; 171319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 172319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 173319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) != 174319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu VK_SUCCESS) { 175319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu ALOGE("failed to enumerate HAL instance extensions"); 176319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu free(exts); 177319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu return false; 178319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 179319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 180319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu for (uint32_t i = 0; i < count; i++) { 181319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 182319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 0) { 183319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu debug_report_index_ = static_cast<int>(i); 184319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu break; 185319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 186319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 187319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 188319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu free(exts); 189319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 19031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return true; 19131b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu} 19231b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu 19331b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I WuCreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info, 194ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks& allocator) 195ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu : is_instance_(true), 196ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu allocator_(allocator), 19731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu physical_dev_(VK_NULL_HANDLE), 198ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu instance_info_(create_info), 199ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu extension_filter_() { 200ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu hook_extensions_.set(ProcHook::EXTENSION_CORE); 201ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu hal_extensions_.set(ProcHook::EXTENSION_CORE); 202ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 203ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 2044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev, 2054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkDeviceCreateInfo& create_info, 2064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkAllocationCallbacks& allocator) 2074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : is_instance_(false), 2084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator_(allocator), 2094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu physical_dev_(physical_dev), 2104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu dev_info_(create_info), 2114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu extension_filter_() { 2124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu hook_extensions_.set(ProcHook::EXTENSION_CORE); 2134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu hal_extensions_.set(ProcHook::EXTENSION_CORE); 2144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::~CreateInfoWrapper() { 2174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts); 2184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator_.pfnFree(allocator_.pUserData, extension_filter_.names); 2194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2213e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::Validate() { 2223e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult result = SanitizePNext(); 2234901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result == VK_SUCCESS) 2243e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu result = SanitizeLayers(); 2254901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result == VK_SUCCESS) 2263e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu result = SanitizeExtensions(); 2274901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2284901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 2294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuconst std::bitset<ProcHook::EXTENSION_COUNT>& 2323e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuCreateInfoWrapper::GetHookExtensions() const { 2334901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return hook_extensions_; 2344901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2354901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2364901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuconst std::bitset<ProcHook::EXTENSION_COUNT>& 2373e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuCreateInfoWrapper::GetHalExtensions() const { 2384901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return hal_extensions_; 2394901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2404901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 241ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuCreateInfoWrapper::operator const VkInstanceCreateInfo*() const { 242ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return &instance_info_; 243ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 244ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 2454901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuCreateInfoWrapper::operator const VkDeviceCreateInfo*() const { 2464901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return &dev_info_; 2474901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2484901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2493e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizePNext() { 2504901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const struct StructHeader { 2514901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkStructureType type; 2524901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const void* next; 2534901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } * header; 2544901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2554901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (is_instance_) { 2564901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header = reinterpret_cast<const StructHeader*>(instance_info_.pNext); 2574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs 2594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu while (header && 2604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO) 2614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header = reinterpret_cast<const StructHeader*>(header->next); 2624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu instance_info_.pNext = header; 2644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } else { 2654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header = reinterpret_cast<const StructHeader*>(dev_info_.pNext); 2664901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs 2684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu while (header && 2694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO) 2704901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu header = reinterpret_cast<const StructHeader*>(header->next); 2714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu dev_info_.pNext = header; 2734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 2744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 2764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2783e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizeLayers() { 2794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames 2804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : dev_info_.ppEnabledLayerNames; 2814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount 2824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : dev_info_.enabledLayerCount; 2834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // remove all layers 2854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu layer_names = nullptr; 2864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu layer_count = 0; 2874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 2894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 2904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2913e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::SanitizeExtensions() { 2924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames 2934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : dev_info_.ppEnabledExtensionNames; 2944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount 2954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : dev_info_.enabledExtensionCount; 2964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!ext_count) 2974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 2984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 2993e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult result = InitExtensionFilter(); 3004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result != VK_SUCCESS) 3014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 3024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu for (uint32_t i = 0; i < ext_count; i++) 3043e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu FilterExtension(ext_names[i]); 3054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ext_names = extension_filter_.names; 3074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ext_count = extension_filter_.name_count; 3084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 3104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 3114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3123e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const { 3134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (is_instance_) { 31431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return Hal::Device().EnumerateInstanceExtensionProperties( 31531b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu nullptr, &count, nullptr); 3164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } else { 3174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const auto& driver = GetData(physical_dev_).driver; 3184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr, 3194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu &count, nullptr); 3204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 3214901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 3224901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3233e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::EnumerateExtensions( 3244901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu uint32_t& count, 3254901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkExtensionProperties* props) const { 3264901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (is_instance_) { 32731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return Hal::Device().EnumerateInstanceExtensionProperties( 32831b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu nullptr, &count, props); 3294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } else { 3304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const auto& driver = GetData(physical_dev_).driver; 3314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr, 3324901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu &count, props); 3334901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 3344901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 3354901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3363e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I WuVkResult CreateInfoWrapper::InitExtensionFilter() { 3374901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // query extension count 3384901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu uint32_t count; 3393e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult result = QueryExtensionCount(count); 3404901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result != VK_SUCCESS || count == 0) 3414901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 3424901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3434901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& filter = extension_filter_; 3444901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu filter.exts = 3454901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation( 3464901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator_.pUserData, sizeof(VkExtensionProperties) * count, 3474901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu alignof(VkExtensionProperties), 3484901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); 3494901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!filter.exts) 3504901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 3514901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3524901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // enumerate extensions 3533e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu result = EnumerateExtensions(count, filter.exts); 3544901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result != VK_SUCCESS && result != VK_INCOMPLETE) 3554901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 3564901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!count) 3584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 3594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu filter.ext_count = count; 3614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // allocate name array 3634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu uint32_t enabled_ext_count = (is_instance_) 3644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ? instance_info_.enabledExtensionCount 3654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu : dev_info_.enabledExtensionCount; 3664901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu count = std::min(filter.ext_count, enabled_ext_count); 3674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation( 3684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator_.pUserData, sizeof(const char*) * count, alignof(const char*), 3694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); 3704901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!filter.names) 3714901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 3724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 3744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 3754901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3763e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wuvoid CreateInfoWrapper::FilterExtension(const char* name) { 3774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu auto& filter = extension_filter_; 3784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 3794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ProcHook::Extension ext_bit = GetProcHookExtension(name); 3804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (is_instance_) { 3814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu switch (ext_bit) { 3824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::KHR_android_surface: 3834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::KHR_surface: 3844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu hook_extensions_.set(ext_bit); 3854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // return now as these extensions do not require HAL support 3864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return; 3874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::EXT_debug_report: 3884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // both we and HAL can take part in 3894901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu hook_extensions_.set(ext_bit); 3904901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu break; 3914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::EXTENSION_UNKNOWN: 3924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // HAL's extensions 3934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu break; 3944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu default: 3954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ALOGW("Ignored invalid instance extension %s", name); 3964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return; 3974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 3984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } else { 3994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu switch (ext_bit) { 4004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::KHR_swapchain: 4014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // map VK_KHR_swapchain to VK_ANDROID_native_buffer 4024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME; 4034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ext_bit = ProcHook::ANDROID_native_buffer; 4044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu break; 4054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu case ProcHook::EXTENSION_UNKNOWN: 4064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // HAL's extensions 4074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu break; 4084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu default: 4094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu ALOGW("Ignored invalid device extension %s", name); 4104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return; 4114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 4124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 4134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 4144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu for (uint32_t i = 0; i < filter.ext_count; i++) { 4154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkExtensionProperties& props = filter.exts[i]; 4164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // ignore unknown extensions 4174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (strcmp(name, props.extensionName) != 0) 4184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu continue; 4194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 4204901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu filter.names[filter.name_count++] = name; 4211600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu if (ext_bit != ProcHook::EXTENSION_UNKNOWN) { 4221600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu if (ext_bit == ProcHook::ANDROID_native_buffer) 4231600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu hook_extensions_.set(ProcHook::KHR_swapchain); 4241600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu 4251600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu hal_extensions_.set(ext_bit); 4261600e269dbf9f2cd818886c55b3e0933dfec7a86Chia-I Wu } 4274901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 4284901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu break; 4294901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 4304901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 4314901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 432dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void* DefaultAllocate(void*, 433dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu size_t size, 434dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu size_t alignment, 435dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu VkSystemAllocationScope) { 436dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu void* ptr = nullptr; 437dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // Vulkan requires 'alignment' to be a power of two, but posix_memalign 438dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // additionally requires that it be at least sizeof(void*). 439dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size); 440dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment, 441dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu ret, ptr); 442dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return ret == 0 ? ptr : nullptr; 443dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu} 444dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 445dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void* DefaultReallocate(void*, 446dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu void* ptr, 447dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu size_t size, 448dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu size_t alignment, 449dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu VkSystemAllocationScope) { 450dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu if (size == 0) { 451dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu free(ptr); 452dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return nullptr; 453dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu } 454dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 455dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // TODO(jessehall): Right now we never shrink allocations; if the new 456dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // request is smaller than the existing chunk, we just continue using it. 457dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // Right now the loader never reallocs, so this doesn't matter. If that 458dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // changes, or if this code is copied into some other project, this should 459dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // probably have a heuristic to allocate-copy-free when doing so will save 460dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu // "enough" space. 461dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu size_t old_size = ptr ? malloc_usable_size(ptr) : 0; 462dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu if (size <= old_size) 463dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return ptr; 464dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 465dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu void* new_ptr = nullptr; 466dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0) 467dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return nullptr; 468dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu if (ptr) { 469dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu memcpy(new_ptr, ptr, std::min(old_size, size)); 470dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu free(ptr); 471dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu } 472dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return new_ptr; 473dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu} 474dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 475dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I WuVKAPI_ATTR void DefaultFree(void*, void* ptr) { 476dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu ALOGD_CALLSTACK("Free: %p", ptr); 477dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu free(ptr); 478dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu} 479dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 480ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuInstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) { 481ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu void* data_mem = allocator.pfnAllocation( 482ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu allocator.pUserData, sizeof(InstanceData), alignof(InstanceData), 483ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 484ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!data_mem) 485ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return nullptr; 486ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 487ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return new (data_mem) InstanceData(allocator); 488ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 489ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 490ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wuvoid FreeInstanceData(InstanceData* data, 491ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks& allocator) { 492ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data->~InstanceData(); 493ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu allocator.pfnFree(allocator.pUserData, data); 494ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 495ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 496950d6e1102077d6a3905eb77268800002e792fb0Chia-I WuDeviceData* AllocateDeviceData( 497950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu const VkAllocationCallbacks& allocator, 498950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu const DebugReportCallbackList& debug_report_callbacks) { 4994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu void* data_mem = allocator.pfnAllocation( 5004901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator.pUserData, sizeof(DeviceData), alignof(DeviceData), 5014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 5024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!data_mem) 5034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return nullptr; 5044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 505950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu return new (data_mem) DeviceData(allocator, debug_report_callbacks); 5064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 5074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 5084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuvoid FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) { 5094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu data->~DeviceData(); 5104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu allocator.pfnFree(allocator.pUserData, data); 5114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 5124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 513136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu} // anonymous namespace 514136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu 5159d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wubool Debuggable() { 5169d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0); 5179d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu} 5189d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu 519136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wubool OpenHAL() { 52031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return Hal::Open(); 521136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu} 522136b8eb38e98d96009799eee59d4ea0088544b54Chia-I Wu 523dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wuconst VkAllocationCallbacks& GetDefaultAllocator() { 524dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu static const VkAllocationCallbacks kDefaultAllocCallbacks = { 525dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu .pUserData = nullptr, 526dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu .pfnAllocation = DefaultAllocate, 527dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu .pfnReallocation = DefaultReallocate, 528dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu .pfnFree = DefaultFree, 529dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu }; 530dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 531dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu return kDefaultAllocCallbacks; 532dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu} 533dbb7e9c8f950ad344eee22cc50acc67253f9f4b1Chia-I Wu 534eb7db124e46da9a9210cf868353f5ea79502ffecChia-I WuPFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { 535eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu const ProcHook* hook = GetProcHook(pName); 536eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu if (!hook) 53731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu return Hal::Device().GetInstanceProcAddr(instance, pName); 538eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 539eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu if (!instance) { 540eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu if (hook->type == ProcHook::GLOBAL) 541eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu return hook->proc; 542eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 543109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu // v0 layers expect 544109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu // 545109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice"); 546109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu // 547109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu // to work. 548109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu if (strcmp(pName, "vkCreateDevice") == 0) 549109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu return hook->proc; 550109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu 551eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu ALOGE( 552e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu "internal vkGetInstanceProcAddr called for %s without an instance", 553eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu pName); 554eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 555109f8985ceaf746fd04b6fe81be238b3865062b7Chia-I Wu return nullptr; 556eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu } 557eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 558eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu PFN_vkVoidFunction proc; 559eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 560eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu switch (hook->type) { 561eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu case ProcHook::INSTANCE: 562eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu proc = (GetData(instance).hook_extensions[hook->extension]) 563eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu ? hook->proc 56436cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu : nullptr; 565eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu break; 566eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu case ProcHook::DEVICE: 567eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu proc = (hook->extension == ProcHook::EXTENSION_CORE) 568eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu ? hook->proc 569eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu : hook->checked_proc; 570eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu break; 571eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu default: 572eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu ALOGE( 573e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu "internal vkGetInstanceProcAddr called for %s with an instance", 574eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu pName); 575eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu proc = nullptr; 576eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu break; 577eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu } 578eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 579eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu return proc; 580eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu} 581eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 582eb7db124e46da9a9210cf868353f5ea79502ffecChia-I WuPFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { 583eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu const ProcHook* hook = GetProcHook(pName); 584eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu if (!hook) 585cc5e2765a9d56b03b69d0c3f25b94721f82d034eChia-I Wu return GetData(device).driver.GetDeviceProcAddr(device, pName); 586eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 587eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu if (hook->type != ProcHook::DEVICE) { 588e201c3f782f0d3e2ec508fb8093e506145614c06Chia-I Wu ALOGE("internal vkGetDeviceProcAddr called for %s", pName); 589eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu return nullptr; 590eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu } 591eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 59236cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu return (GetData(device).hook_extensions[hook->extension]) ? hook->proc 59336cc00a1739f7d926cc20671ae9900a5460dd6aeChia-I Wu : nullptr; 594eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu} 595eb7db124e46da9a9210cf868353f5ea79502ffecChia-I Wu 596ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult EnumerateInstanceExtensionProperties( 597ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const char* pLayerName, 598ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu uint32_t* pPropertyCount, 599ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkExtensionProperties* pProperties) { 600ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu static const std::array<VkExtensionProperties, 2> loader_extensions = {{ 601ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu // WSI extensions 602ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION}, 603ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 604ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VK_KHR_ANDROID_SURFACE_SPEC_VERSION}, 605ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu }}; 606319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu static const VkExtensionProperties loader_debug_report_extension = { 607319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION, 608319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu }; 609ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 610ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu // enumerate our extensions first 611ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!pLayerName && pProperties) { 612ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu uint32_t count = std::min( 613ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu *pPropertyCount, static_cast<uint32_t>(loader_extensions.size())); 614ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 615ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu std::copy_n(loader_extensions.begin(), count, pProperties); 616ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 617ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (count < loader_extensions.size()) { 618ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu *pPropertyCount = count; 619ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return VK_INCOMPLETE; 620ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 621ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 622ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu pProperties += count; 623ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu *pPropertyCount -= count; 624319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 625319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (Hal::Get().GetDebugReportIndex() < 0) { 626319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (!*pPropertyCount) { 627319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu *pPropertyCount = count; 628319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu return VK_INCOMPLETE; 629319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 630319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 631319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu pProperties[0] = loader_debug_report_extension; 632319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu pProperties += 1; 633319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu *pPropertyCount -= 1; 634319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 635ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 636ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 63731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu VkResult result = Hal::Device().EnumerateInstanceExtensionProperties( 638ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu pLayerName, pPropertyCount, pProperties); 639ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 640319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) { 641319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu int idx = Hal::Get().GetDebugReportIndex(); 642319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu if (idx < 0) { 643319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu *pPropertyCount += 1; 644319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } else if (pProperties && 645319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu static_cast<uint32_t>(idx) < *pPropertyCount) { 646319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu pProperties[idx].specVersion = 647319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu std::min(pProperties[idx].specVersion, 648319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu loader_debug_report_extension.specVersion); 649319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 650319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu 651ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu *pPropertyCount += loader_extensions.size(); 652319382517afe913285df5bbf76a8a484e6adfbd0Chia-I Wu } 653ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 654ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return result; 655ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 656ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 65701cf305325f3789c573d7eff435e409f04677c66Chia-I WuVkResult EnumerateDeviceExtensionProperties( 65801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu VkPhysicalDevice physicalDevice, 65901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu const char* pLayerName, 66001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu uint32_t* pPropertyCount, 66101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu VkExtensionProperties* pProperties) { 66201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu const InstanceData& data = GetData(physicalDevice); 66301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 66401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu VkResult result = data.driver.EnumerateDeviceExtensionProperties( 66501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu physicalDevice, pLayerName, pPropertyCount, pProperties); 66601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu if (result != VK_SUCCESS && result != VK_INCOMPLETE) 66701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu return result; 66801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 66901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu if (!pProperties) 67001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu return result; 67101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 67201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu // map VK_ANDROID_native_buffer to VK_KHR_swapchain 67301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu for (uint32_t i = 0; i < *pPropertyCount; i++) { 67401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu auto& prop = pProperties[i]; 67501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 67601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu if (strcmp(prop.extensionName, 67701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0) 67801cf305325f3789c573d7eff435e409f04677c66Chia-I Wu continue; 67901cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 68001cf305325f3789c573d7eff435e409f04677c66Chia-I Wu memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME, 68101cf305325f3789c573d7eff435e409f04677c66Chia-I Wu sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); 68201cf305325f3789c573d7eff435e409f04677c66Chia-I Wu prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION; 68301cf305325f3789c573d7eff435e409f04677c66Chia-I Wu } 68401cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 68501cf305325f3789c573d7eff435e409f04677c66Chia-I Wu return result; 68601cf305325f3789c573d7eff435e409f04677c66Chia-I Wu} 68701cf305325f3789c573d7eff435e409f04677c66Chia-I Wu 688ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, 689ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks* pAllocator, 690ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkInstance* pInstance) { 691ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks& data_allocator = 692ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu (pAllocator) ? *pAllocator : GetDefaultAllocator(); 693ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 69431b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu CreateInfoWrapper wrapper(*pCreateInfo, data_allocator); 6953e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult result = wrapper.Validate(); 696ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (result != VK_SUCCESS) 697ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return result; 698ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 699ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu InstanceData* data = AllocateInstanceData(data_allocator); 700ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!data) 701ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 702ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 7033e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu data->hook_extensions |= wrapper.GetHookExtensions(); 704ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 705ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu // call into the driver 706ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkInstance instance; 70731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu result = Hal::Device().CreateInstance( 708ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator, 709ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu &instance); 710ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (result != VK_SUCCESS) { 711ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu FreeInstanceData(data, data_allocator); 712ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return result; 713ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 714ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 715ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu // initialize InstanceDriverTable 716ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!SetData(instance, *data) || 71731b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr, 718cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu wrapper.GetHalExtensions())) { 719ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>( 72031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance")); 721ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (data->driver.DestroyInstance) 722ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data->driver.DestroyInstance(instance, pAllocator); 723ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 724ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu FreeInstanceData(data, data_allocator); 725ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 726ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return VK_ERROR_INCOMPATIBLE_DRIVER; 727ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 728ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 729ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>( 73031b2e4f01d31aae107340cbc4221b8d49fb42767Chia-I Wu Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr")); 731ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!data->get_device_proc_addr) { 732ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data->driver.DestroyInstance(instance, pAllocator); 733ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu FreeInstanceData(data, data_allocator); 734ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 735ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return VK_ERROR_INCOMPATIBLE_DRIVER; 736ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 737ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 738ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu *pInstance = instance; 739ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 740ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return VK_SUCCESS; 741ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 742ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 743ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wuvoid DestroyInstance(VkInstance instance, 744ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const VkAllocationCallbacks* pAllocator) { 745ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu InstanceData& data = GetData(instance); 746ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu data.driver.DestroyInstance(instance, pAllocator); 747ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 748ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkAllocationCallbacks local_allocator; 749ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if (!pAllocator) { 750ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu local_allocator = data.allocator; 751ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu pAllocator = &local_allocator; 752ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 753ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 754ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu FreeInstanceData(&data, *pAllocator); 755ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 756ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 7574901db70b12801cf1966937a58eb7566bfdeb4ceChia-I WuVkResult CreateDevice(VkPhysicalDevice physicalDevice, 7584901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkDeviceCreateInfo* pCreateInfo, 7594901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkAllocationCallbacks* pAllocator, 7604901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkDevice* pDevice) { 7614901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const InstanceData& instance_data = GetData(physicalDevice); 7624901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu const VkAllocationCallbacks& data_allocator = 7634901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu (pAllocator) ? *pAllocator : instance_data.allocator; 7644901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7654901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator); 7663e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu VkResult result = wrapper.Validate(); 7674901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result != VK_SUCCESS) 7684901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 7694901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 770950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu DeviceData* data = AllocateDeviceData(data_allocator, 771950d6e1102077d6a3905eb77268800002e792fb0Chia-I Wu instance_data.debug_report_callbacks); 7724901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!data) 7734901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 7744901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7753e6c2d6889d9c1bc7eb4dbd9774d861c18a21a80Chia-I Wu data->hook_extensions |= wrapper.GetHookExtensions(); 7764901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7774901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // call into the driver 7784901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkDevice dev; 7794901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu result = instance_data.driver.CreateDevice( 7804901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper), 7814901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu pAllocator, &dev); 7824901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (result != VK_SUCCESS) { 7834901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu FreeDeviceData(data, data_allocator); 7844901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return result; 7854901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 7864901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7874901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu // initialize DeviceDriverTable 7884901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!SetData(dev, *data) || 789cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu !InitDriverTable(dev, instance_data.get_device_proc_addr, 790cbe07ef239121dc99a31a19b9593d76d76abb08bChia-I Wu wrapper.GetHalExtensions())) { 7914901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>( 7924901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu instance_data.get_device_proc_addr(dev, "vkDestroyDevice")); 7934901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (data->driver.DestroyDevice) 7944901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu data->driver.DestroyDevice(dev, pAllocator); 7954901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7964901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu FreeDeviceData(data, data_allocator); 7974901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 7984901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_ERROR_INCOMPATIBLE_DRIVER; 7994901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 800dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall data->driver_device = dev; 8014901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 8024901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu *pDevice = dev; 8034901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 8044901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu return VK_SUCCESS; 8054901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 8064901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 8074901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wuvoid DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { 8084901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu DeviceData& data = GetData(device); 8094901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu data.driver.DestroyDevice(device, pAllocator); 8104901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 8114901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu VkAllocationCallbacks local_allocator; 8124901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu if (!pAllocator) { 8134901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu local_allocator = data.allocator; 8144901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu pAllocator = &local_allocator; 8154901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu } 8164901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 8174901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu FreeDeviceData(&data, *pAllocator); 8184901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu} 8194901db70b12801cf1966937a58eb7566bfdeb4ceChia-I Wu 820ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I WuVkResult EnumeratePhysicalDevices(VkInstance instance, 821ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu uint32_t* pPhysicalDeviceCount, 822ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkPhysicalDevice* pPhysicalDevices) { 823ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu const auto& data = GetData(instance); 824ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 825ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu VkResult result = data.driver.EnumeratePhysicalDevices( 826ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu instance, pPhysicalDeviceCount, pPhysicalDevices); 827ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) { 828ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) 829ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu SetData(pPhysicalDevices[i], data); 830ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu } 831ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 832ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu return result; 833ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu} 834ff4a6c772aaf3ff0b71348647330031a059b1f51Chia-I Wu 835ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wuvoid GetDeviceQueue(VkDevice device, 836ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu uint32_t queueFamilyIndex, 837ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu uint32_t queueIndex, 838ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu VkQueue* pQueue) { 839ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu const auto& data = GetData(device); 840ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu 841ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 842ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu SetData(*pQueue, data); 843ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu} 844ba0be41afe39dcbed0a712a32d1ab6c341797007Chia-I Wu 8456a58a8a7813450038cb15575e3333b83f268c972Chia-I WuVKAPI_ATTR VkResult 8466a58a8a7813450038cb15575e3333b83f268c972Chia-I WuAllocateCommandBuffers(VkDevice device, 8476a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu const VkCommandBufferAllocateInfo* pAllocateInfo, 8486a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu VkCommandBuffer* pCommandBuffers) { 8496a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu const auto& data = GetData(device); 8506a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu 8516a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo, 8526a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu pCommandBuffers); 8536a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu if (result == VK_SUCCESS) { 8546a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) 8556a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu SetData(pCommandBuffers[i], data); 8566a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu } 8576a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu 8586a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu return result; 8596a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu} 8606a58a8a7813450038cb15575e3333b83f268c972Chia-I Wu 8619d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu} // namespace driver 8629d51816145b008b7b4b091a8c90faf30ba0394e4Chia-I Wu} // namespace vulkan 863