blob: c77fa064e602f717778f6525d978c3e3be0bf12b [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 Zhangec6c5052019-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 Zhangec6c5052019-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 Zhangec6c5052019-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 Zhangec6c5052019-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 Zhangec6c5052019-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 Zhangec6c5052019-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 Wu9d518162016-03-24 14:55:27 +0800757bool Debuggable() {
758 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
759}
760
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800761bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800762 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800763}
764
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800765const VkAllocationCallbacks& GetDefaultAllocator() {
766 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
767 .pUserData = nullptr,
768 .pfnAllocation = DefaultAllocate,
769 .pfnReallocation = DefaultReallocate,
770 .pfnFree = DefaultFree,
771 };
772
773 return kDefaultAllocCallbacks;
774}
775
Chia-I Wueb7db122016-03-24 09:11:06 +0800776PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
777 const ProcHook* hook = GetProcHook(pName);
778 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800779 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800780
781 if (!instance) {
782 if (hook->type == ProcHook::GLOBAL)
783 return hook->proc;
784
Chia-I Wu109f8982016-04-22 06:40:40 +0800785 // v0 layers expect
786 //
787 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
788 //
789 // to work.
790 if (strcmp(pName, "vkCreateDevice") == 0)
791 return hook->proc;
792
Chia-I Wueb7db122016-03-24 09:11:06 +0800793 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800794 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800795 pName);
796
Chia-I Wu109f8982016-04-22 06:40:40 +0800797 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800798 }
799
800 PFN_vkVoidFunction proc;
801
802 switch (hook->type) {
803 case ProcHook::INSTANCE:
804 proc = (GetData(instance).hook_extensions[hook->extension])
805 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800806 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800807 break;
808 case ProcHook::DEVICE:
Yiwei Zhangec6c5052019-10-17 15:53:00 -0700809 proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
Chia-I Wueb7db122016-03-24 09:11:06 +0800810 ? hook->proc
811 : hook->checked_proc;
812 break;
813 default:
814 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800815 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800816 pName);
817 proc = nullptr;
818 break;
819 }
820
821 return proc;
822}
823
824PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
825 const ProcHook* hook = GetProcHook(pName);
826 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800827 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800828
829 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800830 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800831 return nullptr;
832 }
833
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800834 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
835 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800836}
837
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800838VkResult EnumerateInstanceExtensionProperties(
839 const char* pLayerName,
840 uint32_t* pPropertyCount,
841 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600842
843 android::Vector<VkExtensionProperties> loader_extensions;
844 loader_extensions.push_back({
845 VK_KHR_SURFACE_EXTENSION_NAME,
846 VK_KHR_SURFACE_SPEC_VERSION});
847 loader_extensions.push_back({
848 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
849 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
850 loader_extensions.push_back({
851 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
852 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700853 loader_extensions.push_back({
854 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
855 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600856
Chia-I Wu31938252016-05-23 15:31:02 +0800857 static const VkExtensionProperties loader_debug_report_extension = {
858 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
859 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800860
861 // enumerate our extensions first
862 if (!pLayerName && pProperties) {
863 uint32_t count = std::min(
864 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
865
866 std::copy_n(loader_extensions.begin(), count, pProperties);
867
868 if (count < loader_extensions.size()) {
869 *pPropertyCount = count;
870 return VK_INCOMPLETE;
871 }
872
873 pProperties += count;
874 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800875
876 if (Hal::Get().GetDebugReportIndex() < 0) {
877 if (!*pPropertyCount) {
878 *pPropertyCount = count;
879 return VK_INCOMPLETE;
880 }
881
882 pProperties[0] = loader_debug_report_extension;
883 pProperties += 1;
884 *pPropertyCount -= 1;
885 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800886 }
887
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800888 ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800889 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800890 pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800891 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800892
Chia-I Wu31938252016-05-23 15:31:02 +0800893 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
894 int idx = Hal::Get().GetDebugReportIndex();
895 if (idx < 0) {
896 *pPropertyCount += 1;
897 } else if (pProperties &&
898 static_cast<uint32_t>(idx) < *pPropertyCount) {
899 pProperties[idx].specVersion =
900 std::min(pProperties[idx].specVersion,
901 loader_debug_report_extension.specVersion);
902 }
903
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800904 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800905 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800906
907 return result;
908}
909
Chris Forbesfa25e632017-02-22 12:36:02 +1300910bool QueryPresentationProperties(
911 VkPhysicalDevice physicalDevice,
912 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
913{
914 const InstanceData& data = GetData(physicalDevice);
915
916 // GPDP2 must be present and enabled on the instance.
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700917 if (!data.driver.GetPhysicalDeviceProperties2KHR &&
918 !data.driver.GetPhysicalDeviceProperties2)
Chris Forbesfa25e632017-02-22 12:36:02 +1300919 return false;
920
921 // Request the android-specific presentation properties via GPDP2
922 VkPhysicalDeviceProperties2KHR properties = {
923 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
924 presentation_properties,
925 {}
926 };
927
928#pragma clang diagnostic push
929#pragma clang diagnostic ignored "-Wold-style-cast"
930 presentation_properties->sType =
931 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
932#pragma clang diagnostic pop
933 presentation_properties->pNext = nullptr;
934 presentation_properties->sharedImage = VK_FALSE;
935
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700936 if (data.driver.GetPhysicalDeviceProperties2KHR) {
937 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
938 &properties);
939 } else {
940 data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
941 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300942
943 return true;
944}
945
Chia-I Wu01cf3052016-03-24 16:16:21 +0800946VkResult EnumerateDeviceExtensionProperties(
947 VkPhysicalDevice physicalDevice,
948 const char* pLayerName,
949 uint32_t* pPropertyCount,
950 VkExtensionProperties* pProperties) {
951 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300952 // extensions that are unconditionally exposed by the loader
953 android::Vector<VkExtensionProperties> loader_extensions;
954 loader_extensions.push_back({
955 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
956 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300957
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -0800958 bool hdrBoardConfig =
959 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
960 false);
961 if (hdrBoardConfig) {
962 loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
963 VK_EXT_HDR_METADATA_SPEC_VERSION});
964 }
965
Chris Forbes16095002017-05-05 15:33:29 -0700966 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
967 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
968 presentation_properties.sharedImage) {
969 loader_extensions.push_back({
970 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
971 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300972 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700973
Ian Elliott5c34de22017-04-10 14:42:30 -0600974 // conditionally add VK_GOOGLE_display_timing if present timestamps are
975 // supported by the driver:
Wei Wangf9b05ee2017-07-19 20:59:39 -0700976 const std::string timestamp_property("service.sf.present_timestamp");
977 android::base::WaitForPropertyCreation(timestamp_property);
978 if (android::base::GetBoolProperty(timestamp_property, true)) {
Ian Elliott5c34de22017-04-10 14:42:30 -0600979 loader_extensions.push_back({
980 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
981 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
982 }
983
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700984 // enumerate our extensions first
985 if (!pLayerName && pProperties) {
986 uint32_t count = std::min(
987 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
988
989 std::copy_n(loader_extensions.begin(), count, pProperties);
990
991 if (count < loader_extensions.size()) {
992 *pPropertyCount = count;
993 return VK_INCOMPLETE;
994 }
995
996 pProperties += count;
997 *pPropertyCount -= count;
998 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800999
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001000 ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
Chia-I Wu01cf3052016-03-24 16:16:21 +08001001 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
1002 physicalDevice, pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001003 ATRACE_END();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001004
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001005 if (pProperties) {
1006 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1007 for (uint32_t i = 0; i < *pPropertyCount; i++) {
1008 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +08001009
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001010 if (strcmp(prop.extensionName,
1011 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1012 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +08001013
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001014 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1015 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
Yiwei Zhang14f4d422019-04-17 12:24:39 -07001016
1017 if (prop.specVersion >= 8) {
1018 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1019 } else {
1020 prop.specVersion = 68;
1021 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001022 }
1023 }
Chia-I Wu01cf3052016-03-24 16:16:21 +08001024
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001025 // restore loader extension count
1026 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1027 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001028 }
1029
1030 return result;
1031}
1032
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001033VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1034 const VkAllocationCallbacks* pAllocator,
1035 VkInstance* pInstance) {
1036 const VkAllocationCallbacks& data_allocator =
1037 (pAllocator) ? *pAllocator : GetDefaultAllocator();
1038
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001039 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001040 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001041 if (result != VK_SUCCESS)
1042 return result;
1043
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001044 ATRACE_BEGIN("AllocateInstanceData");
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001045 InstanceData* data = AllocateInstanceData(data_allocator);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001046 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001047 if (!data)
1048 return VK_ERROR_OUT_OF_HOST_MEMORY;
1049
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001050 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001051
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001052 ATRACE_BEGIN("autoDowngradeApiVersion");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001053#pragma clang diagnostic push
1054#pragma clang diagnostic ignored "-Wold-style-cast"
1055 uint32_t api_version = ((pCreateInfo->pApplicationInfo)
1056 ? pCreateInfo->pApplicationInfo->apiVersion
1057 : VK_API_VERSION_1_0);
1058 uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
1059 uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
1060 uint32_t icd_api_version;
1061 PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1062 reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
Yi Kongbcbc73a2018-07-18 10:13:04 -07001063 Hal::Device().GetInstanceProcAddr(nullptr,
Ian Elliottf3e872d2017-11-02 10:15:13 -06001064 "vkEnumerateInstanceVersion"));
1065 if (!pfn_enumerate_instance_version) {
1066 icd_api_version = VK_API_VERSION_1_0;
1067 } else {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001068 ATRACE_BEGIN("pfn_enumerate_instance_version");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001069 result = (*pfn_enumerate_instance_version)(&icd_api_version);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001070 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001071 }
1072 uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
1073 uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
1074
1075 if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
1076 ((api_major_version > 1) || (api_minor_version > 0))) {
1077 api_version = VK_API_VERSION_1_0;
1078 wrapper.DowngradeApiVersion();
1079 }
1080#pragma clang diagnostic pop
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001081 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001082
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001083 // call into the driver
1084 VkInstance instance;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001085 ATRACE_BEGIN("driver.CreateInstance");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001086 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001087 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1088 &instance);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001089 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001090 if (result != VK_SUCCESS) {
1091 FreeInstanceData(data, data_allocator);
1092 return result;
1093 }
1094
1095 // initialize InstanceDriverTable
1096 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001097 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001098 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001099 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001100 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001101 if (data->driver.DestroyInstance)
1102 data->driver.DestroyInstance(instance, pAllocator);
1103
1104 FreeInstanceData(data, data_allocator);
1105
1106 return VK_ERROR_INCOMPATIBLE_DRIVER;
1107 }
1108
1109 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001110 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001111 if (!data->get_device_proc_addr) {
1112 data->driver.DestroyInstance(instance, pAllocator);
1113 FreeInstanceData(data, data_allocator);
1114
1115 return VK_ERROR_INCOMPATIBLE_DRIVER;
1116 }
1117
1118 *pInstance = instance;
1119
1120 return VK_SUCCESS;
1121}
1122
1123void DestroyInstance(VkInstance instance,
1124 const VkAllocationCallbacks* pAllocator) {
1125 InstanceData& data = GetData(instance);
1126 data.driver.DestroyInstance(instance, pAllocator);
1127
1128 VkAllocationCallbacks local_allocator;
1129 if (!pAllocator) {
1130 local_allocator = data.allocator;
1131 pAllocator = &local_allocator;
1132 }
1133
1134 FreeInstanceData(&data, *pAllocator);
1135}
1136
Chia-I Wu4901db72016-03-24 16:38:58 +08001137VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1138 const VkDeviceCreateInfo* pCreateInfo,
1139 const VkAllocationCallbacks* pAllocator,
1140 VkDevice* pDevice) {
1141 const InstanceData& instance_data = GetData(physicalDevice);
1142 const VkAllocationCallbacks& data_allocator =
1143 (pAllocator) ? *pAllocator : instance_data.allocator;
1144
1145 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001146 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +08001147 if (result != VK_SUCCESS)
1148 return result;
1149
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001150 ATRACE_BEGIN("AllocateDeviceData");
Chia-I Wu950d6e12016-05-03 09:12:35 +08001151 DeviceData* data = AllocateDeviceData(data_allocator,
1152 instance_data.debug_report_callbacks);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001153 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001154 if (!data)
1155 return VK_ERROR_OUT_OF_HOST_MEMORY;
1156
Yiwei Zhangec6c5052019-10-17 15:53:00 -07001157 VkPhysicalDeviceProperties properties;
1158 ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1159 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1160 &properties);
1161 ATRACE_END();
1162
1163 wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001164 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +08001165
1166 // call into the driver
1167 VkDevice dev;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001168 ATRACE_BEGIN("driver.CreateDevice");
Chia-I Wu4901db72016-03-24 16:38:58 +08001169 result = instance_data.driver.CreateDevice(
1170 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1171 pAllocator, &dev);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001172 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001173 if (result != VK_SUCCESS) {
1174 FreeDeviceData(data, data_allocator);
1175 return result;
1176 }
1177
1178 // initialize DeviceDriverTable
1179 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001180 !InitDriverTable(dev, instance_data.get_device_proc_addr,
1181 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +08001182 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1183 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1184 if (data->driver.DestroyDevice)
1185 data->driver.DestroyDevice(dev, pAllocator);
1186
1187 FreeDeviceData(data, data_allocator);
1188
1189 return VK_ERROR_INCOMPATIBLE_DRIVER;
1190 }
Chris Forbesd8277912017-02-10 14:59:59 +13001191
1192 // sanity check ANDROID_native_buffer implementation, whose set of
1193 // entrypoints varies according to the spec version.
1194 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1195 !data->driver.GetSwapchainGrallocUsageANDROID &&
1196 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1197 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1198 " must expose at least one of "
1199 "vkGetSwapchainGrallocUsageANDROID or "
1200 "vkGetSwapchainGrallocUsage2ANDROID");
1201
1202 data->driver.DestroyDevice(dev, pAllocator);
1203 FreeDeviceData(data, data_allocator);
1204
1205 return VK_ERROR_INCOMPATIBLE_DRIVER;
1206 }
1207
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -07001208 if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1209 // Log that the app is hitting software Vulkan implementation
1210 android::GraphicsEnv::getInstance().setCpuVulkanInUse();
1211 }
1212
Jesse Halldc225072016-05-30 22:40:14 -07001213 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001214 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001215
1216 *pDevice = dev;
1217
1218 return VK_SUCCESS;
1219}
1220
1221void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1222 DeviceData& data = GetData(device);
1223 data.driver.DestroyDevice(device, pAllocator);
1224
1225 VkAllocationCallbacks local_allocator;
1226 if (!pAllocator) {
1227 local_allocator = data.allocator;
1228 pAllocator = &local_allocator;
1229 }
1230
1231 FreeDeviceData(&data, *pAllocator);
1232}
1233
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001234VkResult EnumeratePhysicalDevices(VkInstance instance,
1235 uint32_t* pPhysicalDeviceCount,
1236 VkPhysicalDevice* pPhysicalDevices) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001237 ATRACE_CALL();
1238
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001239 const auto& data = GetData(instance);
1240
1241 VkResult result = data.driver.EnumeratePhysicalDevices(
1242 instance, pPhysicalDeviceCount, pPhysicalDevices);
1243 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1244 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1245 SetData(pPhysicalDevices[i], data);
1246 }
1247
1248 return result;
1249}
1250
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001251VkResult EnumeratePhysicalDeviceGroups(
1252 VkInstance instance,
1253 uint32_t* pPhysicalDeviceGroupCount,
1254 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001255 ATRACE_CALL();
1256
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001257 VkResult result = VK_SUCCESS;
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001258 const auto& data = GetData(instance);
1259
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001260 if (!data.driver.EnumeratePhysicalDeviceGroups) {
1261 uint32_t device_count = 0;
1262 result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1263 if (result < 0)
1264 return result;
Chad Versace32c087f2018-09-09 07:28:05 -07001265
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001266 if (!pPhysicalDeviceGroupProperties) {
1267 *pPhysicalDeviceGroupCount = device_count;
1268 return result;
1269 }
1270
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001271 if (!device_count) {
1272 *pPhysicalDeviceGroupCount = 0;
1273 return result;
1274 }
Chad Versace32c087f2018-09-09 07:28:05 -07001275 device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1276 if (!device_count)
1277 return VK_INCOMPLETE;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001278
1279 android::Vector<VkPhysicalDevice> devices;
1280 devices.resize(device_count);
Chad Versace32c087f2018-09-09 07:28:05 -07001281 *pPhysicalDeviceGroupCount = device_count;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001282 result = EnumeratePhysicalDevices(instance, &device_count,
1283 devices.editArray());
1284 if (result < 0)
1285 return result;
1286
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001287 for (uint32_t i = 0; i < device_count; ++i) {
1288 pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1289 pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1290 pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1291 }
1292 } else {
1293 result = data.driver.EnumeratePhysicalDeviceGroups(
1294 instance, pPhysicalDeviceGroupCount,
1295 pPhysicalDeviceGroupProperties);
1296 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1297 *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1298 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1299 for (uint32_t j = 0;
1300 j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1301 j++) {
1302 SetData(
1303 pPhysicalDeviceGroupProperties[i].physicalDevices[j],
Ian Elliottcd8ad332017-10-13 09:21:12 -06001304 data);
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001305 }
Ian Elliottcd8ad332017-10-13 09:21:12 -06001306 }
1307 }
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001308 }
1309
1310 return result;
1311}
1312
Chia-I Wuba0be412016-03-24 16:24:40 +08001313void GetDeviceQueue(VkDevice device,
1314 uint32_t queueFamilyIndex,
1315 uint32_t queueIndex,
1316 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001317 ATRACE_CALL();
1318
Chia-I Wuba0be412016-03-24 16:24:40 +08001319 const auto& data = GetData(device);
1320
1321 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1322 SetData(*pQueue, data);
1323}
1324
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001325void GetDeviceQueue2(VkDevice device,
1326 const VkDeviceQueueInfo2* pQueueInfo,
1327 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001328 ATRACE_CALL();
1329
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001330 const auto& data = GetData(device);
1331
1332 data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
Yiwei Zhangf5b9f732018-02-07 14:06:09 -08001333 if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001334}
1335
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001336VKAPI_ATTR VkResult
1337AllocateCommandBuffers(VkDevice device,
1338 const VkCommandBufferAllocateInfo* pAllocateInfo,
1339 VkCommandBuffer* pCommandBuffers) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001340 ATRACE_CALL();
1341
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001342 const auto& data = GetData(device);
1343
1344 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1345 pCommandBuffers);
1346 if (result == VK_SUCCESS) {
1347 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1348 SetData(pCommandBuffers[i], data);
1349 }
1350
1351 return result;
1352}
1353
Chia-I Wu9d518162016-03-24 14:55:27 +08001354} // namespace driver
1355} // namespace vulkan