blob: 212d1421665eece98324586d2d7db5aa5421f9ee [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});
820 loader_extensions.push_back({
821 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
822 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300823
Ian Elliott34a327b2017-03-28 13:20:35 -0600824 if (kEnableUnratifiedExtensions) {
825 // conditionally add shared_presentable_image if supportable
826 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
827 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
828 presentation_properties.sharedImage) {
829 loader_extensions.push_back({
830 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
831 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
832 }
Chris Forbesfa25e632017-02-22 12:36:02 +1300833 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700834
835 // enumerate our extensions first
836 if (!pLayerName && pProperties) {
837 uint32_t count = std::min(
838 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
839
840 std::copy_n(loader_extensions.begin(), count, pProperties);
841
842 if (count < loader_extensions.size()) {
843 *pPropertyCount = count;
844 return VK_INCOMPLETE;
845 }
846
847 pProperties += count;
848 *pPropertyCount -= count;
849 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800850
851 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
852 physicalDevice, pLayerName, pPropertyCount, pProperties);
Chia-I Wu01cf3052016-03-24 16:16:21 +0800853
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700854 if (pProperties) {
855 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
856 for (uint32_t i = 0; i < *pPropertyCount; i++) {
857 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800858
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700859 if (strcmp(prop.extensionName,
860 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
861 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800862
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700863 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
864 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
865 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
866 }
867 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800868
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700869 // restore loader extension count
870 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
871 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800872 }
873
874 return result;
875}
876
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800877VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
878 const VkAllocationCallbacks* pAllocator,
879 VkInstance* pInstance) {
880 const VkAllocationCallbacks& data_allocator =
881 (pAllocator) ? *pAllocator : GetDefaultAllocator();
882
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800883 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800884 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800885 if (result != VK_SUCCESS)
886 return result;
887
888 InstanceData* data = AllocateInstanceData(data_allocator);
889 if (!data)
890 return VK_ERROR_OUT_OF_HOST_MEMORY;
891
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800892 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800893
894 // call into the driver
895 VkInstance instance;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800896 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800897 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
898 &instance);
899 if (result != VK_SUCCESS) {
900 FreeInstanceData(data, data_allocator);
901 return result;
902 }
903
904 // initialize InstanceDriverTable
905 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800906 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800907 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800908 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800909 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800910 if (data->driver.DestroyInstance)
911 data->driver.DestroyInstance(instance, pAllocator);
912
913 FreeInstanceData(data, data_allocator);
914
915 return VK_ERROR_INCOMPATIBLE_DRIVER;
916 }
917
918 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800919 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800920 if (!data->get_device_proc_addr) {
921 data->driver.DestroyInstance(instance, pAllocator);
922 FreeInstanceData(data, data_allocator);
923
924 return VK_ERROR_INCOMPATIBLE_DRIVER;
925 }
926
927 *pInstance = instance;
928
929 return VK_SUCCESS;
930}
931
932void DestroyInstance(VkInstance instance,
933 const VkAllocationCallbacks* pAllocator) {
934 InstanceData& data = GetData(instance);
935 data.driver.DestroyInstance(instance, pAllocator);
936
937 VkAllocationCallbacks local_allocator;
938 if (!pAllocator) {
939 local_allocator = data.allocator;
940 pAllocator = &local_allocator;
941 }
942
943 FreeInstanceData(&data, *pAllocator);
944}
945
Chia-I Wu4901db72016-03-24 16:38:58 +0800946VkResult CreateDevice(VkPhysicalDevice physicalDevice,
947 const VkDeviceCreateInfo* pCreateInfo,
948 const VkAllocationCallbacks* pAllocator,
949 VkDevice* pDevice) {
950 const InstanceData& instance_data = GetData(physicalDevice);
951 const VkAllocationCallbacks& data_allocator =
952 (pAllocator) ? *pAllocator : instance_data.allocator;
953
954 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800955 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800956 if (result != VK_SUCCESS)
957 return result;
958
Chia-I Wu950d6e12016-05-03 09:12:35 +0800959 DeviceData* data = AllocateDeviceData(data_allocator,
960 instance_data.debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800961 if (!data)
962 return VK_ERROR_OUT_OF_HOST_MEMORY;
963
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800964 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800965
966 // call into the driver
967 VkDevice dev;
968 result = instance_data.driver.CreateDevice(
969 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
970 pAllocator, &dev);
971 if (result != VK_SUCCESS) {
972 FreeDeviceData(data, data_allocator);
973 return result;
974 }
975
976 // initialize DeviceDriverTable
977 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800978 !InitDriverTable(dev, instance_data.get_device_proc_addr,
979 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800980 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
981 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
982 if (data->driver.DestroyDevice)
983 data->driver.DestroyDevice(dev, pAllocator);
984
985 FreeDeviceData(data, data_allocator);
986
987 return VK_ERROR_INCOMPATIBLE_DRIVER;
988 }
Chris Forbesd8277912017-02-10 14:59:59 +1300989
990 // sanity check ANDROID_native_buffer implementation, whose set of
991 // entrypoints varies according to the spec version.
992 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
993 !data->driver.GetSwapchainGrallocUsageANDROID &&
994 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
995 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
996 " must expose at least one of "
997 "vkGetSwapchainGrallocUsageANDROID or "
998 "vkGetSwapchainGrallocUsage2ANDROID");
999
1000 data->driver.DestroyDevice(dev, pAllocator);
1001 FreeDeviceData(data, data_allocator);
1002
1003 return VK_ERROR_INCOMPATIBLE_DRIVER;
1004 }
1005
Jesse Hall85bb0c52017-02-09 22:13:02 -08001006 VkPhysicalDeviceProperties properties;
1007 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1008 &properties);
1009
Jesse Halldc225072016-05-30 22:40:14 -07001010 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001011 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001012
1013 *pDevice = dev;
1014
1015 return VK_SUCCESS;
1016}
1017
1018void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1019 DeviceData& data = GetData(device);
1020 data.driver.DestroyDevice(device, pAllocator);
1021
1022 VkAllocationCallbacks local_allocator;
1023 if (!pAllocator) {
1024 local_allocator = data.allocator;
1025 pAllocator = &local_allocator;
1026 }
1027
1028 FreeDeviceData(&data, *pAllocator);
1029}
1030
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001031VkResult EnumeratePhysicalDevices(VkInstance instance,
1032 uint32_t* pPhysicalDeviceCount,
1033 VkPhysicalDevice* pPhysicalDevices) {
1034 const auto& data = GetData(instance);
1035
1036 VkResult result = data.driver.EnumeratePhysicalDevices(
1037 instance, pPhysicalDeviceCount, pPhysicalDevices);
1038 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1039 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1040 SetData(pPhysicalDevices[i], data);
1041 }
1042
1043 return result;
1044}
1045
Chia-I Wuba0be412016-03-24 16:24:40 +08001046void GetDeviceQueue(VkDevice device,
1047 uint32_t queueFamilyIndex,
1048 uint32_t queueIndex,
1049 VkQueue* pQueue) {
1050 const auto& data = GetData(device);
1051
1052 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1053 SetData(*pQueue, data);
1054}
1055
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001056VKAPI_ATTR VkResult
1057AllocateCommandBuffers(VkDevice device,
1058 const VkCommandBufferAllocateInfo* pAllocateInfo,
1059 VkCommandBuffer* pCommandBuffers) {
1060 const auto& data = GetData(device);
1061
1062 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1063 pCommandBuffers);
1064 if (result == VK_SUCCESS) {
1065 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1066 SetData(pCommandBuffers[i], data);
1067 }
1068
1069 return result;
1070}
1071
Chia-I Wu9d518162016-03-24 14:55:27 +08001072} // namespace driver
1073} // namespace vulkan