blob: 3a8e34eff27d441974cab626c0c1e06c52dc6d76 [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 Zhangfdd0c2a2019-01-30 20:16:37 -080036#include <utils/Trace.h>
Chris Forbesfa25e632017-02-22 12:36:02 +130037#include <utils/Vector.h>
Jesse Hall53457db2016-12-14 16:54:06 -080038
Wei Wangf9b05ee2017-07-19 20:59:39 -070039#include "android-base/properties.h"
40
Chia-I Wu9d518162016-03-24 14:55:27 +080041#include "driver.h"
Jesse Hallb7c4e3b2016-04-11 13:51:38 -070042#include "stubhal.h"
Chia-I Wu9d518162016-03-24 14:55:27 +080043
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080044using namespace android::hardware::configstore;
45using namespace android::hardware::configstore::V1_0;
46
Jesse Hall00e61ff2017-04-07 16:48:02 -070047// TODO(b/37049319) Get this from a header once one exists
48extern "C" {
49android_namespace_t* android_get_exported_namespace(const char*);
50}
51
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080052// #define ENABLE_ALLOC_CALLSTACKS 1
53#if ENABLE_ALLOC_CALLSTACKS
54#include <utils/CallStack.h>
55#define ALOGD_CALLSTACK(...) \
56 do { \
57 ALOGD(__VA_ARGS__); \
58 android::CallStack callstack; \
59 callstack.update(); \
60 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
61 } while (false)
62#else
63#define ALOGD_CALLSTACK(...) \
64 do { \
65 } while (false)
66#endif
67
Chia-I Wu9d518162016-03-24 14:55:27 +080068namespace vulkan {
69namespace driver {
70
Chia-I Wu136b8eb2016-03-24 15:01:52 +080071namespace {
72
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080073class Hal {
74 public:
75 static bool Open();
76
77 static const Hal& Get() { return hal_; }
78 static const hwvulkan_device_t& Device() { return *Get().dev_; }
79
Chia-I Wu31938252016-05-23 15:31:02 +080080 int GetDebugReportIndex() const { return debug_report_index_; }
81
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080082 private:
Chia-I Wu31938252016-05-23 15:31:02 +080083 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080084 Hal(const Hal&) = delete;
85 Hal& operator=(const Hal&) = delete;
86
Chia-I Wu31938252016-05-23 15:31:02 +080087 bool InitDebugReportIndex();
88
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080089 static Hal hal_;
90
91 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080092 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080093};
94
Chia-I Wu4901db72016-03-24 16:38:58 +080095class CreateInfoWrapper {
96 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080097 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080098 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080099 CreateInfoWrapper(VkPhysicalDevice physical_dev,
100 const VkDeviceCreateInfo& create_info,
101 const VkAllocationCallbacks& allocator);
102 ~CreateInfoWrapper();
103
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800104 VkResult Validate();
Ian Elliottf3e872d2017-11-02 10:15:13 -0600105 void DowngradeApiVersion();
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,
154 const char* subname,
155 int subname_len) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800156 ATRACE_CALL();
157
Jesse Hall53457db2016-12-14 16:54:06 -0800158 const char kLibFormat[] = "vulkan.%*s.so";
159 char* name = static_cast<char*>(
160 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
161 sprintf(name, kLibFormat, subname_len, subname);
162 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
163}
164
165const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
166 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
167 "ro.board.platform",
168}};
169
Jesse Hall00e61ff2017-04-07 16:48:02 -0700170int LoadDriver(android_namespace_t* library_namespace,
171 const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800172 ATRACE_CALL();
173
Jesse Hall53457db2016-12-14 16:54:06 -0800174 const android_dlextinfo dlextinfo = {
175 .flags = ANDROID_DLEXT_USE_NAMESPACE,
Jesse Hall00e61ff2017-04-07 16:48:02 -0700176 .library_namespace = library_namespace,
Jesse Hall53457db2016-12-14 16:54:06 -0800177 };
Jesse Hall53457db2016-12-14 16:54:06 -0800178 void* so = nullptr;
179 char prop[PROPERTY_VALUE_MAX];
180 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
181 int prop_len = property_get(key, prop, nullptr);
182 if (prop_len > 0) {
183 so = LoadLibrary(dlextinfo, prop, prop_len);
184 if (so)
185 break;
186 }
187 }
188 if (!so)
189 return -ENOENT;
190
Jesse Hall00e61ff2017-04-07 16:48:02 -0700191 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800192 if (!hmi) {
193 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
194 dlclose(so);
195 return -EINVAL;
196 }
197 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
198 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
199 dlclose(so);
200 return -EINVAL;
201 }
202 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700203 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800204 return 0;
205}
206
Jesse Hall00e61ff2017-04-07 16:48:02 -0700207int LoadBuiltinDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800208 ATRACE_CALL();
209
Jesse Hall00e61ff2017-04-07 16:48:02 -0700210 auto ns = android_get_exported_namespace("sphal");
211 if (!ns)
212 return -ENOENT;
213 return LoadDriver(ns, module);
214}
215
216int LoadUpdatedDriver(const hwvulkan_module_t** module) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800217 ATRACE_CALL();
218
Jesse Hall00e61ff2017-04-07 16:48:02 -0700219 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
220 if (!ns)
221 return -ENOENT;
222 return LoadDriver(ns, module);
223}
224
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800225bool Hal::Open() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800226 ATRACE_CALL();
227
Jesse Halldc225072016-05-30 22:40:14 -0700228 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800229
230 // Use a stub device unless we successfully open a real HAL device.
231 hal_.dev_ = &stubhal::kDevice;
232
Jesse Hall53457db2016-12-14 16:54:06 -0800233 int result;
234 const hwvulkan_module_t* module = nullptr;
235
Jesse Hall00e61ff2017-04-07 16:48:02 -0700236 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800237 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700238 result = LoadBuiltinDriver(&module);
239 if (result != 0) {
240 // -ENOENT means the sphal namespace doesn't exist, not that there
241 // is a problem with the driver.
242 ALOGW_IF(
243 result != -ENOENT,
244 "Failed to load Vulkan driver into sphal namespace. This "
245 "usually means the driver has forbidden library dependencies."
246 "Please fix, this will soon stop working.");
247 result =
248 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
249 reinterpret_cast<const hw_module_t**>(&module));
250 }
Jesse Hall53457db2016-12-14 16:54:06 -0800251 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800252 if (result != 0) {
Jesse Hall53457db2016-12-14 16:54:06 -0800253 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800254 return true;
255 }
256
Yiwei Zhangcb9d4e42019-02-06 20:22:59 -0800257 android::GraphicsEnv::getInstance().sendGpuStats();
258
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800259 hwvulkan_device_t* device;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800260 ATRACE_BEGIN("hwvulkan module open");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800261 result =
262 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
263 reinterpret_cast<hw_device_t**>(&device));
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800264 ATRACE_END();
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800265 if (result != 0) {
266 // Any device with a Vulkan HAL should be able to open the device.
267 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
268 result);
269 return false;
270 }
271
272 hal_.dev_ = device;
273
Chia-I Wu31938252016-05-23 15:31:02 +0800274 hal_.InitDebugReportIndex();
275
276 return true;
277}
278
279bool Hal::InitDebugReportIndex() {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800280 ATRACE_CALL();
281
Chia-I Wu31938252016-05-23 15:31:02 +0800282 uint32_t count;
283 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
284 VK_SUCCESS) {
285 ALOGE("failed to get HAL instance extension count");
286 return false;
287 }
288
289 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
290 malloc(sizeof(VkExtensionProperties) * count));
291 if (!exts) {
292 ALOGE("failed to allocate HAL instance extension array");
293 return false;
294 }
295
296 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
297 VK_SUCCESS) {
298 ALOGE("failed to enumerate HAL instance extensions");
299 free(exts);
300 return false;
301 }
302
303 for (uint32_t i = 0; i < count; i++) {
304 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
305 0) {
306 debug_report_index_ = static_cast<int>(i);
307 break;
308 }
309 }
310
311 free(exts);
312
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800313 return true;
314}
315
316CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800317 const VkAllocationCallbacks& allocator)
318 : is_instance_(true),
319 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800320 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800321 instance_info_(create_info),
322 extension_filter_() {
323 hook_extensions_.set(ProcHook::EXTENSION_CORE);
324 hal_extensions_.set(ProcHook::EXTENSION_CORE);
325}
326
Chia-I Wu4901db72016-03-24 16:38:58 +0800327CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
328 const VkDeviceCreateInfo& create_info,
329 const VkAllocationCallbacks& allocator)
330 : is_instance_(false),
331 allocator_(allocator),
332 physical_dev_(physical_dev),
333 dev_info_(create_info),
334 extension_filter_() {
335 hook_extensions_.set(ProcHook::EXTENSION_CORE);
336 hal_extensions_.set(ProcHook::EXTENSION_CORE);
337}
338
339CreateInfoWrapper::~CreateInfoWrapper() {
340 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
341 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
342}
343
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800344VkResult CreateInfoWrapper::Validate() {
345 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800346 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800347 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800348 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800349 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800350
351 return result;
352}
353
354const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800355CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800356 return hook_extensions_;
357}
358
359const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800360CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800361 return hal_extensions_;
362}
363
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800364CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
365 return &instance_info_;
366}
367
Chia-I Wu4901db72016-03-24 16:38:58 +0800368CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
369 return &dev_info_;
370}
371
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800372VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800373 const struct StructHeader {
374 VkStructureType type;
375 const void* next;
376 } * header;
377
378 if (is_instance_) {
379 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
380
381 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
382 while (header &&
383 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
384 header = reinterpret_cast<const StructHeader*>(header->next);
385
386 instance_info_.pNext = header;
387 } else {
388 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
389
390 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
391 while (header &&
392 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
393 header = reinterpret_cast<const StructHeader*>(header->next);
394
395 dev_info_.pNext = header;
396 }
397
398 return VK_SUCCESS;
399}
400
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800401VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800402 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
403 : dev_info_.ppEnabledLayerNames;
404 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
405 : dev_info_.enabledLayerCount;
406
407 // remove all layers
408 layer_names = nullptr;
409 layer_count = 0;
410
411 return VK_SUCCESS;
412}
413
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800414VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800415 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
416 : dev_info_.ppEnabledExtensionNames;
417 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
418 : dev_info_.enabledExtensionCount;
419 if (!ext_count)
420 return VK_SUCCESS;
421
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800422 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800423 if (result != VK_SUCCESS)
424 return result;
425
426 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800427 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800428
Jesse Halld3d887a2018-03-05 13:34:45 -0800429 // Enable device extensions that contain physical-device commands, so that
430 // vkGetInstanceProcAddr will return those physical-device commands.
431 if (is_instance_) {
432 hook_extensions_.set(ProcHook::KHR_swapchain);
433 }
434
Chia-I Wu4901db72016-03-24 16:38:58 +0800435 ext_names = extension_filter_.names;
436 ext_count = extension_filter_.name_count;
437
438 return VK_SUCCESS;
439}
440
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800441VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800442 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800443 return Hal::Device().EnumerateInstanceExtensionProperties(
444 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800445 } else {
446 const auto& driver = GetData(physical_dev_).driver;
447 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
448 &count, nullptr);
449 }
450}
451
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800452VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800453 uint32_t& count,
454 VkExtensionProperties* props) const {
455 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800456 return Hal::Device().EnumerateInstanceExtensionProperties(
457 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800458 } else {
459 const auto& driver = GetData(physical_dev_).driver;
460 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
461 &count, props);
462 }
463}
464
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800465VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800466 // query extension count
467 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800468 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800469 if (result != VK_SUCCESS || count == 0)
470 return result;
471
472 auto& filter = extension_filter_;
473 filter.exts =
474 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
475 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
476 alignof(VkExtensionProperties),
477 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
478 if (!filter.exts)
479 return VK_ERROR_OUT_OF_HOST_MEMORY;
480
481 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800482 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800483 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
484 return result;
485
486 if (!count)
487 return VK_SUCCESS;
488
489 filter.ext_count = count;
490
491 // allocate name array
492 uint32_t enabled_ext_count = (is_instance_)
493 ? instance_info_.enabledExtensionCount
494 : dev_info_.enabledExtensionCount;
495 count = std::min(filter.ext_count, enabled_ext_count);
496 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
497 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
498 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
499 if (!filter.names)
500 return VK_ERROR_OUT_OF_HOST_MEMORY;
501
502 return VK_SUCCESS;
503}
504
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800505void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800506 auto& filter = extension_filter_;
507
508 ProcHook::Extension ext_bit = GetProcHookExtension(name);
509 if (is_instance_) {
510 switch (ext_bit) {
511 case ProcHook::KHR_android_surface:
512 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700513 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300514 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800515 hook_extensions_.set(ext_bit);
516 // return now as these extensions do not require HAL support
517 return;
518 case ProcHook::EXT_debug_report:
519 // both we and HAL can take part in
520 hook_extensions_.set(ext_bit);
521 break;
Chris Forbes6aa30db2017-02-20 17:12:53 +1300522 case ProcHook::KHR_get_physical_device_properties2:
Jesse Hall7f983a82018-03-29 14:46:45 -0700523 case ProcHook::EXTENSION_UNKNOWN:
524 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800525 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700526
527 case ProcHook::KHR_incremental_present:
528 case ProcHook::KHR_shared_presentable_image:
529 case ProcHook::KHR_swapchain:
530 case ProcHook::EXT_hdr_metadata:
531 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
532 case ProcHook::ANDROID_native_buffer:
533 case ProcHook::GOOGLE_display_timing:
534 case ProcHook::EXTENSION_CORE:
535 case ProcHook::EXTENSION_COUNT:
536 // Device and meta extensions. If we ever get here it's a bug in
537 // our code. But enumerating them lets us avoid having a default
538 // case, and default hides other bugs.
539 ALOGE(
540 "CreateInfoWrapper::FilterExtension: invalid instance "
541 "extension '%s'. FIX ME",
542 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800543 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700544
545 // Don't use a default case. Without it, -Wswitch will tell us
546 // at compile time if someone adds a new ProcHook extension but
547 // doesn't handle it above. That's a real bug that has
548 // not-immediately-obvious effects.
549 //
550 // default:
551 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800552 }
553 } else {
554 switch (ext_bit) {
555 case ProcHook::KHR_swapchain:
556 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
557 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
558 ext_bit = ProcHook::ANDROID_native_buffer;
559 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700560 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700561 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300562 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700563 hook_extensions_.set(ext_bit);
564 // return now as these extensions do not require HAL support
565 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700566 case ProcHook::EXT_hdr_metadata:
567 hook_extensions_.set(ext_bit);
568 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700569 case ProcHook::ANDROID_external_memory_android_hardware_buffer:
Chia-I Wu4901db72016-03-24 16:38:58 +0800570 case ProcHook::EXTENSION_UNKNOWN:
Jesse Hall7f983a82018-03-29 14:46:45 -0700571 // Extensions we don't need to do anything about at this level
Chia-I Wu4901db72016-03-24 16:38:58 +0800572 break;
Jesse Hall7f983a82018-03-29 14:46:45 -0700573
574 case ProcHook::KHR_android_surface:
575 case ProcHook::KHR_get_physical_device_properties2:
576 case ProcHook::KHR_get_surface_capabilities2:
577 case ProcHook::KHR_surface:
578 case ProcHook::EXT_debug_report:
579 case ProcHook::EXT_swapchain_colorspace:
580 case ProcHook::ANDROID_native_buffer:
581 case ProcHook::EXTENSION_CORE:
582 case ProcHook::EXTENSION_COUNT:
583 // Instance and meta extensions. If we ever get here it's a bug
584 // in our code. But enumerating them lets us avoid having a
585 // default case, and default hides other bugs.
586 ALOGE(
587 "CreateInfoWrapper::FilterExtension: invalid device "
588 "extension '%s'. FIX ME",
589 name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800590 return;
Jesse Hall7f983a82018-03-29 14:46:45 -0700591
592 // Don't use a default case. Without it, -Wswitch will tell us
593 // at compile time if someone adds a new ProcHook extension but
594 // doesn't handle it above. That's a real bug that has
595 // not-immediately-obvious effects.
596 //
597 // default:
598 // break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800599 }
600 }
601
602 for (uint32_t i = 0; i < filter.ext_count; i++) {
603 const VkExtensionProperties& props = filter.exts[i];
604 // ignore unknown extensions
605 if (strcmp(name, props.extensionName) != 0)
606 continue;
607
Chia-I Wu4901db72016-03-24 16:38:58 +0800608 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800609 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
610 if (ext_bit == ProcHook::ANDROID_native_buffer)
611 hook_extensions_.set(ProcHook::KHR_swapchain);
612
613 hal_extensions_.set(ext_bit);
614 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800615
616 break;
617 }
618}
619
Ian Elliottf3e872d2017-11-02 10:15:13 -0600620void CreateInfoWrapper::DowngradeApiVersion() {
621 // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
622 if (instance_info_.pApplicationInfo) {
623 application_info_ = *instance_info_.pApplicationInfo;
624 instance_info_.pApplicationInfo = &application_info_;
625 application_info_.apiVersion = VK_API_VERSION_1_0;
626 }
627}
628
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800629VKAPI_ATTR void* DefaultAllocate(void*,
630 size_t size,
631 size_t alignment,
632 VkSystemAllocationScope) {
633 void* ptr = nullptr;
634 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
635 // additionally requires that it be at least sizeof(void*).
636 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
637 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
638 ret, ptr);
639 return ret == 0 ? ptr : nullptr;
640}
641
642VKAPI_ATTR void* DefaultReallocate(void*,
643 void* ptr,
644 size_t size,
645 size_t alignment,
646 VkSystemAllocationScope) {
647 if (size == 0) {
648 free(ptr);
649 return nullptr;
650 }
651
652 // TODO(jessehall): Right now we never shrink allocations; if the new
653 // request is smaller than the existing chunk, we just continue using it.
654 // Right now the loader never reallocs, so this doesn't matter. If that
655 // changes, or if this code is copied into some other project, this should
656 // probably have a heuristic to allocate-copy-free when doing so will save
657 // "enough" space.
658 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
659 if (size <= old_size)
660 return ptr;
661
662 void* new_ptr = nullptr;
663 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
664 return nullptr;
665 if (ptr) {
666 memcpy(new_ptr, ptr, std::min(old_size, size));
667 free(ptr);
668 }
669 return new_ptr;
670}
671
672VKAPI_ATTR void DefaultFree(void*, void* ptr) {
673 ALOGD_CALLSTACK("Free: %p", ptr);
674 free(ptr);
675}
676
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800677InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
678 void* data_mem = allocator.pfnAllocation(
679 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
680 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
681 if (!data_mem)
682 return nullptr;
683
684 return new (data_mem) InstanceData(allocator);
685}
686
687void FreeInstanceData(InstanceData* data,
688 const VkAllocationCallbacks& allocator) {
689 data->~InstanceData();
690 allocator.pfnFree(allocator.pUserData, data);
691}
692
Chia-I Wu950d6e12016-05-03 09:12:35 +0800693DeviceData* AllocateDeviceData(
694 const VkAllocationCallbacks& allocator,
695 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800696 void* data_mem = allocator.pfnAllocation(
697 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
698 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
699 if (!data_mem)
700 return nullptr;
701
Chia-I Wu950d6e12016-05-03 09:12:35 +0800702 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800703}
704
705void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
706 data->~DeviceData();
707 allocator.pfnFree(allocator.pUserData, data);
708}
709
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800710} // anonymous namespace
711
Chia-I Wu9d518162016-03-24 14:55:27 +0800712bool Debuggable() {
713 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
714}
715
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800716bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800717 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800718}
719
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800720const VkAllocationCallbacks& GetDefaultAllocator() {
721 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
722 .pUserData = nullptr,
723 .pfnAllocation = DefaultAllocate,
724 .pfnReallocation = DefaultReallocate,
725 .pfnFree = DefaultFree,
726 };
727
728 return kDefaultAllocCallbacks;
729}
730
Chia-I Wueb7db122016-03-24 09:11:06 +0800731PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
732 const ProcHook* hook = GetProcHook(pName);
733 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800734 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800735
736 if (!instance) {
737 if (hook->type == ProcHook::GLOBAL)
738 return hook->proc;
739
Chia-I Wu109f8982016-04-22 06:40:40 +0800740 // v0 layers expect
741 //
742 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
743 //
744 // to work.
745 if (strcmp(pName, "vkCreateDevice") == 0)
746 return hook->proc;
747
Chia-I Wueb7db122016-03-24 09:11:06 +0800748 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800749 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800750 pName);
751
Chia-I Wu109f8982016-04-22 06:40:40 +0800752 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800753 }
754
755 PFN_vkVoidFunction proc;
756
757 switch (hook->type) {
758 case ProcHook::INSTANCE:
759 proc = (GetData(instance).hook_extensions[hook->extension])
760 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800761 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800762 break;
763 case ProcHook::DEVICE:
764 proc = (hook->extension == ProcHook::EXTENSION_CORE)
765 ? hook->proc
766 : hook->checked_proc;
767 break;
768 default:
769 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800770 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800771 pName);
772 proc = nullptr;
773 break;
774 }
775
776 return proc;
777}
778
779PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
780 const ProcHook* hook = GetProcHook(pName);
781 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800782 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800783
784 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800785 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800786 return nullptr;
787 }
788
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800789 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
790 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800791}
792
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800793VkResult EnumerateInstanceExtensionProperties(
794 const char* pLayerName,
795 uint32_t* pPropertyCount,
796 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600797
798 android::Vector<VkExtensionProperties> loader_extensions;
799 loader_extensions.push_back({
800 VK_KHR_SURFACE_EXTENSION_NAME,
801 VK_KHR_SURFACE_SPEC_VERSION});
802 loader_extensions.push_back({
803 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
804 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
805 loader_extensions.push_back({
806 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
807 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700808 loader_extensions.push_back({
809 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
810 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600811
Chia-I Wu31938252016-05-23 15:31:02 +0800812 static const VkExtensionProperties loader_debug_report_extension = {
813 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
814 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800815
816 // enumerate our extensions first
817 if (!pLayerName && pProperties) {
818 uint32_t count = std::min(
819 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
820
821 std::copy_n(loader_extensions.begin(), count, pProperties);
822
823 if (count < loader_extensions.size()) {
824 *pPropertyCount = count;
825 return VK_INCOMPLETE;
826 }
827
828 pProperties += count;
829 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800830
831 if (Hal::Get().GetDebugReportIndex() < 0) {
832 if (!*pPropertyCount) {
833 *pPropertyCount = count;
834 return VK_INCOMPLETE;
835 }
836
837 pProperties[0] = loader_debug_report_extension;
838 pProperties += 1;
839 *pPropertyCount -= 1;
840 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800841 }
842
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800843 ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800844 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800845 pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800846 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800847
Chia-I Wu31938252016-05-23 15:31:02 +0800848 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
849 int idx = Hal::Get().GetDebugReportIndex();
850 if (idx < 0) {
851 *pPropertyCount += 1;
852 } else if (pProperties &&
853 static_cast<uint32_t>(idx) < *pPropertyCount) {
854 pProperties[idx].specVersion =
855 std::min(pProperties[idx].specVersion,
856 loader_debug_report_extension.specVersion);
857 }
858
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800859 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800860 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800861
862 return result;
863}
864
Chris Forbesfa25e632017-02-22 12:36:02 +1300865bool QueryPresentationProperties(
866 VkPhysicalDevice physicalDevice,
867 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
868{
869 const InstanceData& data = GetData(physicalDevice);
870
871 // GPDP2 must be present and enabled on the instance.
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700872 if (!data.driver.GetPhysicalDeviceProperties2KHR &&
873 !data.driver.GetPhysicalDeviceProperties2)
Chris Forbesfa25e632017-02-22 12:36:02 +1300874 return false;
875
876 // Request the android-specific presentation properties via GPDP2
877 VkPhysicalDeviceProperties2KHR properties = {
878 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
879 presentation_properties,
880 {}
881 };
882
883#pragma clang diagnostic push
884#pragma clang diagnostic ignored "-Wold-style-cast"
885 presentation_properties->sType =
886 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
887#pragma clang diagnostic pop
888 presentation_properties->pNext = nullptr;
889 presentation_properties->sharedImage = VK_FALSE;
890
Yiwei Zhang922b1e32018-03-13 17:12:11 -0700891 if (data.driver.GetPhysicalDeviceProperties2KHR) {
892 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
893 &properties);
894 } else {
895 data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
896 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300897
898 return true;
899}
900
Chia-I Wu01cf3052016-03-24 16:16:21 +0800901VkResult EnumerateDeviceExtensionProperties(
902 VkPhysicalDevice physicalDevice,
903 const char* pLayerName,
904 uint32_t* pPropertyCount,
905 VkExtensionProperties* pProperties) {
906 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300907 // extensions that are unconditionally exposed by the loader
908 android::Vector<VkExtensionProperties> loader_extensions;
909 loader_extensions.push_back({
910 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
911 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300912
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -0800913 bool hdrBoardConfig =
914 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
915 false);
916 if (hdrBoardConfig) {
917 loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
918 VK_EXT_HDR_METADATA_SPEC_VERSION});
919 }
920
Chris Forbes16095002017-05-05 15:33:29 -0700921 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
922 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
923 presentation_properties.sharedImage) {
924 loader_extensions.push_back({
925 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
926 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300927 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700928
Ian Elliott5c34de22017-04-10 14:42:30 -0600929 // conditionally add VK_GOOGLE_display_timing if present timestamps are
930 // supported by the driver:
Wei Wangf9b05ee2017-07-19 20:59:39 -0700931 const std::string timestamp_property("service.sf.present_timestamp");
932 android::base::WaitForPropertyCreation(timestamp_property);
933 if (android::base::GetBoolProperty(timestamp_property, true)) {
Ian Elliott5c34de22017-04-10 14:42:30 -0600934 loader_extensions.push_back({
935 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
936 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
937 }
938
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700939 // enumerate our extensions first
940 if (!pLayerName && pProperties) {
941 uint32_t count = std::min(
942 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
943
944 std::copy_n(loader_extensions.begin(), count, pProperties);
945
946 if (count < loader_extensions.size()) {
947 *pPropertyCount = count;
948 return VK_INCOMPLETE;
949 }
950
951 pProperties += count;
952 *pPropertyCount -= count;
953 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800954
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800955 ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
Chia-I Wu01cf3052016-03-24 16:16:21 +0800956 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
957 physicalDevice, pLayerName, pPropertyCount, pProperties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800958 ATRACE_END();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800959
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700960 if (pProperties) {
961 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
962 for (uint32_t i = 0; i < *pPropertyCount; i++) {
963 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800964
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700965 if (strcmp(prop.extensionName,
966 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
967 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800968
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700969 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
970 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
971 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
972 }
973 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800974
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700975 // restore loader extension count
976 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
977 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800978 }
979
980 return result;
981}
982
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800983VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
984 const VkAllocationCallbacks* pAllocator,
985 VkInstance* pInstance) {
986 const VkAllocationCallbacks& data_allocator =
987 (pAllocator) ? *pAllocator : GetDefaultAllocator();
988
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800989 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800990 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800991 if (result != VK_SUCCESS)
992 return result;
993
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800994 ATRACE_BEGIN("AllocateInstanceData");
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800995 InstanceData* data = AllocateInstanceData(data_allocator);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -0800996 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800997 if (!data)
998 return VK_ERROR_OUT_OF_HOST_MEMORY;
999
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001000 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001001
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001002 ATRACE_BEGIN("autoDowngradeApiVersion");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001003#pragma clang diagnostic push
1004#pragma clang diagnostic ignored "-Wold-style-cast"
1005 uint32_t api_version = ((pCreateInfo->pApplicationInfo)
1006 ? pCreateInfo->pApplicationInfo->apiVersion
1007 : VK_API_VERSION_1_0);
1008 uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
1009 uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
1010 uint32_t icd_api_version;
1011 PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
1012 reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
Yi Kongbcbc73a2018-07-18 10:13:04 -07001013 Hal::Device().GetInstanceProcAddr(nullptr,
Ian Elliottf3e872d2017-11-02 10:15:13 -06001014 "vkEnumerateInstanceVersion"));
1015 if (!pfn_enumerate_instance_version) {
1016 icd_api_version = VK_API_VERSION_1_0;
1017 } else {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001018 ATRACE_BEGIN("pfn_enumerate_instance_version");
Ian Elliottf3e872d2017-11-02 10:15:13 -06001019 result = (*pfn_enumerate_instance_version)(&icd_api_version);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001020 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001021 }
1022 uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
1023 uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
1024
1025 if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
1026 ((api_major_version > 1) || (api_minor_version > 0))) {
1027 api_version = VK_API_VERSION_1_0;
1028 wrapper.DowngradeApiVersion();
1029 }
1030#pragma clang diagnostic pop
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001031 ATRACE_END();
Ian Elliottf3e872d2017-11-02 10:15:13 -06001032
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001033 // call into the driver
1034 VkInstance instance;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001035 ATRACE_BEGIN("driver.CreateInstance");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001036 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001037 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
1038 &instance);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001039 ATRACE_END();
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001040 if (result != VK_SUCCESS) {
1041 FreeInstanceData(data, data_allocator);
1042 return result;
1043 }
1044
1045 // initialize InstanceDriverTable
1046 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001047 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001048 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001049 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001050 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001051 if (data->driver.DestroyInstance)
1052 data->driver.DestroyInstance(instance, pAllocator);
1053
1054 FreeInstanceData(data, data_allocator);
1055
1056 return VK_ERROR_INCOMPATIBLE_DRIVER;
1057 }
1058
1059 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +08001060 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001061 if (!data->get_device_proc_addr) {
1062 data->driver.DestroyInstance(instance, pAllocator);
1063 FreeInstanceData(data, data_allocator);
1064
1065 return VK_ERROR_INCOMPATIBLE_DRIVER;
1066 }
1067
1068 *pInstance = instance;
1069
1070 return VK_SUCCESS;
1071}
1072
1073void DestroyInstance(VkInstance instance,
1074 const VkAllocationCallbacks* pAllocator) {
1075 InstanceData& data = GetData(instance);
1076 data.driver.DestroyInstance(instance, pAllocator);
1077
1078 VkAllocationCallbacks local_allocator;
1079 if (!pAllocator) {
1080 local_allocator = data.allocator;
1081 pAllocator = &local_allocator;
1082 }
1083
1084 FreeInstanceData(&data, *pAllocator);
1085}
1086
Chia-I Wu4901db72016-03-24 16:38:58 +08001087VkResult CreateDevice(VkPhysicalDevice physicalDevice,
1088 const VkDeviceCreateInfo* pCreateInfo,
1089 const VkAllocationCallbacks* pAllocator,
1090 VkDevice* pDevice) {
1091 const InstanceData& instance_data = GetData(physicalDevice);
1092 const VkAllocationCallbacks& data_allocator =
1093 (pAllocator) ? *pAllocator : instance_data.allocator;
1094
1095 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001096 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +08001097 if (result != VK_SUCCESS)
1098 return result;
1099
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001100 ATRACE_BEGIN("AllocateDeviceData");
Chia-I Wu950d6e12016-05-03 09:12:35 +08001101 DeviceData* data = AllocateDeviceData(data_allocator,
1102 instance_data.debug_report_callbacks);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001103 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001104 if (!data)
1105 return VK_ERROR_OUT_OF_HOST_MEMORY;
1106
Chia-I Wu3e6c2d62016-04-11 13:55:56 +08001107 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +08001108
1109 // call into the driver
1110 VkDevice dev;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001111 ATRACE_BEGIN("driver.CreateDevice");
Chia-I Wu4901db72016-03-24 16:38:58 +08001112 result = instance_data.driver.CreateDevice(
1113 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
1114 pAllocator, &dev);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001115 ATRACE_END();
Chia-I Wu4901db72016-03-24 16:38:58 +08001116 if (result != VK_SUCCESS) {
1117 FreeDeviceData(data, data_allocator);
1118 return result;
1119 }
1120
1121 // initialize DeviceDriverTable
1122 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +08001123 !InitDriverTable(dev, instance_data.get_device_proc_addr,
1124 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +08001125 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
1126 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
1127 if (data->driver.DestroyDevice)
1128 data->driver.DestroyDevice(dev, pAllocator);
1129
1130 FreeDeviceData(data, data_allocator);
1131
1132 return VK_ERROR_INCOMPATIBLE_DRIVER;
1133 }
Chris Forbesd8277912017-02-10 14:59:59 +13001134
1135 // sanity check ANDROID_native_buffer implementation, whose set of
1136 // entrypoints varies according to the spec version.
1137 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1138 !data->driver.GetSwapchainGrallocUsageANDROID &&
1139 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1140 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1141 " must expose at least one of "
1142 "vkGetSwapchainGrallocUsageANDROID or "
1143 "vkGetSwapchainGrallocUsage2ANDROID");
1144
1145 data->driver.DestroyDevice(dev, pAllocator);
1146 FreeDeviceData(data, data_allocator);
1147
1148 return VK_ERROR_INCOMPATIBLE_DRIVER;
1149 }
1150
Jesse Hall85bb0c52017-02-09 22:13:02 -08001151 VkPhysicalDeviceProperties properties;
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001152 ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
Jesse Hall85bb0c52017-02-09 22:13:02 -08001153 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1154 &properties);
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001155 ATRACE_END();
Jesse Hall85bb0c52017-02-09 22:13:02 -08001156
Jesse Halldc225072016-05-30 22:40:14 -07001157 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001158 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001159
1160 *pDevice = dev;
1161
1162 return VK_SUCCESS;
1163}
1164
1165void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1166 DeviceData& data = GetData(device);
1167 data.driver.DestroyDevice(device, pAllocator);
1168
1169 VkAllocationCallbacks local_allocator;
1170 if (!pAllocator) {
1171 local_allocator = data.allocator;
1172 pAllocator = &local_allocator;
1173 }
1174
1175 FreeDeviceData(&data, *pAllocator);
1176}
1177
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001178VkResult EnumeratePhysicalDevices(VkInstance instance,
1179 uint32_t* pPhysicalDeviceCount,
1180 VkPhysicalDevice* pPhysicalDevices) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001181 ATRACE_CALL();
1182
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001183 const auto& data = GetData(instance);
1184
1185 VkResult result = data.driver.EnumeratePhysicalDevices(
1186 instance, pPhysicalDeviceCount, pPhysicalDevices);
1187 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1188 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1189 SetData(pPhysicalDevices[i], data);
1190 }
1191
1192 return result;
1193}
1194
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001195VkResult EnumeratePhysicalDeviceGroups(
1196 VkInstance instance,
1197 uint32_t* pPhysicalDeviceGroupCount,
1198 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001199 ATRACE_CALL();
1200
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001201 VkResult result = VK_SUCCESS;
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001202 const auto& data = GetData(instance);
1203
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001204 if (!data.driver.EnumeratePhysicalDeviceGroups) {
1205 uint32_t device_count = 0;
1206 result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1207 if (result < 0)
1208 return result;
Chad Versace32c087f2018-09-09 07:28:05 -07001209
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001210 if (!pPhysicalDeviceGroupProperties) {
1211 *pPhysicalDeviceGroupCount = device_count;
1212 return result;
1213 }
1214
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001215 if (!device_count) {
1216 *pPhysicalDeviceGroupCount = 0;
1217 return result;
1218 }
Chad Versace32c087f2018-09-09 07:28:05 -07001219 device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1220 if (!device_count)
1221 return VK_INCOMPLETE;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001222
1223 android::Vector<VkPhysicalDevice> devices;
1224 devices.resize(device_count);
Chad Versace32c087f2018-09-09 07:28:05 -07001225 *pPhysicalDeviceGroupCount = device_count;
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001226 result = EnumeratePhysicalDevices(instance, &device_count,
1227 devices.editArray());
1228 if (result < 0)
1229 return result;
1230
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001231 for (uint32_t i = 0; i < device_count; ++i) {
1232 pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1233 pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1234 pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1235 }
1236 } else {
1237 result = data.driver.EnumeratePhysicalDeviceGroups(
1238 instance, pPhysicalDeviceGroupCount,
1239 pPhysicalDeviceGroupProperties);
1240 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1241 *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1242 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1243 for (uint32_t j = 0;
1244 j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1245 j++) {
1246 SetData(
1247 pPhysicalDeviceGroupProperties[i].physicalDevices[j],
Ian Elliottcd8ad332017-10-13 09:21:12 -06001248 data);
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001249 }
Ian Elliottcd8ad332017-10-13 09:21:12 -06001250 }
1251 }
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001252 }
1253
1254 return result;
1255}
1256
Chia-I Wuba0be412016-03-24 16:24:40 +08001257void GetDeviceQueue(VkDevice device,
1258 uint32_t queueFamilyIndex,
1259 uint32_t queueIndex,
1260 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001261 ATRACE_CALL();
1262
Chia-I Wuba0be412016-03-24 16:24:40 +08001263 const auto& data = GetData(device);
1264
1265 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1266 SetData(*pQueue, data);
1267}
1268
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001269void GetDeviceQueue2(VkDevice device,
1270 const VkDeviceQueueInfo2* pQueueInfo,
1271 VkQueue* pQueue) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001272 ATRACE_CALL();
1273
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001274 const auto& data = GetData(device);
1275
1276 data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
Yiwei Zhangf5b9f732018-02-07 14:06:09 -08001277 if (*pQueue != VK_NULL_HANDLE) SetData(*pQueue, data);
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001278}
1279
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001280VKAPI_ATTR VkResult
1281AllocateCommandBuffers(VkDevice device,
1282 const VkCommandBufferAllocateInfo* pAllocateInfo,
1283 VkCommandBuffer* pCommandBuffers) {
Yiwei Zhangfdd0c2a2019-01-30 20:16:37 -08001284 ATRACE_CALL();
1285
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001286 const auto& data = GetData(device);
1287
1288 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1289 pCommandBuffers);
1290 if (result == VK_SUCCESS) {
1291 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1292 SetData(pCommandBuffers[i], data);
1293 }
1294
1295 return result;
1296}
1297
Chia-I Wu9d518162016-03-24 14:55:27 +08001298} // namespace driver
1299} // namespace vulkan