blob: 6f425f50c1dea12634a40a27c7e8b5038d85d5e2 [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
Mark Salyzyn7823e122016-09-29 08:08:05 -070017#include <malloc.h>
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080018#include <stdlib.h>
19#include <string.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070020#include <sys/prctl.h>
21
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080022#include <algorithm>
Chia-I Wuff4a6c72016-03-24 16:05:56 +080023#include <array>
Jesse Hall53457db2016-12-14 16:54:06 -080024#include <dlfcn.h>
Chia-I Wu4901db72016-03-24 16:38:58 +080025#include <new>
Mark Salyzyn7823e122016-09-29 08:08:05 -070026
27#include <log/log.h>
Chia-I Wu9d518162016-03-24 14:55:27 +080028
Jesse Hall53457db2016-12-14 16:54:06 -080029#include <android/dlext.h>
30#include <cutils/properties.h>
Mathias Agopian991d2542017-02-06 13:51:32 -080031#include <ui/GraphicsEnv.h>
Chris Forbesfa25e632017-02-22 12:36:02 +130032#include <utils/Vector.h>
Jesse Hall53457db2016-12-14 16:54:06 -080033
Chia-I Wu9d518162016-03-24 14:55:27 +080034#include "driver.h"
Jesse Hallb7c4e3b2016-04-11 13:51:38 -070035#include "stubhal.h"
Chia-I Wu9d518162016-03-24 14:55:27 +080036
Jesse Hall00e61ff2017-04-07 16:48:02 -070037// TODO(b/37049319) Get this from a header once one exists
38extern "C" {
39android_namespace_t* android_get_exported_namespace(const char*);
40}
41
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080042// #define ENABLE_ALLOC_CALLSTACKS 1
43#if ENABLE_ALLOC_CALLSTACKS
44#include <utils/CallStack.h>
45#define ALOGD_CALLSTACK(...) \
46 do { \
47 ALOGD(__VA_ARGS__); \
48 android::CallStack callstack; \
49 callstack.update(); \
50 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
51 } while (false)
52#else
53#define ALOGD_CALLSTACK(...) \
54 do { \
55 } while (false)
56#endif
57
Chia-I Wu9d518162016-03-24 14:55:27 +080058namespace vulkan {
59namespace driver {
60
Chia-I Wu136b8eb2016-03-24 15:01:52 +080061namespace {
62
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080063class Hal {
64 public:
65 static bool Open();
66
67 static const Hal& Get() { return hal_; }
68 static const hwvulkan_device_t& Device() { return *Get().dev_; }
69
Chia-I Wu31938252016-05-23 15:31:02 +080070 int GetDebugReportIndex() const { return debug_report_index_; }
71
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080072 private:
Chia-I Wu31938252016-05-23 15:31:02 +080073 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080074 Hal(const Hal&) = delete;
75 Hal& operator=(const Hal&) = delete;
76
Chia-I Wu31938252016-05-23 15:31:02 +080077 bool InitDebugReportIndex();
78
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080079 static Hal hal_;
80
81 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080082 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080083};
84
Chia-I Wu4901db72016-03-24 16:38:58 +080085class CreateInfoWrapper {
86 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080087 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080088 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080089 CreateInfoWrapper(VkPhysicalDevice physical_dev,
90 const VkDeviceCreateInfo& create_info,
91 const VkAllocationCallbacks& allocator);
92 ~CreateInfoWrapper();
93
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080094 VkResult Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +080095
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080096 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
97 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +080098
Chia-I Wuff4a6c72016-03-24 16:05:56 +080099 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800100 explicit operator const VkDeviceCreateInfo*() const;
101
102 private:
103 struct ExtensionFilter {
104 VkExtensionProperties* exts;
105 uint32_t ext_count;
106
107 const char** names;
108 uint32_t name_count;
109 };
110
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800111 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800112
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800113 VkResult SanitizeLayers();
114 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800115
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800116 VkResult QueryExtensionCount(uint32_t& count) const;
117 VkResult EnumerateExtensions(uint32_t& count,
118 VkExtensionProperties* props) const;
119 VkResult InitExtensionFilter();
120 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800121
122 const bool is_instance_;
123 const VkAllocationCallbacks& allocator_;
124
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800125 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800126
127 union {
128 VkInstanceCreateInfo instance_info_;
129 VkDeviceCreateInfo dev_info_;
130 };
131
132 ExtensionFilter extension_filter_;
133
134 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
135 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
136};
137
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800138Hal Hal::hal_;
139
Jesse Hall53457db2016-12-14 16:54:06 -0800140void* LoadLibrary(const android_dlextinfo& dlextinfo,
141 const char* subname,
142 int subname_len) {
143 const char kLibFormat[] = "vulkan.%*s.so";
144 char* name = static_cast<char*>(
145 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
146 sprintf(name, kLibFormat, subname_len, subname);
147 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
148}
149
150const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
151 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
152 "ro.board.platform",
153}};
154
Jesse Hall00e61ff2017-04-07 16:48:02 -0700155int LoadDriver(android_namespace_t* library_namespace,
156 const hwvulkan_module_t** module) {
Jesse Hall53457db2016-12-14 16:54:06 -0800157 const android_dlextinfo dlextinfo = {
158 .flags = ANDROID_DLEXT_USE_NAMESPACE,
Jesse Hall00e61ff2017-04-07 16:48:02 -0700159 .library_namespace = library_namespace,
Jesse Hall53457db2016-12-14 16:54:06 -0800160 };
Jesse Hall53457db2016-12-14 16:54:06 -0800161 void* so = nullptr;
162 char prop[PROPERTY_VALUE_MAX];
163 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
164 int prop_len = property_get(key, prop, nullptr);
165 if (prop_len > 0) {
166 so = LoadLibrary(dlextinfo, prop, prop_len);
167 if (so)
168 break;
169 }
170 }
171 if (!so)
172 return -ENOENT;
173
Jesse Hall00e61ff2017-04-07 16:48:02 -0700174 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800175 if (!hmi) {
176 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
177 dlclose(so);
178 return -EINVAL;
179 }
180 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
181 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
182 dlclose(so);
183 return -EINVAL;
184 }
185 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700186 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800187 return 0;
188}
189
Jesse Hall00e61ff2017-04-07 16:48:02 -0700190int LoadBuiltinDriver(const hwvulkan_module_t** module) {
191 auto ns = android_get_exported_namespace("sphal");
192 if (!ns)
193 return -ENOENT;
194 return LoadDriver(ns, module);
195}
196
197int LoadUpdatedDriver(const hwvulkan_module_t** module) {
198 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
199 if (!ns)
200 return -ENOENT;
201 return LoadDriver(ns, module);
202}
203
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800204bool Hal::Open() {
Jesse Halldc225072016-05-30 22:40:14 -0700205 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800206
207 // Use a stub device unless we successfully open a real HAL device.
208 hal_.dev_ = &stubhal::kDevice;
209
Jesse Hall53457db2016-12-14 16:54:06 -0800210 int result;
211 const hwvulkan_module_t* module = nullptr;
212
Jesse Hall00e61ff2017-04-07 16:48:02 -0700213 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800214 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700215 result = LoadBuiltinDriver(&module);
216 if (result != 0) {
217 // -ENOENT means the sphal namespace doesn't exist, not that there
218 // is a problem with the driver.
219 ALOGW_IF(
220 result != -ENOENT,
221 "Failed to load Vulkan driver into sphal namespace. This "
222 "usually means the driver has forbidden library dependencies."
223 "Please fix, this will soon stop working.");
224 result =
225 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
226 reinterpret_cast<const hw_module_t**>(&module));
227 }
Jesse Hall53457db2016-12-14 16:54:06 -0800228 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800229 if (result != 0) {
Jesse Hall53457db2016-12-14 16:54:06 -0800230 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800231 return true;
232 }
233
234 hwvulkan_device_t* device;
235 result =
236 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
237 reinterpret_cast<hw_device_t**>(&device));
238 if (result != 0) {
239 // Any device with a Vulkan HAL should be able to open the device.
240 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
241 result);
242 return false;
243 }
244
245 hal_.dev_ = device;
246
Chia-I Wu31938252016-05-23 15:31:02 +0800247 hal_.InitDebugReportIndex();
248
249 return true;
250}
251
252bool Hal::InitDebugReportIndex() {
253 uint32_t count;
254 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
255 VK_SUCCESS) {
256 ALOGE("failed to get HAL instance extension count");
257 return false;
258 }
259
260 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
261 malloc(sizeof(VkExtensionProperties) * count));
262 if (!exts) {
263 ALOGE("failed to allocate HAL instance extension array");
264 return false;
265 }
266
267 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
268 VK_SUCCESS) {
269 ALOGE("failed to enumerate HAL instance extensions");
270 free(exts);
271 return false;
272 }
273
274 for (uint32_t i = 0; i < count; i++) {
275 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
276 0) {
277 debug_report_index_ = static_cast<int>(i);
278 break;
279 }
280 }
281
282 free(exts);
283
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800284 return true;
285}
286
287CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800288 const VkAllocationCallbacks& allocator)
289 : is_instance_(true),
290 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800291 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800292 instance_info_(create_info),
293 extension_filter_() {
294 hook_extensions_.set(ProcHook::EXTENSION_CORE);
295 hal_extensions_.set(ProcHook::EXTENSION_CORE);
296}
297
Chia-I Wu4901db72016-03-24 16:38:58 +0800298CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
299 const VkDeviceCreateInfo& create_info,
300 const VkAllocationCallbacks& allocator)
301 : is_instance_(false),
302 allocator_(allocator),
303 physical_dev_(physical_dev),
304 dev_info_(create_info),
305 extension_filter_() {
306 hook_extensions_.set(ProcHook::EXTENSION_CORE);
307 hal_extensions_.set(ProcHook::EXTENSION_CORE);
308}
309
310CreateInfoWrapper::~CreateInfoWrapper() {
311 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
312 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
313}
314
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800315VkResult CreateInfoWrapper::Validate() {
316 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800317 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800318 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800319 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800320 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800321
322 return result;
323}
324
325const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800326CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800327 return hook_extensions_;
328}
329
330const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800331CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800332 return hal_extensions_;
333}
334
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800335CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
336 return &instance_info_;
337}
338
Chia-I Wu4901db72016-03-24 16:38:58 +0800339CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
340 return &dev_info_;
341}
342
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800343VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800344 const struct StructHeader {
345 VkStructureType type;
346 const void* next;
347 } * header;
348
349 if (is_instance_) {
350 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
351
352 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
353 while (header &&
354 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
355 header = reinterpret_cast<const StructHeader*>(header->next);
356
357 instance_info_.pNext = header;
358 } else {
359 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
360
361 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
362 while (header &&
363 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
364 header = reinterpret_cast<const StructHeader*>(header->next);
365
366 dev_info_.pNext = header;
367 }
368
369 return VK_SUCCESS;
370}
371
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800372VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800373 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
374 : dev_info_.ppEnabledLayerNames;
375 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
376 : dev_info_.enabledLayerCount;
377
378 // remove all layers
379 layer_names = nullptr;
380 layer_count = 0;
381
382 return VK_SUCCESS;
383}
384
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800385VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800386 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
387 : dev_info_.ppEnabledExtensionNames;
388 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
389 : dev_info_.enabledExtensionCount;
390 if (!ext_count)
391 return VK_SUCCESS;
392
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800393 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800394 if (result != VK_SUCCESS)
395 return result;
396
397 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800398 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800399
400 ext_names = extension_filter_.names;
401 ext_count = extension_filter_.name_count;
402
403 return VK_SUCCESS;
404}
405
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800406VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800407 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800408 return Hal::Device().EnumerateInstanceExtensionProperties(
409 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800410 } else {
411 const auto& driver = GetData(physical_dev_).driver;
412 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
413 &count, nullptr);
414 }
415}
416
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800417VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800418 uint32_t& count,
419 VkExtensionProperties* props) const {
420 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800421 return Hal::Device().EnumerateInstanceExtensionProperties(
422 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800423 } else {
424 const auto& driver = GetData(physical_dev_).driver;
425 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
426 &count, props);
427 }
428}
429
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800430VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800431 // query extension count
432 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800433 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800434 if (result != VK_SUCCESS || count == 0)
435 return result;
436
437 auto& filter = extension_filter_;
438 filter.exts =
439 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
440 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
441 alignof(VkExtensionProperties),
442 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
443 if (!filter.exts)
444 return VK_ERROR_OUT_OF_HOST_MEMORY;
445
446 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800447 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800448 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
449 return result;
450
451 if (!count)
452 return VK_SUCCESS;
453
454 filter.ext_count = count;
455
456 // allocate name array
457 uint32_t enabled_ext_count = (is_instance_)
458 ? instance_info_.enabledExtensionCount
459 : dev_info_.enabledExtensionCount;
460 count = std::min(filter.ext_count, enabled_ext_count);
461 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
462 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
463 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
464 if (!filter.names)
465 return VK_ERROR_OUT_OF_HOST_MEMORY;
466
467 return VK_SUCCESS;
468}
469
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800470void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800471 auto& filter = extension_filter_;
472
473 ProcHook::Extension ext_bit = GetProcHookExtension(name);
474 if (is_instance_) {
475 switch (ext_bit) {
476 case ProcHook::KHR_android_surface:
477 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700478 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300479 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800480 hook_extensions_.set(ext_bit);
481 // return now as these extensions do not require HAL support
482 return;
483 case ProcHook::EXT_debug_report:
484 // both we and HAL can take part in
485 hook_extensions_.set(ext_bit);
486 break;
487 case ProcHook::EXTENSION_UNKNOWN:
Chris Forbes6aa30db2017-02-20 17:12:53 +1300488 case ProcHook::KHR_get_physical_device_properties2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800489 // HAL's extensions
490 break;
491 default:
492 ALOGW("Ignored invalid instance extension %s", name);
493 return;
494 }
495 } else {
496 switch (ext_bit) {
497 case ProcHook::KHR_swapchain:
498 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
499 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
500 ext_bit = ProcHook::ANDROID_native_buffer;
501 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700502 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700503 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300504 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700505 hook_extensions_.set(ext_bit);
506 // return now as these extensions do not require HAL support
507 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700508 case ProcHook::EXT_hdr_metadata:
509 hook_extensions_.set(ext_bit);
510 break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800511 case ProcHook::EXTENSION_UNKNOWN:
512 // HAL's extensions
513 break;
514 default:
515 ALOGW("Ignored invalid device extension %s", name);
516 return;
517 }
518 }
519
520 for (uint32_t i = 0; i < filter.ext_count; i++) {
521 const VkExtensionProperties& props = filter.exts[i];
522 // ignore unknown extensions
523 if (strcmp(name, props.extensionName) != 0)
524 continue;
525
Chia-I Wu4901db72016-03-24 16:38:58 +0800526 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800527 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
528 if (ext_bit == ProcHook::ANDROID_native_buffer)
529 hook_extensions_.set(ProcHook::KHR_swapchain);
530
531 hal_extensions_.set(ext_bit);
532 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800533
534 break;
535 }
536}
537
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800538VKAPI_ATTR void* DefaultAllocate(void*,
539 size_t size,
540 size_t alignment,
541 VkSystemAllocationScope) {
542 void* ptr = nullptr;
543 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
544 // additionally requires that it be at least sizeof(void*).
545 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
546 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
547 ret, ptr);
548 return ret == 0 ? ptr : nullptr;
549}
550
551VKAPI_ATTR void* DefaultReallocate(void*,
552 void* ptr,
553 size_t size,
554 size_t alignment,
555 VkSystemAllocationScope) {
556 if (size == 0) {
557 free(ptr);
558 return nullptr;
559 }
560
561 // TODO(jessehall): Right now we never shrink allocations; if the new
562 // request is smaller than the existing chunk, we just continue using it.
563 // Right now the loader never reallocs, so this doesn't matter. If that
564 // changes, or if this code is copied into some other project, this should
565 // probably have a heuristic to allocate-copy-free when doing so will save
566 // "enough" space.
567 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
568 if (size <= old_size)
569 return ptr;
570
571 void* new_ptr = nullptr;
572 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
573 return nullptr;
574 if (ptr) {
575 memcpy(new_ptr, ptr, std::min(old_size, size));
576 free(ptr);
577 }
578 return new_ptr;
579}
580
581VKAPI_ATTR void DefaultFree(void*, void* ptr) {
582 ALOGD_CALLSTACK("Free: %p", ptr);
583 free(ptr);
584}
585
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800586InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
587 void* data_mem = allocator.pfnAllocation(
588 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
589 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
590 if (!data_mem)
591 return nullptr;
592
593 return new (data_mem) InstanceData(allocator);
594}
595
596void FreeInstanceData(InstanceData* data,
597 const VkAllocationCallbacks& allocator) {
598 data->~InstanceData();
599 allocator.pfnFree(allocator.pUserData, data);
600}
601
Chia-I Wu950d6e12016-05-03 09:12:35 +0800602DeviceData* AllocateDeviceData(
603 const VkAllocationCallbacks& allocator,
604 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800605 void* data_mem = allocator.pfnAllocation(
606 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
607 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
608 if (!data_mem)
609 return nullptr;
610
Chia-I Wu950d6e12016-05-03 09:12:35 +0800611 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800612}
613
614void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
615 data->~DeviceData();
616 allocator.pfnFree(allocator.pUserData, data);
617}
618
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800619} // anonymous namespace
620
Chia-I Wu9d518162016-03-24 14:55:27 +0800621bool Debuggable() {
622 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
623}
624
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800625bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800626 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800627}
628
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800629const VkAllocationCallbacks& GetDefaultAllocator() {
630 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
631 .pUserData = nullptr,
632 .pfnAllocation = DefaultAllocate,
633 .pfnReallocation = DefaultReallocate,
634 .pfnFree = DefaultFree,
635 };
636
637 return kDefaultAllocCallbacks;
638}
639
Chia-I Wueb7db122016-03-24 09:11:06 +0800640PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
641 const ProcHook* hook = GetProcHook(pName);
642 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800643 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800644
645 if (!instance) {
646 if (hook->type == ProcHook::GLOBAL)
647 return hook->proc;
648
Chia-I Wu109f8982016-04-22 06:40:40 +0800649 // v0 layers expect
650 //
651 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
652 //
653 // to work.
654 if (strcmp(pName, "vkCreateDevice") == 0)
655 return hook->proc;
656
Chia-I Wueb7db122016-03-24 09:11:06 +0800657 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800658 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800659 pName);
660
Chia-I Wu109f8982016-04-22 06:40:40 +0800661 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800662 }
663
664 PFN_vkVoidFunction proc;
665
666 switch (hook->type) {
667 case ProcHook::INSTANCE:
668 proc = (GetData(instance).hook_extensions[hook->extension])
669 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800670 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800671 break;
672 case ProcHook::DEVICE:
673 proc = (hook->extension == ProcHook::EXTENSION_CORE)
674 ? hook->proc
675 : hook->checked_proc;
676 break;
677 default:
678 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800679 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800680 pName);
681 proc = nullptr;
682 break;
683 }
684
685 return proc;
686}
687
688PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
689 const ProcHook* hook = GetProcHook(pName);
690 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800691 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800692
693 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800694 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800695 return nullptr;
696 }
697
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800698 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
699 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800700}
701
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800702VkResult EnumerateInstanceExtensionProperties(
703 const char* pLayerName,
704 uint32_t* pPropertyCount,
705 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600706
707 android::Vector<VkExtensionProperties> loader_extensions;
708 loader_extensions.push_back({
709 VK_KHR_SURFACE_EXTENSION_NAME,
710 VK_KHR_SURFACE_SPEC_VERSION});
711 loader_extensions.push_back({
712 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
713 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
714 loader_extensions.push_back({
715 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
716 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700717 loader_extensions.push_back({
718 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
719 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600720
Chia-I Wu31938252016-05-23 15:31:02 +0800721 static const VkExtensionProperties loader_debug_report_extension = {
722 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
723 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800724
725 // enumerate our extensions first
726 if (!pLayerName && pProperties) {
727 uint32_t count = std::min(
728 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
729
730 std::copy_n(loader_extensions.begin(), count, pProperties);
731
732 if (count < loader_extensions.size()) {
733 *pPropertyCount = count;
734 return VK_INCOMPLETE;
735 }
736
737 pProperties += count;
738 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800739
740 if (Hal::Get().GetDebugReportIndex() < 0) {
741 if (!*pPropertyCount) {
742 *pPropertyCount = count;
743 return VK_INCOMPLETE;
744 }
745
746 pProperties[0] = loader_debug_report_extension;
747 pProperties += 1;
748 *pPropertyCount -= 1;
749 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800750 }
751
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800752 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800753 pLayerName, pPropertyCount, pProperties);
754
Chia-I Wu31938252016-05-23 15:31:02 +0800755 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
756 int idx = Hal::Get().GetDebugReportIndex();
757 if (idx < 0) {
758 *pPropertyCount += 1;
759 } else if (pProperties &&
760 static_cast<uint32_t>(idx) < *pPropertyCount) {
761 pProperties[idx].specVersion =
762 std::min(pProperties[idx].specVersion,
763 loader_debug_report_extension.specVersion);
764 }
765
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800766 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800767 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800768
769 return result;
770}
771
Chris Forbesfa25e632017-02-22 12:36:02 +1300772bool QueryPresentationProperties(
773 VkPhysicalDevice physicalDevice,
774 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
775{
776 const InstanceData& data = GetData(physicalDevice);
777
778 // GPDP2 must be present and enabled on the instance.
779 if (!data.driver.GetPhysicalDeviceProperties2KHR)
780 return false;
781
782 // Request the android-specific presentation properties via GPDP2
783 VkPhysicalDeviceProperties2KHR properties = {
784 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
785 presentation_properties,
786 {}
787 };
788
789#pragma clang diagnostic push
790#pragma clang diagnostic ignored "-Wold-style-cast"
791 presentation_properties->sType =
792 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
793#pragma clang diagnostic pop
794 presentation_properties->pNext = nullptr;
795 presentation_properties->sharedImage = VK_FALSE;
796
797 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
798 &properties);
799
800 return true;
801}
802
Chia-I Wu01cf3052016-03-24 16:16:21 +0800803VkResult EnumerateDeviceExtensionProperties(
804 VkPhysicalDevice physicalDevice,
805 const char* pLayerName,
806 uint32_t* pPropertyCount,
807 VkExtensionProperties* pProperties) {
808 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300809 // extensions that are unconditionally exposed by the loader
810 android::Vector<VkExtensionProperties> loader_extensions;
811 loader_extensions.push_back({
812 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
813 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300814
Chris Forbes16095002017-05-05 15:33:29 -0700815 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
816 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
817 presentation_properties.sharedImage) {
818 loader_extensions.push_back({
819 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
820 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300821 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700822
Ian Elliott5c34de22017-04-10 14:42:30 -0600823 // conditionally add VK_GOOGLE_display_timing if present timestamps are
824 // supported by the driver:
825 char timestamp_property[PROPERTY_VALUE_MAX];
826 property_get("service.sf.present_timestamp", timestamp_property, "1");
827 if (strcmp(timestamp_property, "1") == 0) {
828 loader_extensions.push_back({
829 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
830 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
831 }
832
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700833 // enumerate our extensions first
834 if (!pLayerName && pProperties) {
835 uint32_t count = std::min(
836 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
837
838 std::copy_n(loader_extensions.begin(), count, pProperties);
839
840 if (count < loader_extensions.size()) {
841 *pPropertyCount = count;
842 return VK_INCOMPLETE;
843 }
844
845 pProperties += count;
846 *pPropertyCount -= count;
847 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800848
849 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
850 physicalDevice, pLayerName, pPropertyCount, pProperties);
Chia-I Wu01cf3052016-03-24 16:16:21 +0800851
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700852 if (pProperties) {
853 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
854 for (uint32_t i = 0; i < *pPropertyCount; i++) {
855 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800856
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700857 if (strcmp(prop.extensionName,
858 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
859 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800860
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700861 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
862 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
863 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
864 }
865 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800866
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700867 // restore loader extension count
868 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
869 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800870 }
871
872 return result;
873}
874
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800875VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
876 const VkAllocationCallbacks* pAllocator,
877 VkInstance* pInstance) {
878 const VkAllocationCallbacks& data_allocator =
879 (pAllocator) ? *pAllocator : GetDefaultAllocator();
880
Ian Elliottb36f4ee2017-05-08 15:59:09 -0600881 if (pCreateInfo->pApplicationInfo &&
882 pCreateInfo->pApplicationInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
883#pragma clang diagnostic push
884#pragma clang diagnostic ignored "-Wold-style-cast"
885 ALOGI(
886 "Requested Vulkan instance version %d.%d is greater than max "
887 "supported version (1.0)",
888 VK_VERSION_MAJOR(pCreateInfo->pApplicationInfo->apiVersion),
889 VK_VERSION_MINOR(pCreateInfo->pApplicationInfo->apiVersion));
890#pragma clang diagnostic pop
891 return VK_ERROR_INCOMPATIBLE_DRIVER;
892 }
893
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800894 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800895 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800896 if (result != VK_SUCCESS)
897 return result;
898
899 InstanceData* data = AllocateInstanceData(data_allocator);
900 if (!data)
901 return VK_ERROR_OUT_OF_HOST_MEMORY;
902
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800903 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800904
905 // call into the driver
906 VkInstance instance;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800907 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800908 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
909 &instance);
910 if (result != VK_SUCCESS) {
911 FreeInstanceData(data, data_allocator);
912 return result;
913 }
914
915 // initialize InstanceDriverTable
916 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800917 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800918 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800919 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800920 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800921 if (data->driver.DestroyInstance)
922 data->driver.DestroyInstance(instance, pAllocator);
923
924 FreeInstanceData(data, data_allocator);
925
926 return VK_ERROR_INCOMPATIBLE_DRIVER;
927 }
928
929 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800930 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800931 if (!data->get_device_proc_addr) {
932 data->driver.DestroyInstance(instance, pAllocator);
933 FreeInstanceData(data, data_allocator);
934
935 return VK_ERROR_INCOMPATIBLE_DRIVER;
936 }
937
938 *pInstance = instance;
939
940 return VK_SUCCESS;
941}
942
943void DestroyInstance(VkInstance instance,
944 const VkAllocationCallbacks* pAllocator) {
945 InstanceData& data = GetData(instance);
946 data.driver.DestroyInstance(instance, pAllocator);
947
948 VkAllocationCallbacks local_allocator;
949 if (!pAllocator) {
950 local_allocator = data.allocator;
951 pAllocator = &local_allocator;
952 }
953
954 FreeInstanceData(&data, *pAllocator);
955}
956
Chia-I Wu4901db72016-03-24 16:38:58 +0800957VkResult CreateDevice(VkPhysicalDevice physicalDevice,
958 const VkDeviceCreateInfo* pCreateInfo,
959 const VkAllocationCallbacks* pAllocator,
960 VkDevice* pDevice) {
961 const InstanceData& instance_data = GetData(physicalDevice);
962 const VkAllocationCallbacks& data_allocator =
963 (pAllocator) ? *pAllocator : instance_data.allocator;
964
965 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800966 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800967 if (result != VK_SUCCESS)
968 return result;
969
Chia-I Wu950d6e12016-05-03 09:12:35 +0800970 DeviceData* data = AllocateDeviceData(data_allocator,
971 instance_data.debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800972 if (!data)
973 return VK_ERROR_OUT_OF_HOST_MEMORY;
974
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800975 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800976
977 // call into the driver
978 VkDevice dev;
979 result = instance_data.driver.CreateDevice(
980 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
981 pAllocator, &dev);
982 if (result != VK_SUCCESS) {
983 FreeDeviceData(data, data_allocator);
984 return result;
985 }
986
987 // initialize DeviceDriverTable
988 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800989 !InitDriverTable(dev, instance_data.get_device_proc_addr,
990 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800991 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
992 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
993 if (data->driver.DestroyDevice)
994 data->driver.DestroyDevice(dev, pAllocator);
995
996 FreeDeviceData(data, data_allocator);
997
998 return VK_ERROR_INCOMPATIBLE_DRIVER;
999 }
Chris Forbesd8277912017-02-10 14:59:59 +13001000
1001 // sanity check ANDROID_native_buffer implementation, whose set of
1002 // entrypoints varies according to the spec version.
1003 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1004 !data->driver.GetSwapchainGrallocUsageANDROID &&
1005 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1006 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1007 " must expose at least one of "
1008 "vkGetSwapchainGrallocUsageANDROID or "
1009 "vkGetSwapchainGrallocUsage2ANDROID");
1010
1011 data->driver.DestroyDevice(dev, pAllocator);
1012 FreeDeviceData(data, data_allocator);
1013
1014 return VK_ERROR_INCOMPATIBLE_DRIVER;
1015 }
1016
Jesse Hall85bb0c52017-02-09 22:13:02 -08001017 VkPhysicalDeviceProperties properties;
1018 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1019 &properties);
1020
Jesse Halldc225072016-05-30 22:40:14 -07001021 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001022 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001023
1024 *pDevice = dev;
1025
1026 return VK_SUCCESS;
1027}
1028
1029void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1030 DeviceData& data = GetData(device);
1031 data.driver.DestroyDevice(device, pAllocator);
1032
1033 VkAllocationCallbacks local_allocator;
1034 if (!pAllocator) {
1035 local_allocator = data.allocator;
1036 pAllocator = &local_allocator;
1037 }
1038
1039 FreeDeviceData(&data, *pAllocator);
1040}
1041
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001042VkResult EnumeratePhysicalDevices(VkInstance instance,
1043 uint32_t* pPhysicalDeviceCount,
1044 VkPhysicalDevice* pPhysicalDevices) {
1045 const auto& data = GetData(instance);
1046
1047 VkResult result = data.driver.EnumeratePhysicalDevices(
1048 instance, pPhysicalDeviceCount, pPhysicalDevices);
1049 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1050 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1051 SetData(pPhysicalDevices[i], data);
1052 }
1053
1054 return result;
1055}
1056
Chia-I Wuba0be412016-03-24 16:24:40 +08001057void GetDeviceQueue(VkDevice device,
1058 uint32_t queueFamilyIndex,
1059 uint32_t queueIndex,
1060 VkQueue* pQueue) {
1061 const auto& data = GetData(device);
1062
1063 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1064 SetData(*pQueue, data);
1065}
1066
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001067VKAPI_ATTR VkResult
1068AllocateCommandBuffers(VkDevice device,
1069 const VkCommandBufferAllocateInfo* pAllocateInfo,
1070 VkCommandBuffer* pCommandBuffers) {
1071 const auto& data = GetData(device);
1072
1073 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1074 pCommandBuffers);
1075 if (result == VK_SUCCESS) {
1076 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1077 SetData(pCommandBuffers[i], data);
1078 }
1079
1080 return result;
1081}
1082
Chia-I Wu9d518162016-03-24 14:55:27 +08001083} // namespace driver
1084} // namespace vulkan