blob: 681a289c1fca8cb4c61f82eb0e631c5d441ea55e [file] [log] [blame]
Chia-I Wu9d518162016-03-24 14:55:27 +08001/*
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
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
Mark Salyzyn7823e122016-09-29 08:08:05 -070019#include <malloc.h>
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080020#include <stdlib.h>
21#include <string.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070022#include <sys/prctl.h>
23
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -080024#include <dlfcn.h>
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080025#include <algorithm>
Chia-I Wuff4a6c72016-03-24 16:05:56 +080026#include <array>
Chia-I Wu4901db72016-03-24 16:38:58 +080027#include <new>
Mark Salyzyn7823e122016-09-29 08:08:05 -070028
29#include <log/log.h>
Chia-I Wu9d518162016-03-24 14:55:27 +080030
Jesse Hall53457db2016-12-14 16:54:06 -080031#include <android/dlext.h>
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080032#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
33#include <configstore/Utils.h>
Jesse Hall53457db2016-12-14 16:54:06 -080034#include <cutils/properties.h>
Jiyong Park27c39e12017-05-08 13:00:02 +090035#include <graphicsenv/GraphicsEnv.h>
Yiwei Zhangd9861812019-02-13 11:51:55 -080036#include <utils/Timers.h>
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -080037#include <utils/Trace.h>
Chris Forbesfa25e632017-02-22 12:36:02 +130038#include <utils/Vector.h>
Jesse Hall53457db2016-12-14 16:54:06 -080039
Wei Wangf9b05ee2017-07-19 20:59:39 -070040#include "android-base/properties.h"
41
Chia-I Wu9d518162016-03-24 14:55:27 +080042#include "driver.h"
Jesse Hallb7c4e3b2016-04-11 13:51:38 -070043#include "stubhal.h"
Chia-I Wu9d518162016-03-24 14:55:27 +080044
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080045using namespace android::hardware::configstore;
46using namespace android::hardware::configstore::V1_0;
47
Jesse Hall00e61ff2017-04-07 16:48:02 -070048// TODO(b/37049319) Get this from a header once one exists
49extern "C" {
50android_namespace_t* android_get_exported_namespace(const char*);
51}
52
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080053// #define ENABLE_ALLOC_CALLSTACKS 1
54#if ENABLE_ALLOC_CALLSTACKS
55#include <utils/CallStack.h>
56#define ALOGD_CALLSTACK(...) \
57 do { \
58 ALOGD(__VA_ARGS__); \
59 android::CallStack callstack; \
60 callstack.update(); \
61 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
62 } while (false)
63#else
64#define ALOGD_CALLSTACK(...) \
65 do { \
66 } while (false)
67#endif
68
Chia-I Wu9d518162016-03-24 14:55:27 +080069namespace vulkan {
70namespace driver {
71
Chia-I Wu136b8eb2016-03-24 15:01:52 +080072namespace {
73
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080074class Hal {
75 public:
76 static bool Open();
77
78 static const Hal& Get() { return hal_; }
79 static const hwvulkan_device_t& Device() { return *Get().dev_; }
80
Chia-I Wu31938252016-05-23 15:31:02 +080081 int GetDebugReportIndex() const { return debug_report_index_; }
82
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080083 private:
Chia-I Wu31938252016-05-23 15:31:02 +080084 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080085 Hal(const Hal&) = delete;
86 Hal& operator=(const Hal&) = delete;
87
Chia-I Wu31938252016-05-23 15:31:02 +080088 bool InitDebugReportIndex();
89
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080090 static Hal hal_;
91
92 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080093 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080094};
95
Chia-I Wu4901db72016-03-24 16:38:58 +080096class CreateInfoWrapper {
97 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080098 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080099 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +0800100 CreateInfoWrapper(VkPhysicalDevice physical_dev,
101 const VkDeviceCreateInfo& create_info,
102 const VkAllocationCallbacks& allocator);
103 ~CreateInfoWrapper();
104
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800105 VkResult Validate();
Ian Elliottf3e872d2017-11-02 10:15:13 -0600106 void DowngradeApiVersion();
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700107 void UpgradeDeviceCoreApiVersion(uint32_t api_version);
Chia-I Wu4901db72016-03-24 16:38:58 +0800108
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800109 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
110 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800111
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800112 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800113 explicit operator const VkDeviceCreateInfo*() const;
114
115 private:
116 struct ExtensionFilter {
117 VkExtensionProperties* exts;
118 uint32_t ext_count;
119
120 const char** names;
121 uint32_t name_count;
122 };
123
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800124 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800125
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800126 VkResult SanitizeLayers();
127 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800128
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800129 VkResult QueryExtensionCount(uint32_t& count) const;
130 VkResult EnumerateExtensions(uint32_t& count,
131 VkExtensionProperties* props) const;
132 VkResult InitExtensionFilter();
133 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800134
135 const bool is_instance_;
136 const VkAllocationCallbacks& allocator_;
137
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800138 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800139
140 union {
141 VkInstanceCreateInfo instance_info_;
142 VkDeviceCreateInfo dev_info_;
143 };
144
Ian Elliottf3e872d2017-11-02 10:15:13 -0600145 VkApplicationInfo application_info_;
146
Chia-I Wu4901db72016-03-24 16:38:58 +0800147 ExtensionFilter extension_filter_;
148
149 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
150 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
151};
152
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800153Hal Hal::hal_;
154
Jesse Hall53457db2016-12-14 16:54:06 -0800155void* LoadLibrary(const android_dlextinfo& dlextinfo,
156 const char* subname,
157 int subname_len) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800158 ATRACE_CALL();
159
Jesse Hall53457db2016-12-14 16:54:06 -0800160 const char kLibFormat[] = "vulkan.%*s.so";
161 char* name = static_cast<char*>(
162 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
163 sprintf(name, kLibFormat, subname_len, subname);
164 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
165}
166
167const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
168 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
169 "ro.board.platform",
170}};
171
Jesse Hall00e61ff2017-04-07 16:48:02 -0700172int LoadDriver(android_namespace_t* library_namespace,
173 const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800174 ATRACE_CALL();
175
Jesse Hall53457db2016-12-14 16:54:06 -0800176 const android_dlextinfo dlextinfo = {
177 .flags = ANDROID_DLEXT_USE_NAMESPACE,
Jesse Hall00e61ff2017-04-07 16:48:02 -0700178 .library_namespace = library_namespace,
Jesse Hall53457db2016-12-14 16:54:06 -0800179 };
Jesse Hall53457db2016-12-14 16:54:06 -0800180 void* so = nullptr;
181 char prop[PROPERTY_VALUE_MAX];
182 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
183 int prop_len = property_get(key, prop, nullptr);
184 if (prop_len > 0) {
185 so = LoadLibrary(dlextinfo, prop, prop_len);
186 if (so)
187 break;
188 }
189 }
190 if (!so)
191 return -ENOENT;
192
Jesse Hall00e61ff2017-04-07 16:48:02 -0700193 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800194 if (!hmi) {
195 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
196 dlclose(so);
197 return -EINVAL;
198 }
199 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
200 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
201 dlclose(so);
202 return -EINVAL;
203 }
204 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700205 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800206 return 0;
207}
208
Jesse Hall00e61ff2017-04-07 16:48:02 -0700209int LoadBuiltinDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800210 ATRACE_CALL();
211
Jesse Hall00e61ff2017-04-07 16:48:02 -0700212 auto ns = android_get_exported_namespace("sphal");
213 if (!ns)
214 return -ENOENT;
Yiwei Zhangd9861812019-02-13 11:51:55 -0800215 android::GraphicsEnv::getInstance().setDriverToLoad(
216 android::GraphicsEnv::Driver::VULKAN);
Jesse Hall00e61ff2017-04-07 16:48:02 -0700217 return LoadDriver(ns, module);
218}
219
220int LoadUpdatedDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800221 ATRACE_CALL();
222
Jesse Hall00e61ff2017-04-07 16:48:02 -0700223 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
224 if (!ns)
225 return -ENOENT;
Yiwei Zhangd9861812019-02-13 11:51:55 -0800226 android::GraphicsEnv::getInstance().setDriverToLoad(
227 android::GraphicsEnv::Driver::VULKAN_UPDATED);
Jesse Hall00e61ff2017-04-07 16:48:02 -0700228 return LoadDriver(ns, module);
229}
230
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800231bool Hal::Open() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800232 ATRACE_CALL();
233
Yiwei Zhangd9861812019-02-13 11:51:55 -0800234 const nsecs_t openTime = systemTime();
235
Jesse Halldc225072016-05-30 22:40:14 -0700236 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800237
238 // Use a stub device unless we successfully open a real HAL device.
239 hal_.dev_ = &stubhal::kDevice;
240
Jesse Hall53457db2016-12-14 16:54:06 -0800241 int result;
242 const hwvulkan_module_t* module = nullptr;
243
Jesse Hall00e61ff2017-04-07 16:48:02 -0700244 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800245 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700246 result = LoadBuiltinDriver(&module);
247 if (result != 0) {
248 // -ENOENT means the sphal namespace doesn't exist, not that there
249 // is a problem with the driver.
250 ALOGW_IF(
251 result != -ENOENT,
252 "Failed to load Vulkan driver into sphal namespace. This "
253 "usually means the driver has forbidden library dependencies."
254 "Please fix, this will soon stop working.");
255 result =
256 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
257 reinterpret_cast<const hw_module_t**>(&module));
258 }
Jesse Hall53457db2016-12-14 16:54:06 -0800259 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800260 if (result != 0) {
Yiwei Zhangd9861812019-02-13 11:51:55 -0800261 android::GraphicsEnv::getInstance().setDriverLoaded(
262 android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
Jesse Hall53457db2016-12-14 16:54:06 -0800263 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800264 return true;
265 }
266
Yiwei Zhangcb9d4e42019-02-06 20:22:59 -0800267
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800268 hwvulkan_device_t* device;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800269 ATRACE_BEGIN("hwvulkan module open");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800270 result =
271 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
272 reinterpret_cast<hw_device_t**>(&device));
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800273 ATRACE_END();
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800274 if (result != 0) {
Yiwei Zhangd9861812019-02-13 11:51:55 -0800275 android::GraphicsEnv::getInstance().setDriverLoaded(
276 android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800277 // Any device with a Vulkan HAL should be able to open the device.
278 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
279 result);
280 return false;
281 }
282
283 hal_.dev_ = device;
284
Chia-I Wu31938252016-05-23 15:31:02 +0800285 hal_.InitDebugReportIndex();
286
Yiwei Zhangd9861812019-02-13 11:51:55 -0800287 android::GraphicsEnv::getInstance().setDriverLoaded(
288 android::GraphicsEnv::Api::API_VK, true, systemTime() - openTime);
289
Chia-I Wu31938252016-05-23 15:31:02 +0800290 return true;
291}
292
293bool Hal::InitDebugReportIndex() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800294 ATRACE_CALL();
295
Chia-I Wu31938252016-05-23 15:31:02 +0800296 uint32_t count;
297 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
298 VK_SUCCESS) {
299 ALOGE("failed to get HAL instance extension count");
300 return false;
301 }
302
303 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
304 malloc(sizeof(VkExtensionProperties) * count));
305 if (!exts) {
306 ALOGE("failed to allocate HAL instance extension array");
307 return false;
308 }
309
310 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
311 VK_SUCCESS) {
312 ALOGE("failed to enumerate HAL instance extensions");
313 free(exts);
314 return false;
315 }
316
317 for (uint32_t i = 0; i < count; i++) {
318 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
319 0) {
320 debug_report_index_ = static_cast<int>(i);
321 break;
322 }
323 }
324
325 free(exts);
326
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800327 return true;
328}
329
330CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800331 const VkAllocationCallbacks& allocator)
332 : is_instance_(true),
333 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800334 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800335 instance_info_(create_info),
336 extension_filter_() {
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700337 // instance core versions need to match the loader api version
338 for (uint32_t i = ProcHook::EXTENSION_CORE_1_0;
339 i != ProcHook::EXTENSION_COUNT; ++i) {
340 hook_extensions_.set(i);
341 hal_extensions_.set(i);
342 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800343}
344
Chia-I Wu4901db72016-03-24 16:38:58 +0800345CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
346 const VkDeviceCreateInfo& create_info,
347 const VkAllocationCallbacks& allocator)
348 : is_instance_(false),
349 allocator_(allocator),
350 physical_dev_(physical_dev),
351 dev_info_(create_info),
352 extension_filter_() {
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700353 // initialize with baseline core API version
354 hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
355 hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
Chia-I Wu4901db72016-03-24 16:38:58 +0800356}
357
358CreateInfoWrapper::~CreateInfoWrapper() {
359 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
360 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
361}
362
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800363VkResult CreateInfoWrapper::Validate() {
364 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800365 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800366 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800367 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800368 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800369
370 return result;
371}
372
373const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800374CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800375 return hook_extensions_;
376}
377
378const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800379CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800380 return hal_extensions_;
381}
382
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800383CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
384 return &instance_info_;
385}
386
Chia-I Wu4901db72016-03-24 16:38:58 +0800387CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
388 return &dev_info_;
389}
390
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800391VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800392 const struct StructHeader {
393 VkStructureType type;
394 const void* next;
395 } * header;
396
397 if (is_instance_) {
398 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
399
400 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
401 while (header &&
402 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
403 header = reinterpret_cast<const StructHeader*>(header->next);
404
405 instance_info_.pNext = header;
406 } else {
407 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
408
409 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
410 while (header &&
411 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
412 header = reinterpret_cast<const StructHeader*>(header->next);
413
414 dev_info_.pNext = header;
415 }
416
417 return VK_SUCCESS;
418}
419
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800420VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800421 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
422 : dev_info_.ppEnabledLayerNames;
423 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
424 : dev_info_.enabledLayerCount;
425
426 // remove all layers
427 layer_names = nullptr;
428 layer_count = 0;
429
430 return VK_SUCCESS;
431}
432
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800433VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800434 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
435 : dev_info_.ppEnabledExtensionNames;
436 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
437 : dev_info_.enabledExtensionCount;
438 if (!ext_count)
439 return VK_SUCCESS;
440
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800441 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800442 if (result != VK_SUCCESS)
443 return result;
444
445 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800446 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800447
Jesse Halld3d887a2018-03-05 13:34:45 -0800448 // Enable device extensions that contain physical-device commands, so that
449 // vkGetInstanceProcAddr will return those physical-device commands.
450 if (is_instance_) {
451 hook_extensions_.set(ProcHook::KHR_swapchain);
452 }
453
Chia-I Wu4901db72016-03-24 16:38:58 +0800454 ext_names = extension_filter_.names;
455 ext_count = extension_filter_.name_count;
456
457 return VK_SUCCESS;
458}
459
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800460VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800461 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800462 return Hal::Device().EnumerateInstanceExtensionProperties(
463 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800464 } else {
465 const auto& driver = GetData(physical_dev_).driver;
466 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
467 &count, nullptr);
468 }
469}
470
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800471VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800472 uint32_t& count,
473 VkExtensionProperties* props) const {
474 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800475 return Hal::Device().EnumerateInstanceExtensionProperties(
476 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800477 } else {
478 const auto& driver = GetData(physical_dev_).driver;
479 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
480 &count, props);
481 }
482}
483
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800484VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800485 // query extension count
486 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800487 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800488 if (result != VK_SUCCESS || count == 0)
489 return result;
490
491 auto& filter = extension_filter_;
492 filter.exts =
493 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
494 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
495 alignof(VkExtensionProperties),
496 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
497 if (!filter.exts)
498 return VK_ERROR_OUT_OF_HOST_MEMORY;
499
500 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800501 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800502 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
503 return result;
504
505 if (!count)
506 return VK_SUCCESS;
507
508 filter.ext_count = count;
509
510 // allocate name array
511 uint32_t enabled_ext_count = (is_instance_)
512 ? instance_info_.enabledExtensionCount
513 : dev_info_.enabledExtensionCount;
514 count = std::min(filter.ext_count, enabled_ext_count);
515 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
516 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
517 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
518 if (!filter.names)
519 return VK_ERROR_OUT_OF_HOST_MEMORY;
520
521 return VK_SUCCESS;
522}
523
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800524void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800525 auto& filter = extension_filter_;
526
527 ProcHook::Extension ext_bit = GetProcHookExtension(name);
528 if (is_instance_) {
529 switch (ext_bit) {
530 case ProcHook::KHR_android_surface:
531 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700532 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300533 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800534 hook_extensions_.set(ext_bit);
535 // return now as these extensions do not require HAL support
536 return;
537 case ProcHook::EXT_debug_report:
538 // both we and HAL can take part in
539 hook_extensions_.set(ext_bit);
540 break;
Chris Forbes6aa30db2017-02-20 17:12:53 +1300541 case ProcHook::KHR_get_physical_device_properties2:
Jesse Hall7f983a82018-03-29 14:46:45 -0700542 case ProcHook::EXTENSION_UNKNOWN:
543 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800544 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700545
Yiwei Zhang23143102019-04-10 18:24:05 -0700546 case ProcHook::KHR_bind_memory2:
Jesse Hall7f983a82018-03-29 14:46:45 -0700547 case ProcHook::KHR_incremental_present:
548 case ProcHook::KHR_shared_presentable_image:
549 case ProcHook::KHR_swapchain:
550 case ProcHook::EXT_hdr_metadata:
551 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
552 case ProcHook::ANDROID_native_buffer:
553 case ProcHook::GOOGLE_display_timing:
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700554 case ProcHook::EXTENSION_CORE_1_0:
555 case ProcHook::EXTENSION_CORE_1_1:
Jesse Hall7f983a82018-03-29 14:46:45 -0700556 case ProcHook::EXTENSION_COUNT:
557 // Device and meta extensions. If we ever get here it's a bug in
558 // our code. But enumerating them lets us avoid having a default
559 // case, and default hides other bugs.
560 ALOGE(
561 "CreateInfoWrapper::FilterExtension: invalid instance "
562 "extension '%s'. FIX ME",
563 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800564 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700565
566 // Don't use a default case. Without it, -Wswitch will tell us
567 // at compile time if someone adds a new ProcHook extension but
568 // doesn't handle it above. That's a real bug that has
569 // not-immediately-obvious effects.
570 //
571 // default:
572 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800573 }
574 } else {
575 switch (ext_bit) {
576 case ProcHook::KHR_swapchain:
577 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
578 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
579 ext_bit = ProcHook::ANDROID_native_buffer;
580 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700581 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700582 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300583 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700584 hook_extensions_.set(ext_bit);
585 // return now as these extensions do not require HAL support
586 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700587 case ProcHook::EXT_hdr_metadata:
Yiwei Zhang23143102019-04-10 18:24:05 -0700588 case ProcHook::KHR_bind_memory2:
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700589 hook_extensions_.set(ext_bit);
590 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700591 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
Chia-I Wu4901db72016-03-24 16:38:58 +0800592 case ProcHook::EXTENSION_UNKNOWN:
Jesse Hall7f983a82018-03-29 14:46:45 -0700593 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800594 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700595
596 case ProcHook::KHR_android_surface:
597 case ProcHook::KHR_get_physical_device_properties2:
598 case ProcHook::KHR_get_surface_capabilities2:
599 case ProcHook::KHR_surface:
600 case ProcHook::EXT_debug_report:
601 case ProcHook::EXT_swapchain_colorspace:
602 case ProcHook::ANDROID_native_buffer:
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700603 case ProcHook::EXTENSION_CORE_1_0:
604 case ProcHook::EXTENSION_CORE_1_1:
Jesse Hall7f983a82018-03-29 14:46:45 -0700605 case ProcHook::EXTENSION_COUNT:
606 // Instance and meta extensions. If we ever get here it's a bug
607 // in our code. But enumerating them lets us avoid having a
608 // default case, and default hides other bugs.
609 ALOGE(
610 "CreateInfoWrapper::FilterExtension: invalid device "
611 "extension '%s'. FIX ME",
612 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800613 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700614
615 // Don't use a default case. Without it, -Wswitch will tell us
616 // at compile time if someone adds a new ProcHook extension but
617 // doesn't handle it above. That's a real bug that has
618 // not-immediately-obvious effects.
619 //
620 // default:
621 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800622 }
623 }
624
625 for (uint32_t i = 0; i < filter.ext_count; i++) {
626 const VkExtensionProperties& props = filter.exts[i];
627 // ignore unknown extensions
628 if (strcmp(name, props.extensionName) != 0)
629 continue;
630
Chia-I Wu4901db72016-03-24 16:38:58 +0800631 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800632 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
633 if (ext_bit == ProcHook::ANDROID_native_buffer)
634 hook_extensions_.set(ProcHook::KHR_swapchain);
635
636 hal_extensions_.set(ext_bit);
637 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800638
639 break;
640 }
641}
642
Ian Elliottf3e872d2017-11-02 10:15:13 -0600643void CreateInfoWrapper::DowngradeApiVersion() {
644 // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
645 if (instance_info_.pApplicationInfo) {
646 application_info_ = *instance_info_.pApplicationInfo;
647 instance_info_.pApplicationInfo = &application_info_;
648 application_info_.apiVersion = VK_API_VERSION_1_0;
649 }
650}
651
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700652void CreateInfoWrapper::UpgradeDeviceCoreApiVersion(uint32_t api_version) {
653 ALOG_ASSERT(!is_instance_, "Device only API called by instance wrapper.");
654#pragma clang diagnostic push
655#pragma clang diagnostic ignored "-Wold-style-cast"
656 api_version ^= VK_VERSION_PATCH(api_version);
657#pragma clang diagnostic pop
658 // cap the API version to the loader supported highest version
659 if (api_version > VK_API_VERSION_1_1)
660 api_version = VK_API_VERSION_1_1;
661 switch (api_version) {
662 case VK_API_VERSION_1_1:
663 hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
664 hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
665 [[clang::fallthrough]];
666 case VK_API_VERSION_1_0:
667 break;
668 default:
669 ALOGD("Unknown upgrade API version[%u]", api_version);
670 break;
671 }
672}
673
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800674VKAPI_ATTR void* DefaultAllocate(void*,
675 size_t size,
676 size_t alignment,
677 VkSystemAllocationScope) {
678 void* ptr = nullptr;
679 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
680 // additionally requires that it be at least sizeof(void*).
681 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
682 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
683 ret, ptr);
684 return ret == 0 ? ptr : nullptr;
685}
686
687VKAPI_ATTR void* DefaultReallocate(void*,
688 void* ptr,
689 size_t size,
690 size_t alignment,
691 VkSystemAllocationScope) {
692 if (size == 0) {
693 free(ptr);
694 return nullptr;
695 }
696
697 // TODO(jessehall): Right now we never shrink allocations; if the new
698 // request is smaller than the existing chunk, we just continue using it.
699 // Right now the loader never reallocs, so this doesn't matter. If that
700 // changes, or if this code is copied into some other project, this should
701 // probably have a heuristic to allocate-copy-free when doing so will save
702 // "enough" space.
703 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
704 if (size <= old_size)
705 return ptr;
706
707 void* new_ptr = nullptr;
708 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
709 return nullptr;
710 if (ptr) {
711 memcpy(new_ptr, ptr, std::min(old_size, size));
712 free(ptr);
713 }
714 return new_ptr;
715}
716
717VKAPI_ATTR void DefaultFree(void*, void* ptr) {
718 ALOGD_CALLSTACK("Free: %p", ptr);
719 free(ptr);
720}
721
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800722InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
723 void* data_mem = allocator.pfnAllocation(
724 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
725 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
726 if (!data_mem)
727 return nullptr;
728
729 return new (data_mem) InstanceData(allocator);
730}
731
732void FreeInstanceData(InstanceData* data,
733 const VkAllocationCallbacks& allocator) {
734 data->~InstanceData();
735 allocator.pfnFree(allocator.pUserData, data);
736}
737
Chia-I Wu950d6e12016-05-03 09:12:35 +0800738DeviceData* AllocateDeviceData(
739 const VkAllocationCallbacks& allocator,
740 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800741 void* data_mem = allocator.pfnAllocation(
742 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
743 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
744 if (!data_mem)
745 return nullptr;
746
Chia-I Wu950d6e12016-05-03 09:12:35 +0800747 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800748}
749
750void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
751 data->~DeviceData();
752 allocator.pfnFree(allocator.pUserData, data);
753}
754
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800755} // anonymous namespace
756
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800757bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800758 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800759}
760
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800761const VkAllocationCallbacks& GetDefaultAllocator() {
762 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
763 .pUserData = nullptr,
764 .pfnAllocation = DefaultAllocate,
765 .pfnReallocation = DefaultReallocate,
766 .pfnFree = DefaultFree,
767 };
768
769 return kDefaultAllocCallbacks;
770}
771
Chia-I Wueb7db122016-03-24 09:11:06 +0800772PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
773 const ProcHook* hook = GetProcHook(pName);
774 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800775 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800776
777 if (!instance) {
778 if (hook->type == ProcHook::GLOBAL)
779 return hook->proc;
780
Chia-I Wu109f8982016-04-22 06:40:40 +0800781 // v0 layers expect
782 //
783 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
784 //
785 // to work.
786 if (strcmp(pName, "vkCreateDevice") == 0)
787 return hook->proc;
788
Chia-I Wueb7db122016-03-24 09:11:06 +0800789 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800790 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800791 pName);
792
Chia-I Wu109f8982016-04-22 06:40:40 +0800793 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800794 }
795
796 PFN_vkVoidFunction proc;
797
798 switch (hook->type) {
799 case ProcHook::INSTANCE:
800 proc = (GetData(instance).hook_extensions[hook->extension])
801 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800802 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800803 break;
804 case ProcHook::DEVICE:
Yiwei Zhangc7e30b52019-10-17 15:53:00 -0700805 proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
Chia-I Wueb7db122016-03-24 09:11:06 +0800806 ? hook->proc
807 : hook->checked_proc;
808 break;
809 default:
810 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800811 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800812 pName);
813 proc = nullptr;
814 break;
815 }
816
817 return proc;
818}
819
820PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
821 const ProcHook* hook = GetProcHook(pName);
822 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800823 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800824
825 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800826 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800827 return nullptr;
828 }
829
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800830 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
831 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800832}
833
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800834VkResult EnumerateInstanceExtensionProperties(
835 const char* pLayerName,
836 uint32_t* pPropertyCount,
837 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600838
839 android::Vector<VkExtensionProperties> loader_extensions;
840 loader_extensions.push_back({
841 VK_KHR_SURFACE_EXTENSION_NAME,
842 VK_KHR_SURFACE_SPEC_VERSION});
843 loader_extensions.push_back({
844 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
845 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
846 loader_extensions.push_back({
847 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
848 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700849 loader_extensions.push_back({
850 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
851 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600852
Chia-I Wu31938252016-05-23 15:31:02 +0800853 static const VkExtensionProperties loader_debug_report_extension = {
854 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
855 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800856
857 // enumerate our extensions first
858 if (!pLayerName && pProperties) {
859 uint32_t count = std::min(
860 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
861
862 std::copy_n(loader_extensions.begin(), count, pProperties);
863
864 if (count < loader_extensions.size()) {
865 *pPropertyCount = count;
866 return VK_INCOMPLETE;
867 }
868
869 pProperties += count;
870 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800871
872 if (Hal::Get().GetDebugReportIndex() < 0) {
873 if (!*pPropertyCount) {
874 *pPropertyCount = count;
875 return VK_INCOMPLETE;
876 }
877
878 pProperties[0] = loader_debug_report_extension;
879 pProperties += 1;
880 *pPropertyCount -= 1;
881 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800882 }
883
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800884 ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800885 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800886 pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800887 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800888
Chia-I Wu31938252016-05-23 15:31:02 +0800889 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
890 int idx = Hal::Get().GetDebugReportIndex();
891 if (idx < 0) {
892 *pPropertyCount += 1;
893 } else if (pProperties &&
894 static_cast<uint32_t>(idx) < *pPropertyCount) {
895 pProperties[idx].specVersion =
896 std::min(pProperties[idx].specVersion,
897 loader_debug_report_extension.specVersion);
898 }
899
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800900 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800901 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800902
903 return result;
904}
905
Chris Forbesfa25e632017-02-22 12:36:02 +1300906bool QueryPresentationProperties(
907 VkPhysicalDevice physicalDevice,
908 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
909{
910 const InstanceData& data = GetData(physicalDevice);
911
912 // GPDP2 must be present and enabled on the instance.
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700913 if (!data.driver.GetPhysicalDeviceProperties2KHR &&
914 !data.driver.GetPhysicalDeviceProperties2)
Chris Forbesfa25e632017-02-22 12:36:02 +1300915 return false;
916
917 // Request the android-specific presentation properties via GPDP2
918 VkPhysicalDeviceProperties2KHR properties = {
919 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
920 presentation_properties,
921 {}
922 };
923
924#pragma clang diagnostic push
925#pragma clang diagnostic ignored "-Wold-style-cast"
926 presentation_properties->sType =
927 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
928#pragma clang diagnostic pop
929 presentation_properties->pNext = nullptr;
930 presentation_properties->sharedImage = VK_FALSE;
931
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700932 if (data.driver.GetPhysicalDeviceProperties2KHR) {
933 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
934 &properties);
935 } else {
936 data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
937 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300938
939 return true;
940}
941
Chia-I Wu01cf3052016-03-24 16:16:21 +0800942VkResult EnumerateDeviceExtensionProperties(
943 VkPhysicalDevice physicalDevice,
944 const char* pLayerName,
945 uint32_t* pPropertyCount,
946 VkExtensionProperties* pProperties) {
947 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300948 // extensions that are unconditionally exposed by the loader
949 android::Vector<VkExtensionProperties> loader_extensions;
950 loader_extensions.push_back({
951 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
952 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300953
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -0800954 bool hdrBoardConfig =
955 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
956 false);
957 if (hdrBoardConfig) {
958 loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
959 VK_EXT_HDR_METADATA_SPEC_VERSION});
960 }
961
Chris Forbes16095002017-05-05 15:33:29 -0700962 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
963 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
964 presentation_properties.sharedImage) {
965 loader_extensions.push_back({
966 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
967 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300968 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700969
Ian Elliott5c34de22017-04-10 14:42:30 -0600970 // conditionally add VK_GOOGLE_display_timing if present timestamps are
971 // supported by the driver:
Wei Wangf9b05ee2017-07-19 20:59:39 -0700972 const std::string timestamp_property("service.sf.present_timestamp");
973 android::base::WaitForPropertyCreation(timestamp_property);
974 if (android::base::GetBoolProperty(timestamp_property, true)) {
Ian Elliott5c34de22017-04-10 14:42:30 -0600975 loader_extensions.push_back({
976 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
977 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
978 }
979
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700980 // enumerate our extensions first
981 if (!pLayerName && pProperties) {
982 uint32_t count = std::min(
983 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
984
985 std::copy_n(loader_extensions.begin(), count, pProperties);
986
987 if (count < loader_extensions.size()) {
988 *pPropertyCount = count;
989 return VK_INCOMPLETE;
990 }
991
992 pProperties += count;
993 *pPropertyCount -= count;
994 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800995
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800996 ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
Chia-I Wu01cf3052016-03-24 16:16:21 +0800997 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
998 physicalDevice, pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800999 ATRACE_END();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001000
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001001 if (pProperties) {
1002 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1003 for (uint32_t i = 0; i < *pPropertyCount; i++) {
1004 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +08001005
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001006 if (strcmp(prop.extensionName,
1007 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1008 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +08001009
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001010 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1011 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
Yiwei Zhang14f4d422019-04-17 12:24:39 -07001012
1013 if (prop.specVersion >= 8) {
1014 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1015 } else {
1016 prop.specVersion = 68;
1017 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001018 }
1019 }
Chia-I Wu01cf3052016-03-24 16:16:21 +08001020
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001021 // restore loader extension count
1022 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1023 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001024 }
1025
1026 return result;
1027}
1028
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001029VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1030 const VkAllocationCallbacks* pAllocator,
1031 VkInstance* pInstance) {
1032 const VkAllocationCallbacks& data_allocator =
1033 (pAllocator) ? *pAllocator : GetDefaultAllocator();
1034
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001035 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001036 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001037 if (result != VK_SUCCESS)
1038 return result;
1039
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001040 ATRACE_BEGIN("AllocateInstanceData");
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001041 InstanceData* data = AllocateInstanceData(data_allocator);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001042 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001043 if (!data)
1044 return VK_ERROR_OUT_OF_HOST_MEMORY;
1045
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001046 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001047
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001048 ATRACE_BEGIN("autoDowngradeApiVersion");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001049#pragma clang diagnostic push
1050#pragma clang diagnostic ignored "-Wold-style-cast"
1051 uint32_t api_version = ((pCreateInfo->pApplicationInfo)
1052 ? pCreateInfo->pApplicationInfo->apiVersion
1053 : VK_API_VERSION_1_0);
1054 uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
1055 uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
1056 uint32_t icd_api_version;
1057 PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1058 reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
Yi Kongbcbc73a2018-07-18 10:13:04 -07001059 Hal::Device().GetInstanceProcAddr(nullptr,
Ian Elliottf3e872d2017-11-02 10:15:13 -06001060 "vkEnumerateInstanceVersion"));
1061 if (!pfn_enumerate_instance_version) {
1062 icd_api_version = VK_API_VERSION_1_0;
1063 } else {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001064 ATRACE_BEGIN("pfn_enumerate_instance_version");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001065 result = (*pfn_enumerate_instance_version)(&icd_api_version);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001066 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001067 }
1068 uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
1069 uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
1070
1071 if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
1072 ((api_major_version > 1) || (api_minor_version > 0))) {
1073 api_version = VK_API_VERSION_1_0;
1074 wrapper.DowngradeApiVersion();
1075 }
1076#pragma clang diagnostic pop
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001077 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001078
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001079 // call into the driver
1080 VkInstance instance;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001081 ATRACE_BEGIN("driver.CreateInstance");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001082 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001083 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1084 &instance);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001085 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001086 if (result != VK_SUCCESS) {
1087 FreeInstanceData(data, data_allocator);
1088 return result;
1089 }
1090
1091 // initialize InstanceDriverTable
1092 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001093 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001094 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001095 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001096 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001097 if (data->driver.DestroyInstance)
1098 data->driver.DestroyInstance(instance, pAllocator);
1099
1100 FreeInstanceData(data, data_allocator);
1101
1102 return VK_ERROR_INCOMPATIBLE_DRIVER;
1103 }
1104
1105 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001106 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001107 if (!data->get_device_proc_addr) {
1108 data->driver.DestroyInstance(instance, pAllocator);
1109 FreeInstanceData(data, data_allocator);
1110
1111 return VK_ERROR_INCOMPATIBLE_DRIVER;
1112 }
1113
1114 *pInstance = instance;
1115
1116 return VK_SUCCESS;
1117}
1118
1119void DestroyInstance(VkInstance instance,
1120 const VkAllocationCallbacks* pAllocator) {
1121 InstanceData& data = GetData(instance);
1122 data.driver.DestroyInstance(instance, pAllocator);
1123
1124 VkAllocationCallbacks local_allocator;
1125 if (!pAllocator) {
1126 local_allocator = data.allocator;
1127 pAllocator = &local_allocator;
1128 }
1129
1130 FreeInstanceData(&data, *pAllocator);
1131}
1132
Chia-I Wu4901db72016-03-24 16:38:58 +08001133VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1134 const VkDeviceCreateInfo* pCreateInfo,
1135 const VkAllocationCallbacks* pAllocator,
1136 VkDevice* pDevice) {
1137 const InstanceData& instance_data = GetData(physicalDevice);
1138 const VkAllocationCallbacks& data_allocator =
1139 (pAllocator) ? *pAllocator : instance_data.allocator;
1140
1141 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001142 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +08001143 if (result != VK_SUCCESS)
1144 return result;
1145
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001146 ATRACE_BEGIN("AllocateDeviceData");
Chia-I Wu950d6e12016-05-03 09:12:35 +08001147 DeviceData* data = AllocateDeviceData(data_allocator,
1148 instance_data.debug_report_callbacks);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001149 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001150 if (!data)
1151 return VK_ERROR_OUT_OF_HOST_MEMORY;
1152
Yiwei Zhangc7e30b52019-10-17 15:53:00 -07001153 VkPhysicalDeviceProperties properties;
1154 ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1155 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1156 &properties);
1157 ATRACE_END();
1158
1159 wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001160 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +08001161
1162 // call into the driver
1163 VkDevice dev;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001164 ATRACE_BEGIN("driver.CreateDevice");
Chia-I Wu4901db72016-03-24 16:38:58 +08001165 result = instance_data.driver.CreateDevice(
1166 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1167 pAllocator, &dev);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001168 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001169 if (result != VK_SUCCESS) {
1170 FreeDeviceData(data, data_allocator);
1171 return result;
1172 }
1173
1174 // initialize DeviceDriverTable
1175 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001176 !InitDriverTable(dev, instance_data.get_device_proc_addr,
1177 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +08001178 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1179 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1180 if (data->driver.DestroyDevice)
1181 data->driver.DestroyDevice(dev, pAllocator);
1182
1183 FreeDeviceData(data, data_allocator);
1184
1185 return VK_ERROR_INCOMPATIBLE_DRIVER;
1186 }
Chris Forbesd8277912017-02-10 14:59:59 +13001187
1188 // sanity check ANDROID_native_buffer implementation, whose set of
1189 // entrypoints varies according to the spec version.
1190 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1191 !data->driver.GetSwapchainGrallocUsageANDROID &&
1192 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1193 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1194 " must expose at least one of "
1195 "vkGetSwapchainGrallocUsageANDROID or "
1196 "vkGetSwapchainGrallocUsage2ANDROID");
1197
1198 data->driver.DestroyDevice(dev, pAllocator);
1199 FreeDeviceData(data, data_allocator);
1200
1201 return VK_ERROR_INCOMPATIBLE_DRIVER;
1202 }
1203
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -07001204 if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1205 // Log that the app is hitting software Vulkan implementation
Yiwei Zhangb1c1a372019-07-03 13:39:32 -07001206 android::GraphicsEnv::getInstance().setTargetStats(
1207 android::GraphicsEnv::Stats::CPU_VULKAN_IN_USE);
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -07001208 }
1209
Jesse Halldc225072016-05-30 22:40:14 -07001210 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001211 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001212
1213 *pDevice = dev;
1214
1215 return VK_SUCCESS;
1216}
1217
1218void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1219 DeviceData& data = GetData(device);
1220 data.driver.DestroyDevice(device, pAllocator);
1221
1222 VkAllocationCallbacks local_allocator;
1223 if (!pAllocator) {
1224 local_allocator = data.allocator;
1225 pAllocator = &local_allocator;
1226 }
1227
1228 FreeDeviceData(&data, *pAllocator);
1229}
1230
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001231VkResult EnumeratePhysicalDevices(VkInstance instance,
1232 uint32_t* pPhysicalDeviceCount,
1233 VkPhysicalDevice* pPhysicalDevices) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001234 ATRACE_CALL();
1235
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001236 const auto& data = GetData(instance);
1237
1238 VkResult result = data.driver.EnumeratePhysicalDevices(
1239 instance, pPhysicalDeviceCount, pPhysicalDevices);
1240 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1241 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1242 SetData(pPhysicalDevices[i], data);
1243 }
1244
1245 return result;
1246}
1247
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001248VkResult EnumeratePhysicalDeviceGroups(
1249 VkInstance instance,
1250 uint32_t* pPhysicalDeviceGroupCount,
1251 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001252 ATRACE_CALL();
1253
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001254 VkResult result = VK_SUCCESS;
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001255 const auto& data = GetData(instance);
1256
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001257 if (!data.driver.EnumeratePhysicalDeviceGroups) {
1258 uint32_t device_count = 0;
1259 result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1260 if (result < 0)
1261 return result;
Chad Versace32c087f2018-09-09 07:28:05 -07001262
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001263 if (!pPhysicalDeviceGroupProperties) {
1264 *pPhysicalDeviceGroupCount = device_count;
1265 return result;
1266 }
1267
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001268 if (!device_count) {
1269 *pPhysicalDeviceGroupCount = 0;
1270 return result;
1271 }
Chad Versace32c087f2018-09-09 07:28:05 -07001272 device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1273 if (!device_count)
1274 return VK_INCOMPLETE;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001275
1276 android::Vector<VkPhysicalDevice> devices;
1277 devices.resize(device_count);
Chad Versace32c087f2018-09-09 07:28:05 -07001278 *pPhysicalDeviceGroupCount = device_count;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001279 result = EnumeratePhysicalDevices(instance, &device_count,
1280 devices.editArray());
1281 if (result < 0)
1282 return result;
1283
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001284 for (uint32_t i = 0; i < device_count; ++i) {
1285 pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1286 pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1287 pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1288 }
1289 } else {
1290 result = data.driver.EnumeratePhysicalDeviceGroups(
1291 instance, pPhysicalDeviceGroupCount,
1292 pPhysicalDeviceGroupProperties);
1293 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1294 *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1295 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1296 for (uint32_t j = 0;
1297 j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1298 j++) {
1299 SetData(
1300 pPhysicalDeviceGroupProperties[i].physicalDevices[j],
Ian Elliottcd8ad332017-10-13 09:21:12 -06001301 data);
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001302 }
Ian Elliottcd8ad332017-10-13 09:21:12 -06001303 }
1304 }
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001305 }
1306
1307 return result;
1308}
1309
Chia-I Wuba0be412016-03-24 16:24:40 +08001310void GetDeviceQueue(VkDevice device,
1311 uint32_t queueFamilyIndex,
1312 uint32_t queueIndex,
1313 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001314 ATRACE_CALL();
1315
Chia-I Wuba0be412016-03-24 16:24:40 +08001316 const auto& data = GetData(device);
1317
1318 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1319 SetData(*pQueue, data);
1320}
1321
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001322void GetDeviceQueue2(VkDevice device,
1323 const VkDeviceQueueInfo2* pQueueInfo,
1324 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001325 ATRACE_CALL();
1326
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001327 const auto& data = GetData(device);
1328
1329 data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
Yiwei Zhangf5b9f732018-02-07 14:06:09 -08001330 if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001331}
1332
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001333VKAPI_ATTR VkResult
1334AllocateCommandBuffers(VkDevice device,
1335 const VkCommandBufferAllocateInfo* pAllocateInfo,
1336 VkCommandBuffer* pCommandBuffers) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001337 ATRACE_CALL();
1338
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001339 const auto& data = GetData(device);
1340
1341 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1342 pCommandBuffers);
1343 if (result == VK_SUCCESS) {
1344 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1345 SetData(pCommandBuffers[i], data);
1346 }
1347
1348 return result;
1349}
1350
Chia-I Wu9d518162016-03-24 14:55:27 +08001351} // namespace driver
1352} // namespace vulkan