blob: f2cd8e6bc3d75a5b3ee8d3614d9cf0ecd32f38bb [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
Ian Elliott34a327b2017-03-28 13:20:35 -060042// Set to true to enable exposing unratified extensions for development
43static const bool kEnableUnratifiedExtensions = false;
44
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080045// #define ENABLE_ALLOC_CALLSTACKS 1
46#if ENABLE_ALLOC_CALLSTACKS
47#include <utils/CallStack.h>
48#define ALOGD_CALLSTACK(...) \
49 do { \
50 ALOGD(__VA_ARGS__); \
51 android::CallStack callstack; \
52 callstack.update(); \
53 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
54 } while (false)
55#else
56#define ALOGD_CALLSTACK(...) \
57 do { \
58 } while (false)
59#endif
60
Chia-I Wu9d518162016-03-24 14:55:27 +080061namespace vulkan {
62namespace driver {
63
Chia-I Wu136b8eb2016-03-24 15:01:52 +080064namespace {
65
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080066class Hal {
67 public:
68 static bool Open();
69
70 static const Hal& Get() { return hal_; }
71 static const hwvulkan_device_t& Device() { return *Get().dev_; }
72
Chia-I Wu31938252016-05-23 15:31:02 +080073 int GetDebugReportIndex() const { return debug_report_index_; }
74
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080075 private:
Chia-I Wu31938252016-05-23 15:31:02 +080076 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080077 Hal(const Hal&) = delete;
78 Hal& operator=(const Hal&) = delete;
79
Chia-I Wu31938252016-05-23 15:31:02 +080080 bool InitDebugReportIndex();
81
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080082 static Hal hal_;
83
84 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080085 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080086};
87
Chia-I Wu4901db72016-03-24 16:38:58 +080088class CreateInfoWrapper {
89 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080090 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080091 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080092 CreateInfoWrapper(VkPhysicalDevice physical_dev,
93 const VkDeviceCreateInfo& create_info,
94 const VkAllocationCallbacks& allocator);
95 ~CreateInfoWrapper();
96
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080097 VkResult Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +080098
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080099 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
100 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800101
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800102 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800103 explicit operator const VkDeviceCreateInfo*() const;
104
105 private:
106 struct ExtensionFilter {
107 VkExtensionProperties* exts;
108 uint32_t ext_count;
109
110 const char** names;
111 uint32_t name_count;
112 };
113
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800114 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800115
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800116 VkResult SanitizeLayers();
117 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800118
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800119 VkResult QueryExtensionCount(uint32_t& count) const;
120 VkResult EnumerateExtensions(uint32_t& count,
121 VkExtensionProperties* props) const;
122 VkResult InitExtensionFilter();
123 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800124
125 const bool is_instance_;
126 const VkAllocationCallbacks& allocator_;
127
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800128 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800129
130 union {
131 VkInstanceCreateInfo instance_info_;
132 VkDeviceCreateInfo dev_info_;
133 };
134
135 ExtensionFilter extension_filter_;
136
137 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
138 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
139};
140
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800141Hal Hal::hal_;
142
Jesse Hall53457db2016-12-14 16:54:06 -0800143void* LoadLibrary(const android_dlextinfo& dlextinfo,
144 const char* subname,
145 int subname_len) {
146 const char kLibFormat[] = "vulkan.%*s.so";
147 char* name = static_cast<char*>(
148 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
149 sprintf(name, kLibFormat, subname_len, subname);
150 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
151}
152
153const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
154 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
155 "ro.board.platform",
156}};
157
Jesse Hall00e61ff2017-04-07 16:48:02 -0700158int LoadDriver(android_namespace_t* library_namespace,
159 const hwvulkan_module_t** module) {
Jesse Hall53457db2016-12-14 16:54:06 -0800160 const android_dlextinfo dlextinfo = {
161 .flags = ANDROID_DLEXT_USE_NAMESPACE,
Jesse Hall00e61ff2017-04-07 16:48:02 -0700162 .library_namespace = library_namespace,
Jesse Hall53457db2016-12-14 16:54:06 -0800163 };
Jesse Hall53457db2016-12-14 16:54:06 -0800164 void* so = nullptr;
165 char prop[PROPERTY_VALUE_MAX];
166 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
167 int prop_len = property_get(key, prop, nullptr);
168 if (prop_len > 0) {
169 so = LoadLibrary(dlextinfo, prop, prop_len);
170 if (so)
171 break;
172 }
173 }
174 if (!so)
175 return -ENOENT;
176
Jesse Hall00e61ff2017-04-07 16:48:02 -0700177 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800178 if (!hmi) {
179 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
180 dlclose(so);
181 return -EINVAL;
182 }
183 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
184 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
185 dlclose(so);
186 return -EINVAL;
187 }
188 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700189 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800190 return 0;
191}
192
Jesse Hall00e61ff2017-04-07 16:48:02 -0700193int LoadBuiltinDriver(const hwvulkan_module_t** module) {
194 auto ns = android_get_exported_namespace("sphal");
195 if (!ns)
196 return -ENOENT;
197 return LoadDriver(ns, module);
198}
199
200int LoadUpdatedDriver(const hwvulkan_module_t** module) {
201 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
202 if (!ns)
203 return -ENOENT;
204 return LoadDriver(ns, module);
205}
206
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800207bool Hal::Open() {
Jesse Halldc225072016-05-30 22:40:14 -0700208 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800209
210 // Use a stub device unless we successfully open a real HAL device.
211 hal_.dev_ = &stubhal::kDevice;
212
Jesse Hall53457db2016-12-14 16:54:06 -0800213 int result;
214 const hwvulkan_module_t* module = nullptr;
215
Jesse Hall00e61ff2017-04-07 16:48:02 -0700216 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800217 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700218 result = LoadBuiltinDriver(&module);
219 if (result != 0) {
220 // -ENOENT means the sphal namespace doesn't exist, not that there
221 // is a problem with the driver.
222 ALOGW_IF(
223 result != -ENOENT,
224 "Failed to load Vulkan driver into sphal namespace. This "
225 "usually means the driver has forbidden library dependencies."
226 "Please fix, this will soon stop working.");
227 result =
228 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
229 reinterpret_cast<const hw_module_t**>(&module));
230 }
Jesse Hall53457db2016-12-14 16:54:06 -0800231 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800232 if (result != 0) {
Jesse Hall53457db2016-12-14 16:54:06 -0800233 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800234 return true;
235 }
236
237 hwvulkan_device_t* device;
238 result =
239 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
240 reinterpret_cast<hw_device_t**>(&device));
241 if (result != 0) {
242 // Any device with a Vulkan HAL should be able to open the device.
243 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
244 result);
245 return false;
246 }
247
248 hal_.dev_ = device;
249
Chia-I Wu31938252016-05-23 15:31:02 +0800250 hal_.InitDebugReportIndex();
251
252 return true;
253}
254
255bool Hal::InitDebugReportIndex() {
256 uint32_t count;
257 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
258 VK_SUCCESS) {
259 ALOGE("failed to get HAL instance extension count");
260 return false;
261 }
262
263 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
264 malloc(sizeof(VkExtensionProperties) * count));
265 if (!exts) {
266 ALOGE("failed to allocate HAL instance extension array");
267 return false;
268 }
269
270 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
271 VK_SUCCESS) {
272 ALOGE("failed to enumerate HAL instance extensions");
273 free(exts);
274 return false;
275 }
276
277 for (uint32_t i = 0; i < count; i++) {
278 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
279 0) {
280 debug_report_index_ = static_cast<int>(i);
281 break;
282 }
283 }
284
285 free(exts);
286
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800287 return true;
288}
289
290CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800291 const VkAllocationCallbacks& allocator)
292 : is_instance_(true),
293 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800294 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800295 instance_info_(create_info),
296 extension_filter_() {
297 hook_extensions_.set(ProcHook::EXTENSION_CORE);
298 hal_extensions_.set(ProcHook::EXTENSION_CORE);
299}
300
Chia-I Wu4901db72016-03-24 16:38:58 +0800301CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
302 const VkDeviceCreateInfo& create_info,
303 const VkAllocationCallbacks& allocator)
304 : is_instance_(false),
305 allocator_(allocator),
306 physical_dev_(physical_dev),
307 dev_info_(create_info),
308 extension_filter_() {
309 hook_extensions_.set(ProcHook::EXTENSION_CORE);
310 hal_extensions_.set(ProcHook::EXTENSION_CORE);
311}
312
313CreateInfoWrapper::~CreateInfoWrapper() {
314 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
315 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
316}
317
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800318VkResult CreateInfoWrapper::Validate() {
319 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800320 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800321 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800322 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800323 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800324
325 return result;
326}
327
328const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800329CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800330 return hook_extensions_;
331}
332
333const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800334CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800335 return hal_extensions_;
336}
337
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800338CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
339 return &instance_info_;
340}
341
Chia-I Wu4901db72016-03-24 16:38:58 +0800342CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
343 return &dev_info_;
344}
345
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800346VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800347 const struct StructHeader {
348 VkStructureType type;
349 const void* next;
350 } * header;
351
352 if (is_instance_) {
353 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
354
355 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
356 while (header &&
357 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
358 header = reinterpret_cast<const StructHeader*>(header->next);
359
360 instance_info_.pNext = header;
361 } else {
362 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
363
364 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
365 while (header &&
366 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
367 header = reinterpret_cast<const StructHeader*>(header->next);
368
369 dev_info_.pNext = header;
370 }
371
372 return VK_SUCCESS;
373}
374
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800375VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800376 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
377 : dev_info_.ppEnabledLayerNames;
378 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
379 : dev_info_.enabledLayerCount;
380
381 // remove all layers
382 layer_names = nullptr;
383 layer_count = 0;
384
385 return VK_SUCCESS;
386}
387
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800388VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800389 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
390 : dev_info_.ppEnabledExtensionNames;
391 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
392 : dev_info_.enabledExtensionCount;
393 if (!ext_count)
394 return VK_SUCCESS;
395
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800396 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800397 if (result != VK_SUCCESS)
398 return result;
399
400 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800401 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800402
403 ext_names = extension_filter_.names;
404 ext_count = extension_filter_.name_count;
405
406 return VK_SUCCESS;
407}
408
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800409VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800410 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800411 return Hal::Device().EnumerateInstanceExtensionProperties(
412 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800413 } else {
414 const auto& driver = GetData(physical_dev_).driver;
415 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
416 &count, nullptr);
417 }
418}
419
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800420VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800421 uint32_t& count,
422 VkExtensionProperties* props) const {
423 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800424 return Hal::Device().EnumerateInstanceExtensionProperties(
425 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800426 } else {
427 const auto& driver = GetData(physical_dev_).driver;
428 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
429 &count, props);
430 }
431}
432
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800433VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800434 // query extension count
435 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800436 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800437 if (result != VK_SUCCESS || count == 0)
438 return result;
439
440 auto& filter = extension_filter_;
441 filter.exts =
442 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
443 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
444 alignof(VkExtensionProperties),
445 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
446 if (!filter.exts)
447 return VK_ERROR_OUT_OF_HOST_MEMORY;
448
449 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800450 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800451 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
452 return result;
453
454 if (!count)
455 return VK_SUCCESS;
456
457 filter.ext_count = count;
458
459 // allocate name array
460 uint32_t enabled_ext_count = (is_instance_)
461 ? instance_info_.enabledExtensionCount
462 : dev_info_.enabledExtensionCount;
463 count = std::min(filter.ext_count, enabled_ext_count);
464 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
465 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
466 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
467 if (!filter.names)
468 return VK_ERROR_OUT_OF_HOST_MEMORY;
469
470 return VK_SUCCESS;
471}
472
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800473void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800474 auto& filter = extension_filter_;
475
476 ProcHook::Extension ext_bit = GetProcHookExtension(name);
477 if (is_instance_) {
478 switch (ext_bit) {
479 case ProcHook::KHR_android_surface:
480 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700481 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300482 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800483 hook_extensions_.set(ext_bit);
484 // return now as these extensions do not require HAL support
485 return;
486 case ProcHook::EXT_debug_report:
487 // both we and HAL can take part in
488 hook_extensions_.set(ext_bit);
489 break;
490 case ProcHook::EXTENSION_UNKNOWN:
Chris Forbes6aa30db2017-02-20 17:12:53 +1300491 case ProcHook::KHR_get_physical_device_properties2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800492 // HAL's extensions
493 break;
494 default:
495 ALOGW("Ignored invalid instance extension %s", name);
496 return;
497 }
498 } else {
499 switch (ext_bit) {
500 case ProcHook::KHR_swapchain:
501 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
502 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
503 ext_bit = ProcHook::ANDROID_native_buffer;
504 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700505 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700506 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300507 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700508 hook_extensions_.set(ext_bit);
509 // return now as these extensions do not require HAL support
510 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700511 case ProcHook::EXT_hdr_metadata:
512 hook_extensions_.set(ext_bit);
513 break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800514 case ProcHook::EXTENSION_UNKNOWN:
515 // HAL's extensions
516 break;
517 default:
518 ALOGW("Ignored invalid device extension %s", name);
519 return;
520 }
521 }
522
523 for (uint32_t i = 0; i < filter.ext_count; i++) {
524 const VkExtensionProperties& props = filter.exts[i];
525 // ignore unknown extensions
526 if (strcmp(name, props.extensionName) != 0)
527 continue;
528
Chia-I Wu4901db72016-03-24 16:38:58 +0800529 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800530 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
531 if (ext_bit == ProcHook::ANDROID_native_buffer)
532 hook_extensions_.set(ProcHook::KHR_swapchain);
533
534 hal_extensions_.set(ext_bit);
535 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800536
537 break;
538 }
539}
540
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800541VKAPI_ATTR void* DefaultAllocate(void*,
542 size_t size,
543 size_t alignment,
544 VkSystemAllocationScope) {
545 void* ptr = nullptr;
546 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
547 // additionally requires that it be at least sizeof(void*).
548 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
549 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
550 ret, ptr);
551 return ret == 0 ? ptr : nullptr;
552}
553
554VKAPI_ATTR void* DefaultReallocate(void*,
555 void* ptr,
556 size_t size,
557 size_t alignment,
558 VkSystemAllocationScope) {
559 if (size == 0) {
560 free(ptr);
561 return nullptr;
562 }
563
564 // TODO(jessehall): Right now we never shrink allocations; if the new
565 // request is smaller than the existing chunk, we just continue using it.
566 // Right now the loader never reallocs, so this doesn't matter. If that
567 // changes, or if this code is copied into some other project, this should
568 // probably have a heuristic to allocate-copy-free when doing so will save
569 // "enough" space.
570 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
571 if (size <= old_size)
572 return ptr;
573
574 void* new_ptr = nullptr;
575 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
576 return nullptr;
577 if (ptr) {
578 memcpy(new_ptr, ptr, std::min(old_size, size));
579 free(ptr);
580 }
581 return new_ptr;
582}
583
584VKAPI_ATTR void DefaultFree(void*, void* ptr) {
585 ALOGD_CALLSTACK("Free: %p", ptr);
586 free(ptr);
587}
588
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800589InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
590 void* data_mem = allocator.pfnAllocation(
591 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
592 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
593 if (!data_mem)
594 return nullptr;
595
596 return new (data_mem) InstanceData(allocator);
597}
598
599void FreeInstanceData(InstanceData* data,
600 const VkAllocationCallbacks& allocator) {
601 data->~InstanceData();
602 allocator.pfnFree(allocator.pUserData, data);
603}
604
Chia-I Wu950d6e12016-05-03 09:12:35 +0800605DeviceData* AllocateDeviceData(
606 const VkAllocationCallbacks& allocator,
607 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800608 void* data_mem = allocator.pfnAllocation(
609 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
610 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
611 if (!data_mem)
612 return nullptr;
613
Chia-I Wu950d6e12016-05-03 09:12:35 +0800614 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800615}
616
617void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
618 data->~DeviceData();
619 allocator.pfnFree(allocator.pUserData, data);
620}
621
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800622} // anonymous namespace
623
Chia-I Wu9d518162016-03-24 14:55:27 +0800624bool Debuggable() {
625 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
626}
627
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800628bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800629 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800630}
631
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800632const VkAllocationCallbacks& GetDefaultAllocator() {
633 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
634 .pUserData = nullptr,
635 .pfnAllocation = DefaultAllocate,
636 .pfnReallocation = DefaultReallocate,
637 .pfnFree = DefaultFree,
638 };
639
640 return kDefaultAllocCallbacks;
641}
642
Chia-I Wueb7db122016-03-24 09:11:06 +0800643PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
644 const ProcHook* hook = GetProcHook(pName);
645 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800646 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800647
648 if (!instance) {
649 if (hook->type == ProcHook::GLOBAL)
650 return hook->proc;
651
Chia-I Wu109f8982016-04-22 06:40:40 +0800652 // v0 layers expect
653 //
654 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
655 //
656 // to work.
657 if (strcmp(pName, "vkCreateDevice") == 0)
658 return hook->proc;
659
Chia-I Wueb7db122016-03-24 09:11:06 +0800660 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800661 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800662 pName);
663
Chia-I Wu109f8982016-04-22 06:40:40 +0800664 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800665 }
666
667 PFN_vkVoidFunction proc;
668
669 switch (hook->type) {
670 case ProcHook::INSTANCE:
671 proc = (GetData(instance).hook_extensions[hook->extension])
672 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800673 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800674 break;
675 case ProcHook::DEVICE:
676 proc = (hook->extension == ProcHook::EXTENSION_CORE)
677 ? hook->proc
678 : hook->checked_proc;
679 break;
680 default:
681 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800682 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800683 pName);
684 proc = nullptr;
685 break;
686 }
687
688 return proc;
689}
690
691PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
692 const ProcHook* hook = GetProcHook(pName);
693 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800694 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800695
696 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800697 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800698 return nullptr;
699 }
700
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800701 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
702 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800703}
704
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800705VkResult EnumerateInstanceExtensionProperties(
706 const char* pLayerName,
707 uint32_t* pPropertyCount,
708 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600709
710 android::Vector<VkExtensionProperties> loader_extensions;
711 loader_extensions.push_back({
712 VK_KHR_SURFACE_EXTENSION_NAME,
713 VK_KHR_SURFACE_SPEC_VERSION});
714 loader_extensions.push_back({
715 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
716 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
717 loader_extensions.push_back({
718 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
719 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
720
721 if (kEnableUnratifiedExtensions) {
722 loader_extensions.push_back({
723 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
724 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
725 }
726
Chia-I Wu31938252016-05-23 15:31:02 +0800727 static const VkExtensionProperties loader_debug_report_extension = {
728 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
729 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800730
731 // enumerate our extensions first
732 if (!pLayerName && pProperties) {
733 uint32_t count = std::min(
734 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
735
736 std::copy_n(loader_extensions.begin(), count, pProperties);
737
738 if (count < loader_extensions.size()) {
739 *pPropertyCount = count;
740 return VK_INCOMPLETE;
741 }
742
743 pProperties += count;
744 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800745
746 if (Hal::Get().GetDebugReportIndex() < 0) {
747 if (!*pPropertyCount) {
748 *pPropertyCount = count;
749 return VK_INCOMPLETE;
750 }
751
752 pProperties[0] = loader_debug_report_extension;
753 pProperties += 1;
754 *pPropertyCount -= 1;
755 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800756 }
757
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800758 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800759 pLayerName, pPropertyCount, pProperties);
760
Chia-I Wu31938252016-05-23 15:31:02 +0800761 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
762 int idx = Hal::Get().GetDebugReportIndex();
763 if (idx < 0) {
764 *pPropertyCount += 1;
765 } else if (pProperties &&
766 static_cast<uint32_t>(idx) < *pPropertyCount) {
767 pProperties[idx].specVersion =
768 std::min(pProperties[idx].specVersion,
769 loader_debug_report_extension.specVersion);
770 }
771
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800772 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800773 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800774
775 return result;
776}
777
Chris Forbesfa25e632017-02-22 12:36:02 +1300778bool QueryPresentationProperties(
779 VkPhysicalDevice physicalDevice,
780 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
781{
782 const InstanceData& data = GetData(physicalDevice);
783
784 // GPDP2 must be present and enabled on the instance.
785 if (!data.driver.GetPhysicalDeviceProperties2KHR)
786 return false;
787
788 // Request the android-specific presentation properties via GPDP2
789 VkPhysicalDeviceProperties2KHR properties = {
790 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
791 presentation_properties,
792 {}
793 };
794
795#pragma clang diagnostic push
796#pragma clang diagnostic ignored "-Wold-style-cast"
797 presentation_properties->sType =
798 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
799#pragma clang diagnostic pop
800 presentation_properties->pNext = nullptr;
801 presentation_properties->sharedImage = VK_FALSE;
802
803 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
804 &properties);
805
806 return true;
807}
808
Chia-I Wu01cf3052016-03-24 16:16:21 +0800809VkResult EnumerateDeviceExtensionProperties(
810 VkPhysicalDevice physicalDevice,
811 const char* pLayerName,
812 uint32_t* pPropertyCount,
813 VkExtensionProperties* pProperties) {
814 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300815 // extensions that are unconditionally exposed by the loader
816 android::Vector<VkExtensionProperties> loader_extensions;
817 loader_extensions.push_back({
818 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
819 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300820
Ian Elliott34a327b2017-03-28 13:20:35 -0600821 if (kEnableUnratifiedExtensions) {
822 // conditionally add shared_presentable_image if supportable
823 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
824 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
825 presentation_properties.sharedImage) {
826 loader_extensions.push_back({
827 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
828 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
829 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300830 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700831
Ian Elliott5c34de22017-04-10 14:42:30 -0600832 // conditionally add VK_GOOGLE_display_timing if present timestamps are
833 // supported by the driver:
834 char timestamp_property[PROPERTY_VALUE_MAX];
835 property_get("service.sf.present_timestamp", timestamp_property, "1");
836 if (strcmp(timestamp_property, "1") == 0) {
837 loader_extensions.push_back({
838 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
839 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
840 }
841
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700842 // enumerate our extensions first
843 if (!pLayerName && pProperties) {
844 uint32_t count = std::min(
845 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
846
847 std::copy_n(loader_extensions.begin(), count, pProperties);
848
849 if (count < loader_extensions.size()) {
850 *pPropertyCount = count;
851 return VK_INCOMPLETE;
852 }
853
854 pProperties += count;
855 *pPropertyCount -= count;
856 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800857
858 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
859 physicalDevice, pLayerName, pPropertyCount, pProperties);
Chia-I Wu01cf3052016-03-24 16:16:21 +0800860
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700861 if (pProperties) {
862 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
863 for (uint32_t i = 0; i < *pPropertyCount; i++) {
864 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800865
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700866 if (strcmp(prop.extensionName,
867 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
868 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800869
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700870 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
871 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
872 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
873 }
874 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800875
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700876 // restore loader extension count
877 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
878 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800879 }
880
881 return result;
882}
883
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800884VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
885 const VkAllocationCallbacks* pAllocator,
886 VkInstance* pInstance) {
887 const VkAllocationCallbacks& data_allocator =
888 (pAllocator) ? *pAllocator : GetDefaultAllocator();
889
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800890 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800891 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800892 if (result != VK_SUCCESS)
893 return result;
894
895 InstanceData* data = AllocateInstanceData(data_allocator);
896 if (!data)
897 return VK_ERROR_OUT_OF_HOST_MEMORY;
898
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800899 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800900
901 // call into the driver
902 VkInstance instance;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800903 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800904 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
905 &instance);
906 if (result != VK_SUCCESS) {
907 FreeInstanceData(data, data_allocator);
908 return result;
909 }
910
911 // initialize InstanceDriverTable
912 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800913 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800914 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800915 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800916 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800917 if (data->driver.DestroyInstance)
918 data->driver.DestroyInstance(instance, pAllocator);
919
920 FreeInstanceData(data, data_allocator);
921
922 return VK_ERROR_INCOMPATIBLE_DRIVER;
923 }
924
925 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800926 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800927 if (!data->get_device_proc_addr) {
928 data->driver.DestroyInstance(instance, pAllocator);
929 FreeInstanceData(data, data_allocator);
930
931 return VK_ERROR_INCOMPATIBLE_DRIVER;
932 }
933
934 *pInstance = instance;
935
936 return VK_SUCCESS;
937}
938
939void DestroyInstance(VkInstance instance,
940 const VkAllocationCallbacks* pAllocator) {
941 InstanceData& data = GetData(instance);
942 data.driver.DestroyInstance(instance, pAllocator);
943
944 VkAllocationCallbacks local_allocator;
945 if (!pAllocator) {
946 local_allocator = data.allocator;
947 pAllocator = &local_allocator;
948 }
949
950 FreeInstanceData(&data, *pAllocator);
951}
952
Chia-I Wu4901db72016-03-24 16:38:58 +0800953VkResult CreateDevice(VkPhysicalDevice physicalDevice,
954 const VkDeviceCreateInfo* pCreateInfo,
955 const VkAllocationCallbacks* pAllocator,
956 VkDevice* pDevice) {
957 const InstanceData& instance_data = GetData(physicalDevice);
958 const VkAllocationCallbacks& data_allocator =
959 (pAllocator) ? *pAllocator : instance_data.allocator;
960
961 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800962 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800963 if (result != VK_SUCCESS)
964 return result;
965
Chia-I Wu950d6e12016-05-03 09:12:35 +0800966 DeviceData* data = AllocateDeviceData(data_allocator,
967 instance_data.debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800968 if (!data)
969 return VK_ERROR_OUT_OF_HOST_MEMORY;
970
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800971 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800972
973 // call into the driver
974 VkDevice dev;
975 result = instance_data.driver.CreateDevice(
976 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
977 pAllocator, &dev);
978 if (result != VK_SUCCESS) {
979 FreeDeviceData(data, data_allocator);
980 return result;
981 }
982
983 // initialize DeviceDriverTable
984 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800985 !InitDriverTable(dev, instance_data.get_device_proc_addr,
986 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800987 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
988 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
989 if (data->driver.DestroyDevice)
990 data->driver.DestroyDevice(dev, pAllocator);
991
992 FreeDeviceData(data, data_allocator);
993
994 return VK_ERROR_INCOMPATIBLE_DRIVER;
995 }
Chris Forbesd8277912017-02-10 14:59:59 +1300996
997 // sanity check ANDROID_native_buffer implementation, whose set of
998 // entrypoints varies according to the spec version.
999 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1000 !data->driver.GetSwapchainGrallocUsageANDROID &&
1001 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1002 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1003 " must expose at least one of "
1004 "vkGetSwapchainGrallocUsageANDROID or "
1005 "vkGetSwapchainGrallocUsage2ANDROID");
1006
1007 data->driver.DestroyDevice(dev, pAllocator);
1008 FreeDeviceData(data, data_allocator);
1009
1010 return VK_ERROR_INCOMPATIBLE_DRIVER;
1011 }
1012
Jesse Hall85bb0c52017-02-09 22:13:02 -08001013 VkPhysicalDeviceProperties properties;
1014 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1015 &properties);
1016
Jesse Halldc225072016-05-30 22:40:14 -07001017 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001018 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001019
1020 *pDevice = dev;
1021
1022 return VK_SUCCESS;
1023}
1024
1025void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1026 DeviceData& data = GetData(device);
1027 data.driver.DestroyDevice(device, pAllocator);
1028
1029 VkAllocationCallbacks local_allocator;
1030 if (!pAllocator) {
1031 local_allocator = data.allocator;
1032 pAllocator = &local_allocator;
1033 }
1034
1035 FreeDeviceData(&data, *pAllocator);
1036}
1037
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001038VkResult EnumeratePhysicalDevices(VkInstance instance,
1039 uint32_t* pPhysicalDeviceCount,
1040 VkPhysicalDevice* pPhysicalDevices) {
1041 const auto& data = GetData(instance);
1042
1043 VkResult result = data.driver.EnumeratePhysicalDevices(
1044 instance, pPhysicalDeviceCount, pPhysicalDevices);
1045 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1046 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1047 SetData(pPhysicalDevices[i], data);
1048 }
1049
1050 return result;
1051}
1052
Chia-I Wuba0be412016-03-24 16:24:40 +08001053void GetDeviceQueue(VkDevice device,
1054 uint32_t queueFamilyIndex,
1055 uint32_t queueIndex,
1056 VkQueue* pQueue) {
1057 const auto& data = GetData(device);
1058
1059 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1060 SetData(*pQueue, data);
1061}
1062
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001063VKAPI_ATTR VkResult
1064AllocateCommandBuffers(VkDevice device,
1065 const VkCommandBufferAllocateInfo* pAllocateInfo,
1066 VkCommandBuffer* pCommandBuffers) {
1067 const auto& data = GetData(device);
1068
1069 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1070 pCommandBuffers);
1071 if (result == VK_SUCCESS) {
1072 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1073 SetData(pCommandBuffers[i], data);
1074 }
1075
1076 return result;
1077}
1078
Chia-I Wu9d518162016-03-24 14:55:27 +08001079} // namespace driver
1080} // namespace vulkan