blob: a7ec4aed1db990cb86819c70657f1894f0ff0d38 [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
Yiwei Zhang5e862202019-06-21 14:59:16 -070019#include "driver.h"
20
21#include <dlfcn.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070022#include <malloc.h>
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080023#include <stdlib.h>
24#include <string.h>
Chia-I Wu9d518162016-03-24 14:55:27 +080025
Jesse Hall53457db2016-12-14 16:54:06 -080026#include <android/dlext.h>
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080027#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
Yiwei Zhang5e862202019-06-21 14:59:16 -070028#include <android-base/properties.h>
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080029#include <configstore/Utils.h>
Jesse Hall53457db2016-12-14 16:54:06 -080030#include <cutils/properties.h>
Jiyong Park27c39e12017-05-08 13:00:02 +090031#include <graphicsenv/GraphicsEnv.h>
Yiwei Zhang5e862202019-06-21 14:59:16 -070032#include <log/log.h>
Yiwei Zhange40dd732019-08-05 16:41:03 -070033#include <nativeloader/dlext_namespaces.h>
Yiwei Zhang5e862202019-06-21 14:59:16 -070034#include <sys/prctl.h>
Yiwei Zhangd9861812019-02-13 11:51:55 -080035#include <utils/Timers.h>
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -080036#include <utils/Trace.h>
Jesse Hall53457db2016-12-14 16:54:06 -080037
Yiwei Zhang5e862202019-06-21 14:59:16 -070038#include <algorithm>
39#include <array>
Nick Desaulniers7c123cc2019-10-21 13:52:41 -070040#include <climits>
Yiwei Zhang5e862202019-06-21 14:59:16 -070041#include <new>
Nick Desaulniers7c123cc2019-10-21 13:52:41 -070042#include <string_view>
43#include <sstream>
Yiwei Zhang5e862202019-06-21 14:59:16 -070044#include <vector>
Wei Wangf9b05ee2017-07-19 20:59:39 -070045
Jesse Hallb7c4e3b2016-04-11 13:51:38 -070046#include "stubhal.h"
Chia-I Wu9d518162016-03-24 14:55:27 +080047
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080048using namespace android::hardware::configstore;
49using namespace android::hardware::configstore::V1_0;
50
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080051// #define ENABLE_ALLOC_CALLSTACKS 1
52#if ENABLE_ALLOC_CALLSTACKS
53#include <utils/CallStack.h>
54#define ALOGD_CALLSTACK(...) \
55 do { \
56 ALOGD(__VA_ARGS__); \
57 android::CallStack callstack; \
58 callstack.update(); \
59 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
60 } while (false)
61#else
62#define ALOGD_CALLSTACK(...) \
63 do { \
64 } while (false)
65#endif
66
Chia-I Wu9d518162016-03-24 14:55:27 +080067namespace vulkan {
68namespace driver {
69
Chia-I Wu136b8eb2016-03-24 15:01:52 +080070namespace {
71
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080072class Hal {
73 public:
74 static bool Open();
75
76 static const Hal& Get() { return hal_; }
77 static const hwvulkan_device_t& Device() { return *Get().dev_; }
78
Chia-I Wu31938252016-05-23 15:31:02 +080079 int GetDebugReportIndex() const { return debug_report_index_; }
80
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080081 private:
Chia-I Wu31938252016-05-23 15:31:02 +080082 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080083 Hal(const Hal&) = delete;
84 Hal& operator=(const Hal&) = delete;
85
Chia-I Wu31938252016-05-23 15:31:02 +080086 bool InitDebugReportIndex();
87
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080088 static Hal hal_;
89
90 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080091 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080092};
93
Chia-I Wu4901db72016-03-24 16:38:58 +080094class CreateInfoWrapper {
95 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080096 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080097 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080098 CreateInfoWrapper(VkPhysicalDevice physical_dev,
99 const VkDeviceCreateInfo& create_info,
100 const VkAllocationCallbacks& allocator);
101 ~CreateInfoWrapper();
102
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800103 VkResult Validate();
Ian Elliottf3e872d2017-11-02 10:15:13 -0600104 void DowngradeApiVersion();
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700105 void UpgradeDeviceCoreApiVersion(uint32_t api_version);
Chia-I Wu4901db72016-03-24 16:38:58 +0800106
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800107 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
108 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800109
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800110 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800111 explicit operator const VkDeviceCreateInfo*() const;
112
113 private:
114 struct ExtensionFilter {
115 VkExtensionProperties* exts;
116 uint32_t ext_count;
117
118 const char** names;
119 uint32_t name_count;
120 };
121
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800122 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800123
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800124 VkResult SanitizeLayers();
125 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800126
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800127 VkResult QueryExtensionCount(uint32_t& count) const;
128 VkResult EnumerateExtensions(uint32_t& count,
129 VkExtensionProperties* props) const;
130 VkResult InitExtensionFilter();
131 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800132
133 const bool is_instance_;
134 const VkAllocationCallbacks& allocator_;
135
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800136 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800137
138 union {
139 VkInstanceCreateInfo instance_info_;
140 VkDeviceCreateInfo dev_info_;
141 };
142
Ian Elliottf3e872d2017-11-02 10:15:13 -0600143 VkApplicationInfo application_info_;
144
Chia-I Wu4901db72016-03-24 16:38:58 +0800145 ExtensionFilter extension_filter_;
146
147 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
148 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
149};
150
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800151Hal Hal::hal_;
152
Jesse Hall53457db2016-12-14 16:54:06 -0800153void* LoadLibrary(const android_dlextinfo& dlextinfo,
Nick Desaulniers60307ce2019-10-25 13:34:21 -0700154 const std::string_view subname) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800155 ATRACE_CALL();
156
Nick Desaulniers60307ce2019-10-25 13:34:21 -0700157 std::stringstream ss;
158 ss << "vulkan." << subname << ".so";
159 return android_dlopen_ext(ss.str().c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
Jesse Hall53457db2016-12-14 16:54:06 -0800160}
161
162const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
163 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
164 "ro.board.platform",
165}};
166
Peiyong Linefa0cbd2020-01-29 20:51:50 -0800167// LoadDriver returns:
168// * 0 when succeed, or
169// * -ENOENT when fail to open binary libraries, or
170// * -EINVAL when fail to find HAL_MODULE_INFO_SYM_AS_STR or
171// HWVULKAN_HARDWARE_MODULE_ID in the library.
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);
Nick Desaulniers60307ce2019-10-25 13:34:21 -0700184 if (prop_len > 0 && prop_len <= UINT_MAX) {
185 std::string_view lib_name(prop, static_cast<unsigned int>(prop_len));
186 so = LoadLibrary(dlextinfo, lib_name);
Jesse Hall53457db2016-12-14 16:54:06 -0800187 if (so)
188 break;
189 }
190 }
191 if (!so)
192 return -ENOENT;
193
Jesse Hall00e61ff2017-04-07 16:48:02 -0700194 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800195 if (!hmi) {
196 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
197 dlclose(so);
198 return -EINVAL;
199 }
200 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
201 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
202 dlclose(so);
203 return -EINVAL;
204 }
205 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700206 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800207 return 0;
208}
209
Jesse Hall00e61ff2017-04-07 16:48:02 -0700210int LoadBuiltinDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800211 ATRACE_CALL();
212
Jesse Hall00e61ff2017-04-07 16:48:02 -0700213 auto ns = android_get_exported_namespace("sphal");
214 if (!ns)
215 return -ENOENT;
Yiwei Zhangd9861812019-02-13 11:51:55 -0800216 android::GraphicsEnv::getInstance().setDriverToLoad(
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -0700217 android::GpuStatsInfo::Driver::VULKAN);
Jesse Hall00e61ff2017-04-07 16:48:02 -0700218 return LoadDriver(ns, module);
219}
220
221int LoadUpdatedDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800222 ATRACE_CALL();
223
Jesse Hall00e61ff2017-04-07 16:48:02 -0700224 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
225 if (!ns)
226 return -ENOENT;
Yiwei Zhangd9861812019-02-13 11:51:55 -0800227 android::GraphicsEnv::getInstance().setDriverToLoad(
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -0700228 android::GpuStatsInfo::Driver::VULKAN_UPDATED);
Peiyong Linefa0cbd2020-01-29 20:51:50 -0800229 int result = LoadDriver(ns, module);
230 if (result != 0) {
231 LOG_ALWAYS_FATAL(
232 "couldn't find an updated Vulkan implementation from %s",
233 android::GraphicsEnv::getInstance().getDriverPath().c_str());
234 }
235 return result;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700236}
237
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800238bool Hal::Open() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800239 ATRACE_CALL();
240
Yiwei Zhangd9861812019-02-13 11:51:55 -0800241 const nsecs_t openTime = systemTime();
242
Jesse Halldc225072016-05-30 22:40:14 -0700243 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800244
245 // Use a stub device unless we successfully open a real HAL device.
246 hal_.dev_ = &stubhal::kDevice;
247
Jesse Hall53457db2016-12-14 16:54:06 -0800248 int result;
249 const hwvulkan_module_t* module = nullptr;
250
Jesse Hall00e61ff2017-04-07 16:48:02 -0700251 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800252 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700253 result = LoadBuiltinDriver(&module);
254 if (result != 0) {
255 // -ENOENT means the sphal namespace doesn't exist, not that there
256 // is a problem with the driver.
257 ALOGW_IF(
258 result != -ENOENT,
259 "Failed to load Vulkan driver into sphal namespace. This "
260 "usually means the driver has forbidden library dependencies."
261 "Please fix, this will soon stop working.");
262 result =
263 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
264 reinterpret_cast<const hw_module_t**>(&module));
265 }
Jesse Hall53457db2016-12-14 16:54:06 -0800266 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800267 if (result != 0) {
Yiwei Zhangd9861812019-02-13 11:51:55 -0800268 android::GraphicsEnv::getInstance().setDriverLoaded(
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -0700269 android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
Jesse Hall53457db2016-12-14 16:54:06 -0800270 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800271 return true;
272 }
273
Yiwei Zhangcb9d4e42019-02-06 20:22:59 -0800274
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800275 hwvulkan_device_t* device;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800276 ATRACE_BEGIN("hwvulkan module open");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800277 result =
278 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
279 reinterpret_cast<hw_device_t**>(&device));
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800280 ATRACE_END();
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800281 if (result != 0) {
Yiwei Zhangd9861812019-02-13 11:51:55 -0800282 android::GraphicsEnv::getInstance().setDriverLoaded(
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -0700283 android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800284 // Any device with a Vulkan HAL should be able to open the device.
285 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
286 result);
287 return false;
288 }
289
290 hal_.dev_ = device;
291
Chia-I Wu31938252016-05-23 15:31:02 +0800292 hal_.InitDebugReportIndex();
293
Yiwei Zhangd9861812019-02-13 11:51:55 -0800294 android::GraphicsEnv::getInstance().setDriverLoaded(
Yiwei Zhang27ab3ac2019-07-02 18:10:55 -0700295 android::GpuStatsInfo::Api::API_VK, true, systemTime() - openTime);
Yiwei Zhangd9861812019-02-13 11:51:55 -0800296
Chia-I Wu31938252016-05-23 15:31:02 +0800297 return true;
298}
299
300bool Hal::InitDebugReportIndex() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800301 ATRACE_CALL();
302
Chia-I Wu31938252016-05-23 15:31:02 +0800303 uint32_t count;
304 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
305 VK_SUCCESS) {
306 ALOGE("failed to get HAL instance extension count");
307 return false;
308 }
309
310 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
311 malloc(sizeof(VkExtensionProperties) * count));
312 if (!exts) {
313 ALOGE("failed to allocate HAL instance extension array");
314 return false;
315 }
316
317 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
318 VK_SUCCESS) {
319 ALOGE("failed to enumerate HAL instance extensions");
320 free(exts);
321 return false;
322 }
323
324 for (uint32_t i = 0; i < count; i++) {
325 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
326 0) {
327 debug_report_index_ = static_cast<int>(i);
328 break;
329 }
330 }
331
332 free(exts);
333
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800334 return true;
335}
336
337CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800338 const VkAllocationCallbacks& allocator)
339 : is_instance_(true),
340 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800341 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800342 instance_info_(create_info),
343 extension_filter_() {
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700344 // instance core versions need to match the loader api version
345 for (uint32_t i = ProcHook::EXTENSION_CORE_1_0;
346 i != ProcHook::EXTENSION_COUNT; ++i) {
347 hook_extensions_.set(i);
348 hal_extensions_.set(i);
349 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800350}
351
Chia-I Wu4901db72016-03-24 16:38:58 +0800352CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
353 const VkDeviceCreateInfo& create_info,
354 const VkAllocationCallbacks& allocator)
355 : is_instance_(false),
356 allocator_(allocator),
357 physical_dev_(physical_dev),
358 dev_info_(create_info),
359 extension_filter_() {
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700360 // initialize with baseline core API version
361 hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
362 hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
Chia-I Wu4901db72016-03-24 16:38:58 +0800363}
364
365CreateInfoWrapper::~CreateInfoWrapper() {
366 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
367 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
368}
369
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800370VkResult CreateInfoWrapper::Validate() {
371 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800372 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800373 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800374 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800375 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800376
377 return result;
378}
379
380const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800381CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800382 return hook_extensions_;
383}
384
385const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800386CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800387 return hal_extensions_;
388}
389
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800390CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
391 return &instance_info_;
392}
393
Chia-I Wu4901db72016-03-24 16:38:58 +0800394CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
395 return &dev_info_;
396}
397
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800398VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800399 const struct StructHeader {
400 VkStructureType type;
401 const void* next;
402 } * header;
403
404 if (is_instance_) {
405 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
406
407 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
408 while (header &&
409 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
410 header = reinterpret_cast<const StructHeader*>(header->next);
411
412 instance_info_.pNext = header;
413 } else {
414 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
415
416 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
417 while (header &&
418 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
419 header = reinterpret_cast<const StructHeader*>(header->next);
420
421 dev_info_.pNext = header;
422 }
423
424 return VK_SUCCESS;
425}
426
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800427VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800428 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
429 : dev_info_.ppEnabledLayerNames;
430 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
431 : dev_info_.enabledLayerCount;
432
433 // remove all layers
434 layer_names = nullptr;
435 layer_count = 0;
436
437 return VK_SUCCESS;
438}
439
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800440VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800441 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
442 : dev_info_.ppEnabledExtensionNames;
443 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
444 : dev_info_.enabledExtensionCount;
445 if (!ext_count)
446 return VK_SUCCESS;
447
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800448 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800449 if (result != VK_SUCCESS)
450 return result;
451
452 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800453 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800454
Jesse Halld3d887a2018-03-05 13:34:45 -0800455 // Enable device extensions that contain physical-device commands, so that
456 // vkGetInstanceProcAddr will return those physical-device commands.
457 if (is_instance_) {
458 hook_extensions_.set(ProcHook::KHR_swapchain);
459 }
460
Chia-I Wu4901db72016-03-24 16:38:58 +0800461 ext_names = extension_filter_.names;
462 ext_count = extension_filter_.name_count;
463
464 return VK_SUCCESS;
465}
466
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800467VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800468 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800469 return Hal::Device().EnumerateInstanceExtensionProperties(
470 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800471 } else {
472 const auto& driver = GetData(physical_dev_).driver;
473 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
474 &count, nullptr);
475 }
476}
477
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800478VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800479 uint32_t& count,
480 VkExtensionProperties* props) const {
481 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800482 return Hal::Device().EnumerateInstanceExtensionProperties(
483 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800484 } else {
485 const auto& driver = GetData(physical_dev_).driver;
486 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
487 &count, props);
488 }
489}
490
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800491VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800492 // query extension count
493 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800494 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800495 if (result != VK_SUCCESS || count == 0)
496 return result;
497
498 auto& filter = extension_filter_;
499 filter.exts =
500 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
501 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
502 alignof(VkExtensionProperties),
503 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
504 if (!filter.exts)
505 return VK_ERROR_OUT_OF_HOST_MEMORY;
506
507 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800508 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800509 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
510 return result;
511
512 if (!count)
513 return VK_SUCCESS;
514
515 filter.ext_count = count;
516
517 // allocate name array
518 uint32_t enabled_ext_count = (is_instance_)
519 ? instance_info_.enabledExtensionCount
520 : dev_info_.enabledExtensionCount;
521 count = std::min(filter.ext_count, enabled_ext_count);
522 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
523 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
524 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
525 if (!filter.names)
526 return VK_ERROR_OUT_OF_HOST_MEMORY;
527
528 return VK_SUCCESS;
529}
530
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800531void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800532 auto& filter = extension_filter_;
533
534 ProcHook::Extension ext_bit = GetProcHookExtension(name);
535 if (is_instance_) {
536 switch (ext_bit) {
537 case ProcHook::KHR_android_surface:
538 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700539 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300540 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800541 hook_extensions_.set(ext_bit);
542 // return now as these extensions do not require HAL support
543 return;
544 case ProcHook::EXT_debug_report:
545 // both we and HAL can take part in
546 hook_extensions_.set(ext_bit);
547 break;
Chris Forbes6aa30db2017-02-20 17:12:53 +1300548 case ProcHook::KHR_get_physical_device_properties2:
Jesse Hall7f983a82018-03-29 14:46:45 -0700549 case ProcHook::EXTENSION_UNKNOWN:
550 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800551 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700552
Yiwei Zhang23143102019-04-10 18:24:05 -0700553 case ProcHook::KHR_bind_memory2:
Jesse Hall7f983a82018-03-29 14:46:45 -0700554 case ProcHook::KHR_incremental_present:
555 case ProcHook::KHR_shared_presentable_image:
556 case ProcHook::KHR_swapchain:
557 case ProcHook::EXT_hdr_metadata:
558 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
559 case ProcHook::ANDROID_native_buffer:
560 case ProcHook::GOOGLE_display_timing:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700561 case ProcHook::EXTENSION_CORE_1_0:
562 case ProcHook::EXTENSION_CORE_1_1:
Jesse Hall7f983a82018-03-29 14:46:45 -0700563 case ProcHook::EXTENSION_COUNT:
564 // Device and meta extensions. If we ever get here it's a bug in
565 // our code. But enumerating them lets us avoid having a default
566 // case, and default hides other bugs.
567 ALOGE(
568 "CreateInfoWrapper::FilterExtension: invalid instance "
569 "extension '%s'. FIX ME",
570 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800571 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700572
573 // Don't use a default case. Without it, -Wswitch will tell us
574 // at compile time if someone adds a new ProcHook extension but
575 // doesn't handle it above. That's a real bug that has
576 // not-immediately-obvious effects.
577 //
578 // default:
579 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800580 }
581 } else {
582 switch (ext_bit) {
583 case ProcHook::KHR_swapchain:
584 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
585 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
586 ext_bit = ProcHook::ANDROID_native_buffer;
587 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700588 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700589 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300590 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700591 hook_extensions_.set(ext_bit);
592 // return now as these extensions do not require HAL support
593 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700594 case ProcHook::EXT_hdr_metadata:
Yiwei Zhang23143102019-04-10 18:24:05 -0700595 case ProcHook::KHR_bind_memory2:
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700596 hook_extensions_.set(ext_bit);
597 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700598 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
Chia-I Wu4901db72016-03-24 16:38:58 +0800599 case ProcHook::EXTENSION_UNKNOWN:
Jesse Hall7f983a82018-03-29 14:46:45 -0700600 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800601 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700602
603 case ProcHook::KHR_android_surface:
604 case ProcHook::KHR_get_physical_device_properties2:
605 case ProcHook::KHR_get_surface_capabilities2:
606 case ProcHook::KHR_surface:
607 case ProcHook::EXT_debug_report:
608 case ProcHook::EXT_swapchain_colorspace:
609 case ProcHook::ANDROID_native_buffer:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700610 case ProcHook::EXTENSION_CORE_1_0:
611 case ProcHook::EXTENSION_CORE_1_1:
Jesse Hall7f983a82018-03-29 14:46:45 -0700612 case ProcHook::EXTENSION_COUNT:
613 // Instance and meta extensions. If we ever get here it's a bug
614 // in our code. But enumerating them lets us avoid having a
615 // default case, and default hides other bugs.
616 ALOGE(
617 "CreateInfoWrapper::FilterExtension: invalid device "
618 "extension '%s'. FIX ME",
619 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800620 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700621
622 // Don't use a default case. Without it, -Wswitch will tell us
623 // at compile time if someone adds a new ProcHook extension but
624 // doesn't handle it above. That's a real bug that has
625 // not-immediately-obvious effects.
626 //
627 // default:
628 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800629 }
630 }
631
632 for (uint32_t i = 0; i < filter.ext_count; i++) {
633 const VkExtensionProperties& props = filter.exts[i];
634 // ignore unknown extensions
635 if (strcmp(name, props.extensionName) != 0)
636 continue;
637
Chia-I Wu4901db72016-03-24 16:38:58 +0800638 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800639 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
640 if (ext_bit == ProcHook::ANDROID_native_buffer)
641 hook_extensions_.set(ProcHook::KHR_swapchain);
642
643 hal_extensions_.set(ext_bit);
644 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800645
646 break;
647 }
648}
649
Ian Elliottf3e872d2017-11-02 10:15:13 -0600650void CreateInfoWrapper::DowngradeApiVersion() {
651 // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
652 if (instance_info_.pApplicationInfo) {
653 application_info_ = *instance_info_.pApplicationInfo;
654 instance_info_.pApplicationInfo = &application_info_;
655 application_info_.apiVersion = VK_API_VERSION_1_0;
656 }
657}
658
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700659void CreateInfoWrapper::UpgradeDeviceCoreApiVersion(uint32_t api_version) {
660 ALOG_ASSERT(!is_instance_, "Device only API called by instance wrapper.");
661
662#pragma clang diagnostic push
663#pragma clang diagnostic ignored "-Wold-style-cast"
664 api_version ^= VK_VERSION_PATCH(api_version);
665#pragma clang diagnostic pop
666
667 // cap the API version to the loader supported highest version
668 if (api_version > VK_API_VERSION_1_1)
669 api_version = VK_API_VERSION_1_1;
670
671 switch (api_version) {
672 case VK_API_VERSION_1_1:
673 hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
674 hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
675 [[clang::fallthrough]];
676 case VK_API_VERSION_1_0:
677 break;
678 default:
679 ALOGD("Unknown upgrade API version[%u]", api_version);
680 break;
681 }
682}
683
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800684VKAPI_ATTR void* DefaultAllocate(void*,
685 size_t size,
686 size_t alignment,
687 VkSystemAllocationScope) {
688 void* ptr = nullptr;
689 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
690 // additionally requires that it be at least sizeof(void*).
691 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
692 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
693 ret, ptr);
694 return ret == 0 ? ptr : nullptr;
695}
696
697VKAPI_ATTR void* DefaultReallocate(void*,
698 void* ptr,
699 size_t size,
700 size_t alignment,
701 VkSystemAllocationScope) {
702 if (size == 0) {
703 free(ptr);
704 return nullptr;
705 }
706
Yiwei Zhanga885c062019-10-24 12:07:57 -0700707 // TODO(b/143295633): Right now we never shrink allocations; if the new
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800708 // request is smaller than the existing chunk, we just continue using it.
709 // Right now the loader never reallocs, so this doesn't matter. If that
710 // changes, or if this code is copied into some other project, this should
711 // probably have a heuristic to allocate-copy-free when doing so will save
712 // "enough" space.
713 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
714 if (size <= old_size)
715 return ptr;
716
717 void* new_ptr = nullptr;
718 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
719 return nullptr;
720 if (ptr) {
721 memcpy(new_ptr, ptr, std::min(old_size, size));
722 free(ptr);
723 }
724 return new_ptr;
725}
726
727VKAPI_ATTR void DefaultFree(void*, void* ptr) {
728 ALOGD_CALLSTACK("Free: %p", ptr);
729 free(ptr);
730}
731
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800732InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
733 void* data_mem = allocator.pfnAllocation(
734 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
735 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
736 if (!data_mem)
737 return nullptr;
738
739 return new (data_mem) InstanceData(allocator);
740}
741
742void FreeInstanceData(InstanceData* data,
743 const VkAllocationCallbacks& allocator) {
744 data->~InstanceData();
745 allocator.pfnFree(allocator.pUserData, data);
746}
747
Chia-I Wu950d6e12016-05-03 09:12:35 +0800748DeviceData* AllocateDeviceData(
749 const VkAllocationCallbacks& allocator,
750 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800751 void* data_mem = allocator.pfnAllocation(
752 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
753 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
754 if (!data_mem)
755 return nullptr;
756
Chia-I Wu950d6e12016-05-03 09:12:35 +0800757 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800758}
759
760void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
761 data->~DeviceData();
762 allocator.pfnFree(allocator.pUserData, data);
763}
764
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800765} // anonymous namespace
766
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800767bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800768 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800769}
770
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800771const VkAllocationCallbacks& GetDefaultAllocator() {
772 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
773 .pUserData = nullptr,
774 .pfnAllocation = DefaultAllocate,
775 .pfnReallocation = DefaultReallocate,
776 .pfnFree = DefaultFree,
777 };
778
779 return kDefaultAllocCallbacks;
780}
781
Chia-I Wueb7db122016-03-24 09:11:06 +0800782PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
783 const ProcHook* hook = GetProcHook(pName);
784 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800785 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800786
787 if (!instance) {
788 if (hook->type == ProcHook::GLOBAL)
789 return hook->proc;
790
Chia-I Wu109f8982016-04-22 06:40:40 +0800791 // v0 layers expect
792 //
793 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
794 //
795 // to work.
796 if (strcmp(pName, "vkCreateDevice") == 0)
797 return hook->proc;
798
Chia-I Wueb7db122016-03-24 09:11:06 +0800799 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800800 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800801 pName);
802
Chia-I Wu109f8982016-04-22 06:40:40 +0800803 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800804 }
805
806 PFN_vkVoidFunction proc;
807
808 switch (hook->type) {
809 case ProcHook::INSTANCE:
810 proc = (GetData(instance).hook_extensions[hook->extension])
811 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800812 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800813 break;
814 case ProcHook::DEVICE:
Yiwei Zhang7cc36a52019-10-11 19:02:09 -0700815 proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
Chia-I Wueb7db122016-03-24 09:11:06 +0800816 ? hook->proc
817 : hook->checked_proc;
818 break;
819 default:
820 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800821 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800822 pName);
823 proc = nullptr;
824 break;
825 }
826
827 return proc;
828}
829
830PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
831 const ProcHook* hook = GetProcHook(pName);
832 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800833 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800834
835 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800836 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800837 return nullptr;
838 }
839
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800840 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
841 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800842}
843
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800844VkResult EnumerateInstanceExtensionProperties(
845 const char* pLayerName,
846 uint32_t* pPropertyCount,
847 VkExtensionProperties* pProperties) {
Yiwei Zhang5e862202019-06-21 14:59:16 -0700848 std::vector<VkExtensionProperties> loader_extensions;
Ian Elliott34a327b2017-03-28 13:20:35 -0600849 loader_extensions.push_back({
850 VK_KHR_SURFACE_EXTENSION_NAME,
851 VK_KHR_SURFACE_SPEC_VERSION});
852 loader_extensions.push_back({
853 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
854 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
855 loader_extensions.push_back({
856 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
857 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700858 loader_extensions.push_back({
859 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
860 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600861
Chia-I Wu31938252016-05-23 15:31:02 +0800862 static const VkExtensionProperties loader_debug_report_extension = {
863 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
864 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800865
866 // enumerate our extensions first
867 if (!pLayerName && pProperties) {
868 uint32_t count = std::min(
869 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
870
Yiwei Zhang5e862202019-06-21 14:59:16 -0700871 std::copy_n(loader_extensions.data(), count, pProperties);
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800872
873 if (count < loader_extensions.size()) {
874 *pPropertyCount = count;
875 return VK_INCOMPLETE;
876 }
877
878 pProperties += count;
879 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800880
881 if (Hal::Get().GetDebugReportIndex() < 0) {
882 if (!*pPropertyCount) {
883 *pPropertyCount = count;
884 return VK_INCOMPLETE;
885 }
886
887 pProperties[0] = loader_debug_report_extension;
888 pProperties += 1;
889 *pPropertyCount -= 1;
890 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800891 }
892
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800893 ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800894 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800895 pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800896 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800897
Chia-I Wu31938252016-05-23 15:31:02 +0800898 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
899 int idx = Hal::Get().GetDebugReportIndex();
900 if (idx < 0) {
901 *pPropertyCount += 1;
902 } else if (pProperties &&
903 static_cast<uint32_t>(idx) < *pPropertyCount) {
904 pProperties[idx].specVersion =
905 std::min(pProperties[idx].specVersion,
906 loader_debug_report_extension.specVersion);
907 }
908
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800909 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800910 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800911
912 return result;
913}
914
Chris Forbesfa25e632017-02-22 12:36:02 +1300915bool QueryPresentationProperties(
916 VkPhysicalDevice physicalDevice,
Yiwei Zhang5e862202019-06-21 14:59:16 -0700917 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties) {
Chris Forbesfa25e632017-02-22 12:36:02 +1300918 const InstanceData& data = GetData(physicalDevice);
919
920 // GPDP2 must be present and enabled on the instance.
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700921 if (!data.driver.GetPhysicalDeviceProperties2KHR &&
922 !data.driver.GetPhysicalDeviceProperties2)
Chris Forbesfa25e632017-02-22 12:36:02 +1300923 return false;
924
925 // Request the android-specific presentation properties via GPDP2
926 VkPhysicalDeviceProperties2KHR properties = {
927 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
928 presentation_properties,
929 {}
930 };
931
932#pragma clang diagnostic push
933#pragma clang diagnostic ignored "-Wold-style-cast"
934 presentation_properties->sType =
935 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
936#pragma clang diagnostic pop
937 presentation_properties->pNext = nullptr;
938 presentation_properties->sharedImage = VK_FALSE;
939
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700940 if (data.driver.GetPhysicalDeviceProperties2KHR) {
941 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
942 &properties);
943 } else {
944 data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
945 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300946
947 return true;
948}
949
Chia-I Wu01cf3052016-03-24 16:16:21 +0800950VkResult EnumerateDeviceExtensionProperties(
951 VkPhysicalDevice physicalDevice,
952 const char* pLayerName,
953 uint32_t* pPropertyCount,
954 VkExtensionProperties* pProperties) {
955 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300956 // extensions that are unconditionally exposed by the loader
Yiwei Zhang5e862202019-06-21 14:59:16 -0700957 std::vector<VkExtensionProperties> loader_extensions;
Chris Forbesfa25e632017-02-22 12:36:02 +1300958 loader_extensions.push_back({
959 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
960 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300961
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -0800962 bool hdrBoardConfig =
963 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
964 false);
965 if (hdrBoardConfig) {
966 loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
967 VK_EXT_HDR_METADATA_SPEC_VERSION});
968 }
969
Chris Forbes16095002017-05-05 15:33:29 -0700970 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
971 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
972 presentation_properties.sharedImage) {
973 loader_extensions.push_back({
974 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
975 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300976 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700977
Ian Elliott5c34de22017-04-10 14:42:30 -0600978 // conditionally add VK_GOOGLE_display_timing if present timestamps are
979 // supported by the driver:
Wei Wangf9b05ee2017-07-19 20:59:39 -0700980 const std::string timestamp_property("service.sf.present_timestamp");
981 android::base::WaitForPropertyCreation(timestamp_property);
982 if (android::base::GetBoolProperty(timestamp_property, true)) {
Ian Elliott5c34de22017-04-10 14:42:30 -0600983 loader_extensions.push_back({
984 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
985 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
986 }
987
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700988 // enumerate our extensions first
989 if (!pLayerName && pProperties) {
990 uint32_t count = std::min(
991 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
992
Yiwei Zhang5e862202019-06-21 14:59:16 -0700993 std::copy_n(loader_extensions.data(), count, pProperties);
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700994
995 if (count < loader_extensions.size()) {
996 *pPropertyCount = count;
997 return VK_INCOMPLETE;
998 }
999
1000 pProperties += count;
1001 *pPropertyCount -= count;
1002 }
Chia-I Wu01cf3052016-03-24 16:16:21 +08001003
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001004 ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
Chia-I Wu01cf3052016-03-24 16:16:21 +08001005 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
1006 physicalDevice, pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001007 ATRACE_END();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001008
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001009 if (pProperties) {
1010 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
1011 for (uint32_t i = 0; i < *pPropertyCount; i++) {
1012 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +08001013
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001014 if (strcmp(prop.extensionName,
1015 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
1016 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +08001017
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001018 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
1019 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
Yiwei Zhang14f4d422019-04-17 12:24:39 -07001020
1021 if (prop.specVersion >= 8) {
1022 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
1023 } else {
1024 prop.specVersion = 68;
1025 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001026 }
1027 }
Chia-I Wu01cf3052016-03-24 16:16:21 +08001028
Ian Elliottd4b50aa2017-01-09 16:21:36 -07001029 // restore loader extension count
1030 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
1031 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +08001032 }
1033
1034 return result;
1035}
1036
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001037VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1038 const VkAllocationCallbacks* pAllocator,
1039 VkInstance* pInstance) {
1040 const VkAllocationCallbacks& data_allocator =
1041 (pAllocator) ? *pAllocator : GetDefaultAllocator();
1042
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001043 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001044 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001045 if (result != VK_SUCCESS)
1046 return result;
1047
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001048 ATRACE_BEGIN("AllocateInstanceData");
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001049 InstanceData* data = AllocateInstanceData(data_allocator);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001050 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001051 if (!data)
1052 return VK_ERROR_OUT_OF_HOST_MEMORY;
1053
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001054 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001055
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001056 ATRACE_BEGIN("autoDowngradeApiVersion");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001057#pragma clang diagnostic push
1058#pragma clang diagnostic ignored "-Wold-style-cast"
1059 uint32_t api_version = ((pCreateInfo->pApplicationInfo)
1060 ? pCreateInfo->pApplicationInfo->apiVersion
1061 : VK_API_VERSION_1_0);
1062 uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
1063 uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
1064 uint32_t icd_api_version;
1065 PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1066 reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
Yi Kongbcbc73a2018-07-18 10:13:04 -07001067 Hal::Device().GetInstanceProcAddr(nullptr,
Ian Elliottf3e872d2017-11-02 10:15:13 -06001068 "vkEnumerateInstanceVersion"));
1069 if (!pfn_enumerate_instance_version) {
1070 icd_api_version = VK_API_VERSION_1_0;
1071 } else {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001072 ATRACE_BEGIN("pfn_enumerate_instance_version");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001073 result = (*pfn_enumerate_instance_version)(&icd_api_version);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001074 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001075 }
1076 uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
1077 uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
1078
1079 if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
1080 ((api_major_version > 1) || (api_minor_version > 0))) {
1081 api_version = VK_API_VERSION_1_0;
1082 wrapper.DowngradeApiVersion();
1083 }
1084#pragma clang diagnostic pop
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001085 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001086
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001087 // call into the driver
1088 VkInstance instance;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001089 ATRACE_BEGIN("driver.CreateInstance");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001090 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001091 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1092 &instance);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001093 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001094 if (result != VK_SUCCESS) {
1095 FreeInstanceData(data, data_allocator);
1096 return result;
1097 }
1098
1099 // initialize InstanceDriverTable
1100 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001101 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001102 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001103 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001104 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001105 if (data->driver.DestroyInstance)
1106 data->driver.DestroyInstance(instance, pAllocator);
1107
1108 FreeInstanceData(data, data_allocator);
1109
1110 return VK_ERROR_INCOMPATIBLE_DRIVER;
1111 }
1112
1113 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001114 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001115 if (!data->get_device_proc_addr) {
1116 data->driver.DestroyInstance(instance, pAllocator);
1117 FreeInstanceData(data, data_allocator);
1118
1119 return VK_ERROR_INCOMPATIBLE_DRIVER;
1120 }
1121
1122 *pInstance = instance;
1123
1124 return VK_SUCCESS;
1125}
1126
1127void DestroyInstance(VkInstance instance,
1128 const VkAllocationCallbacks* pAllocator) {
1129 InstanceData& data = GetData(instance);
1130 data.driver.DestroyInstance(instance, pAllocator);
1131
1132 VkAllocationCallbacks local_allocator;
1133 if (!pAllocator) {
1134 local_allocator = data.allocator;
1135 pAllocator = &local_allocator;
1136 }
1137
1138 FreeInstanceData(&data, *pAllocator);
1139}
1140
Chia-I Wu4901db72016-03-24 16:38:58 +08001141VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1142 const VkDeviceCreateInfo* pCreateInfo,
1143 const VkAllocationCallbacks* pAllocator,
1144 VkDevice* pDevice) {
1145 const InstanceData& instance_data = GetData(physicalDevice);
1146 const VkAllocationCallbacks& data_allocator =
1147 (pAllocator) ? *pAllocator : instance_data.allocator;
1148
1149 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001150 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +08001151 if (result != VK_SUCCESS)
1152 return result;
1153
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001154 ATRACE_BEGIN("AllocateDeviceData");
Chia-I Wu950d6e12016-05-03 09:12:35 +08001155 DeviceData* data = AllocateDeviceData(data_allocator,
1156 instance_data.debug_report_callbacks);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001157 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001158 if (!data)
1159 return VK_ERROR_OUT_OF_HOST_MEMORY;
1160
Yiwei Zhang7cc36a52019-10-11 19:02:09 -07001161 VkPhysicalDeviceProperties properties;
1162 ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
1163 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1164 &properties);
1165 ATRACE_END();
1166
1167 wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001168 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +08001169
1170 // call into the driver
1171 VkDevice dev;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001172 ATRACE_BEGIN("driver.CreateDevice");
Chia-I Wu4901db72016-03-24 16:38:58 +08001173 result = instance_data.driver.CreateDevice(
1174 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1175 pAllocator, &dev);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001176 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001177 if (result != VK_SUCCESS) {
1178 FreeDeviceData(data, data_allocator);
1179 return result;
1180 }
1181
1182 // initialize DeviceDriverTable
1183 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001184 !InitDriverTable(dev, instance_data.get_device_proc_addr,
1185 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +08001186 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1187 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1188 if (data->driver.DestroyDevice)
1189 data->driver.DestroyDevice(dev, pAllocator);
1190
1191 FreeDeviceData(data, data_allocator);
1192
1193 return VK_ERROR_INCOMPATIBLE_DRIVER;
1194 }
Chris Forbesd8277912017-02-10 14:59:59 +13001195
1196 // sanity check ANDROID_native_buffer implementation, whose set of
1197 // entrypoints varies according to the spec version.
1198 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1199 !data->driver.GetSwapchainGrallocUsageANDROID &&
1200 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1201 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1202 " must expose at least one of "
1203 "vkGetSwapchainGrallocUsageANDROID or "
1204 "vkGetSwapchainGrallocUsage2ANDROID");
1205
1206 data->driver.DestroyDevice(dev, pAllocator);
1207 FreeDeviceData(data, data_allocator);
1208
1209 return VK_ERROR_INCOMPATIBLE_DRIVER;
1210 }
1211
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -07001212 if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
1213 // Log that the app is hitting software Vulkan implementation
Yiwei Zhangbcba4112019-07-03 13:39:32 -07001214 android::GraphicsEnv::getInstance().setTargetStats(
1215 android::GpuStatsInfo::Stats::CPU_VULKAN_IN_USE);
Yiwei Zhang8c5e3bd2019-05-09 14:34:19 -07001216 }
1217
Jesse Halldc225072016-05-30 22:40:14 -07001218 data->driver_device = dev;
Chia-I Wu4901db72016-03-24 16:38:58 +08001219
1220 *pDevice = dev;
1221
1222 return VK_SUCCESS;
1223}
1224
1225void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1226 DeviceData& data = GetData(device);
1227 data.driver.DestroyDevice(device, pAllocator);
1228
1229 VkAllocationCallbacks local_allocator;
1230 if (!pAllocator) {
1231 local_allocator = data.allocator;
1232 pAllocator = &local_allocator;
1233 }
1234
1235 FreeDeviceData(&data, *pAllocator);
1236}
1237
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001238VkResult EnumeratePhysicalDevices(VkInstance instance,
1239 uint32_t* pPhysicalDeviceCount,
1240 VkPhysicalDevice* pPhysicalDevices) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001241 ATRACE_CALL();
1242
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001243 const auto& data = GetData(instance);
1244
1245 VkResult result = data.driver.EnumeratePhysicalDevices(
1246 instance, pPhysicalDeviceCount, pPhysicalDevices);
1247 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1248 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1249 SetData(pPhysicalDevices[i], data);
1250 }
1251
1252 return result;
1253}
1254
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001255VkResult EnumeratePhysicalDeviceGroups(
1256 VkInstance instance,
1257 uint32_t* pPhysicalDeviceGroupCount,
1258 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001259 ATRACE_CALL();
1260
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001261 VkResult result = VK_SUCCESS;
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001262 const auto& data = GetData(instance);
1263
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001264 if (!data.driver.EnumeratePhysicalDeviceGroups) {
1265 uint32_t device_count = 0;
1266 result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1267 if (result < 0)
1268 return result;
Chad Versace32c087f2018-09-09 07:28:05 -07001269
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001270 if (!pPhysicalDeviceGroupProperties) {
1271 *pPhysicalDeviceGroupCount = device_count;
1272 return result;
1273 }
1274
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001275 if (!device_count) {
1276 *pPhysicalDeviceGroupCount = 0;
1277 return result;
1278 }
Chad Versace32c087f2018-09-09 07:28:05 -07001279 device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1280 if (!device_count)
1281 return VK_INCOMPLETE;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001282
Yiwei Zhang5e862202019-06-21 14:59:16 -07001283 std::vector<VkPhysicalDevice> devices(device_count);
Chad Versace32c087f2018-09-09 07:28:05 -07001284 *pPhysicalDeviceGroupCount = device_count;
Yiwei Zhang5e862202019-06-21 14:59:16 -07001285 result =
1286 EnumeratePhysicalDevices(instance, &device_count, devices.data());
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001287 if (result < 0)
1288 return result;
1289
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001290 for (uint32_t i = 0; i < device_count; ++i) {
1291 pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1292 pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1293 pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1294 }
1295 } else {
1296 result = data.driver.EnumeratePhysicalDeviceGroups(
1297 instance, pPhysicalDeviceGroupCount,
1298 pPhysicalDeviceGroupProperties);
1299 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1300 *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1301 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1302 for (uint32_t j = 0;
1303 j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1304 j++) {
1305 SetData(
1306 pPhysicalDeviceGroupProperties[i].physicalDevices[j],
Ian Elliottcd8ad332017-10-13 09:21:12 -06001307 data);
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001308 }
Ian Elliottcd8ad332017-10-13 09:21:12 -06001309 }
1310 }
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001311 }
1312
1313 return result;
1314}
1315
Chia-I Wuba0be412016-03-24 16:24:40 +08001316void GetDeviceQueue(VkDevice device,
1317 uint32_t queueFamilyIndex,
1318 uint32_t queueIndex,
1319 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001320 ATRACE_CALL();
1321
Chia-I Wuba0be412016-03-24 16:24:40 +08001322 const auto& data = GetData(device);
1323
1324 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1325 SetData(*pQueue, data);
1326}
1327
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001328void GetDeviceQueue2(VkDevice device,
1329 const VkDeviceQueueInfo2* pQueueInfo,
1330 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001331 ATRACE_CALL();
1332
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001333 const auto& data = GetData(device);
1334
1335 data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
Yiwei Zhangf5b9f732018-02-07 14:06:09 -08001336 if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001337}
1338
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001339VKAPI_ATTR VkResult
1340AllocateCommandBuffers(VkDevice device,
1341 const VkCommandBufferAllocateInfo* pAllocateInfo,
1342 VkCommandBuffer* pCommandBuffers) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001343 ATRACE_CALL();
1344
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001345 const auto& data = GetData(device);
1346
1347 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1348 pCommandBuffers);
1349 if (result == VK_SUCCESS) {
1350 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1351 SetData(pCommandBuffers[i], data);
1352 }
1353
1354 return result;
1355}
1356
Yiwei Zhang899d1752019-09-23 16:05:35 -07001357VKAPI_ATTR VkResult QueueSubmit(VkQueue queue,
1358 uint32_t submitCount,
1359 const VkSubmitInfo* pSubmits,
1360 VkFence fence) {
1361 ATRACE_CALL();
1362
1363 const auto& data = GetData(queue);
1364
1365 return data.driver.QueueSubmit(queue, submitCount, pSubmits, fence);
1366}
1367
Chia-I Wu9d518162016-03-24 14:55:27 +08001368} // namespace driver
1369} // namespace vulkan