blob: dbb217d956797b9afaef5b3e94c8fdcf0f5238ba [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
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080037// #define ENABLE_ALLOC_CALLSTACKS 1
38#if ENABLE_ALLOC_CALLSTACKS
39#include <utils/CallStack.h>
40#define ALOGD_CALLSTACK(...) \
41 do { \
42 ALOGD(__VA_ARGS__); \
43 android::CallStack callstack; \
44 callstack.update(); \
45 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
46 } while (false)
47#else
48#define ALOGD_CALLSTACK(...) \
49 do { \
50 } while (false)
51#endif
52
Chia-I Wu9d518162016-03-24 14:55:27 +080053namespace vulkan {
54namespace driver {
55
Chia-I Wu136b8eb2016-03-24 15:01:52 +080056namespace {
57
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080058class Hal {
59 public:
60 static bool Open();
61
62 static const Hal& Get() { return hal_; }
63 static const hwvulkan_device_t& Device() { return *Get().dev_; }
64
Chia-I Wu31938252016-05-23 15:31:02 +080065 int GetDebugReportIndex() const { return debug_report_index_; }
66
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080067 private:
Chia-I Wu31938252016-05-23 15:31:02 +080068 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080069 Hal(const Hal&) = delete;
70 Hal& operator=(const Hal&) = delete;
71
Chia-I Wu31938252016-05-23 15:31:02 +080072 bool InitDebugReportIndex();
73
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080074 static Hal hal_;
75
76 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080077 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080078};
79
Chia-I Wu4901db72016-03-24 16:38:58 +080080class CreateInfoWrapper {
81 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080082 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080083 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080084 CreateInfoWrapper(VkPhysicalDevice physical_dev,
85 const VkDeviceCreateInfo& create_info,
86 const VkAllocationCallbacks& allocator);
87 ~CreateInfoWrapper();
88
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080089 VkResult Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +080090
Chia-I Wu3e6c2d62016-04-11 13:55:56 +080091 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
92 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +080093
Chia-I Wuff4a6c72016-03-24 16:05:56 +080094 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +080095 explicit operator const VkDeviceCreateInfo*() const;
96
97 private:
98 struct ExtensionFilter {
99 VkExtensionProperties* exts;
100 uint32_t ext_count;
101
102 const char** names;
103 uint32_t name_count;
104 };
105
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800106 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800107
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800108 VkResult SanitizeLayers();
109 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800110
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800111 VkResult QueryExtensionCount(uint32_t& count) const;
112 VkResult EnumerateExtensions(uint32_t& count,
113 VkExtensionProperties* props) const;
114 VkResult InitExtensionFilter();
115 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800116
117 const bool is_instance_;
118 const VkAllocationCallbacks& allocator_;
119
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800120 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800121
122 union {
123 VkInstanceCreateInfo instance_info_;
124 VkDeviceCreateInfo dev_info_;
125 };
126
127 ExtensionFilter extension_filter_;
128
129 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
130 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
131};
132
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800133Hal Hal::hal_;
134
Jesse Hall53457db2016-12-14 16:54:06 -0800135void* LoadLibrary(const android_dlextinfo& dlextinfo,
136 const char* subname,
137 int subname_len) {
138 const char kLibFormat[] = "vulkan.%*s.so";
139 char* name = static_cast<char*>(
140 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
141 sprintf(name, kLibFormat, subname_len, subname);
142 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
143}
144
145const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
146 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
147 "ro.board.platform",
148}};
149
150int LoadUpdatedDriver(const hw_module_t** module) {
151 const android_dlextinfo dlextinfo = {
152 .flags = ANDROID_DLEXT_USE_NAMESPACE,
153 .library_namespace = android::GraphicsEnv::getInstance().getDriverNamespace(),
154 };
155 if (!dlextinfo.library_namespace)
156 return -ENOENT;
157
158 void* so = nullptr;
159 char prop[PROPERTY_VALUE_MAX];
160 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
161 int prop_len = property_get(key, prop, nullptr);
162 if (prop_len > 0) {
163 so = LoadLibrary(dlextinfo, prop, prop_len);
164 if (so)
165 break;
166 }
167 }
168 if (!so)
169 return -ENOENT;
170
171 hw_module_t* hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
172 if (!hmi) {
173 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
174 dlclose(so);
175 return -EINVAL;
176 }
177 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
178 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
179 dlclose(so);
180 return -EINVAL;
181 }
182 hmi->dso = so;
183 *module = hmi;
184 ALOGD("loaded updated driver");
185 return 0;
186}
187
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800188bool Hal::Open() {
Jesse Halldc225072016-05-30 22:40:14 -0700189 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800190
191 // Use a stub device unless we successfully open a real HAL device.
192 hal_.dev_ = &stubhal::kDevice;
193
Jesse Hall53457db2016-12-14 16:54:06 -0800194 int result;
195 const hwvulkan_module_t* module = nullptr;
196
197 result = LoadUpdatedDriver(reinterpret_cast<const hw_module_t**>(&module));
198 if (result == -ENOENT) {
199 result = hw_get_module(HWVULKAN_HARDWARE_MODULE_ID, reinterpret_cast<const hw_module_t**>(&module));
200 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800201 if (result != 0) {
Jesse Hall53457db2016-12-14 16:54:06 -0800202 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800203 return true;
204 }
205
206 hwvulkan_device_t* device;
207 result =
208 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
209 reinterpret_cast<hw_device_t**>(&device));
210 if (result != 0) {
211 // Any device with a Vulkan HAL should be able to open the device.
212 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
213 result);
214 return false;
215 }
216
217 hal_.dev_ = device;
218
Chia-I Wu31938252016-05-23 15:31:02 +0800219 hal_.InitDebugReportIndex();
220
221 return true;
222}
223
224bool Hal::InitDebugReportIndex() {
225 uint32_t count;
226 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
227 VK_SUCCESS) {
228 ALOGE("failed to get HAL instance extension count");
229 return false;
230 }
231
232 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
233 malloc(sizeof(VkExtensionProperties) * count));
234 if (!exts) {
235 ALOGE("failed to allocate HAL instance extension array");
236 return false;
237 }
238
239 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
240 VK_SUCCESS) {
241 ALOGE("failed to enumerate HAL instance extensions");
242 free(exts);
243 return false;
244 }
245
246 for (uint32_t i = 0; i < count; i++) {
247 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
248 0) {
249 debug_report_index_ = static_cast<int>(i);
250 break;
251 }
252 }
253
254 free(exts);
255
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800256 return true;
257}
258
259CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800260 const VkAllocationCallbacks& allocator)
261 : is_instance_(true),
262 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800263 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800264 instance_info_(create_info),
265 extension_filter_() {
266 hook_extensions_.set(ProcHook::EXTENSION_CORE);
267 hal_extensions_.set(ProcHook::EXTENSION_CORE);
268}
269
Chia-I Wu4901db72016-03-24 16:38:58 +0800270CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
271 const VkDeviceCreateInfo& create_info,
272 const VkAllocationCallbacks& allocator)
273 : is_instance_(false),
274 allocator_(allocator),
275 physical_dev_(physical_dev),
276 dev_info_(create_info),
277 extension_filter_() {
278 hook_extensions_.set(ProcHook::EXTENSION_CORE);
279 hal_extensions_.set(ProcHook::EXTENSION_CORE);
280}
281
282CreateInfoWrapper::~CreateInfoWrapper() {
283 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
284 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
285}
286
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800287VkResult CreateInfoWrapper::Validate() {
288 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800289 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800290 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800291 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800292 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800293
294 return result;
295}
296
297const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800298CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800299 return hook_extensions_;
300}
301
302const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800303CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800304 return hal_extensions_;
305}
306
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800307CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
308 return &instance_info_;
309}
310
Chia-I Wu4901db72016-03-24 16:38:58 +0800311CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
312 return &dev_info_;
313}
314
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800315VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800316 const struct StructHeader {
317 VkStructureType type;
318 const void* next;
319 } * header;
320
321 if (is_instance_) {
322 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
323
324 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
325 while (header &&
326 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
327 header = reinterpret_cast<const StructHeader*>(header->next);
328
329 instance_info_.pNext = header;
330 } else {
331 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
332
333 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
334 while (header &&
335 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
336 header = reinterpret_cast<const StructHeader*>(header->next);
337
338 dev_info_.pNext = header;
339 }
340
341 return VK_SUCCESS;
342}
343
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800344VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800345 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
346 : dev_info_.ppEnabledLayerNames;
347 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
348 : dev_info_.enabledLayerCount;
349
350 // remove all layers
351 layer_names = nullptr;
352 layer_count = 0;
353
354 return VK_SUCCESS;
355}
356
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800357VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800358 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
359 : dev_info_.ppEnabledExtensionNames;
360 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
361 : dev_info_.enabledExtensionCount;
362 if (!ext_count)
363 return VK_SUCCESS;
364
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800365 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800366 if (result != VK_SUCCESS)
367 return result;
368
369 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800370 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800371
372 ext_names = extension_filter_.names;
373 ext_count = extension_filter_.name_count;
374
375 return VK_SUCCESS;
376}
377
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800378VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800379 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800380 return Hal::Device().EnumerateInstanceExtensionProperties(
381 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800382 } else {
383 const auto& driver = GetData(physical_dev_).driver;
384 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
385 &count, nullptr);
386 }
387}
388
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800389VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800390 uint32_t& count,
391 VkExtensionProperties* props) const {
392 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800393 return Hal::Device().EnumerateInstanceExtensionProperties(
394 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800395 } else {
396 const auto& driver = GetData(physical_dev_).driver;
397 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
398 &count, props);
399 }
400}
401
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800402VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800403 // query extension count
404 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800405 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800406 if (result != VK_SUCCESS || count == 0)
407 return result;
408
409 auto& filter = extension_filter_;
410 filter.exts =
411 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
412 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
413 alignof(VkExtensionProperties),
414 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
415 if (!filter.exts)
416 return VK_ERROR_OUT_OF_HOST_MEMORY;
417
418 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800419 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800420 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
421 return result;
422
423 if (!count)
424 return VK_SUCCESS;
425
426 filter.ext_count = count;
427
428 // allocate name array
429 uint32_t enabled_ext_count = (is_instance_)
430 ? instance_info_.enabledExtensionCount
431 : dev_info_.enabledExtensionCount;
432 count = std::min(filter.ext_count, enabled_ext_count);
433 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
434 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
435 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
436 if (!filter.names)
437 return VK_ERROR_OUT_OF_HOST_MEMORY;
438
439 return VK_SUCCESS;
440}
441
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800442void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800443 auto& filter = extension_filter_;
444
445 ProcHook::Extension ext_bit = GetProcHookExtension(name);
446 if (is_instance_) {
447 switch (ext_bit) {
448 case ProcHook::KHR_android_surface:
449 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700450 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300451 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800452 hook_extensions_.set(ext_bit);
453 // return now as these extensions do not require HAL support
454 return;
455 case ProcHook::EXT_debug_report:
456 // both we and HAL can take part in
457 hook_extensions_.set(ext_bit);
458 break;
459 case ProcHook::EXTENSION_UNKNOWN:
Chris Forbes6aa30db2017-02-20 17:12:53 +1300460 case ProcHook::KHR_get_physical_device_properties2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800461 // HAL's extensions
462 break;
463 default:
464 ALOGW("Ignored invalid instance extension %s", name);
465 return;
466 }
467 } else {
468 switch (ext_bit) {
469 case ProcHook::KHR_swapchain:
470 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
471 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
472 ext_bit = ProcHook::ANDROID_native_buffer;
473 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700474 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700475 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300476 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700477 hook_extensions_.set(ext_bit);
478 // return now as these extensions do not require HAL support
479 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700480 case ProcHook::EXT_hdr_metadata:
481 hook_extensions_.set(ext_bit);
482 break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800483 case ProcHook::EXTENSION_UNKNOWN:
484 // HAL's extensions
485 break;
486 default:
487 ALOGW("Ignored invalid device extension %s", name);
488 return;
489 }
490 }
491
492 for (uint32_t i = 0; i < filter.ext_count; i++) {
493 const VkExtensionProperties& props = filter.exts[i];
494 // ignore unknown extensions
495 if (strcmp(name, props.extensionName) != 0)
496 continue;
497
Chia-I Wu4901db72016-03-24 16:38:58 +0800498 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800499 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
500 if (ext_bit == ProcHook::ANDROID_native_buffer)
501 hook_extensions_.set(ProcHook::KHR_swapchain);
502
503 hal_extensions_.set(ext_bit);
504 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800505
506 break;
507 }
508}
509
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800510VKAPI_ATTR void* DefaultAllocate(void*,
511 size_t size,
512 size_t alignment,
513 VkSystemAllocationScope) {
514 void* ptr = nullptr;
515 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
516 // additionally requires that it be at least sizeof(void*).
517 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
518 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
519 ret, ptr);
520 return ret == 0 ? ptr : nullptr;
521}
522
523VKAPI_ATTR void* DefaultReallocate(void*,
524 void* ptr,
525 size_t size,
526 size_t alignment,
527 VkSystemAllocationScope) {
528 if (size == 0) {
529 free(ptr);
530 return nullptr;
531 }
532
533 // TODO(jessehall): Right now we never shrink allocations; if the new
534 // request is smaller than the existing chunk, we just continue using it.
535 // Right now the loader never reallocs, so this doesn't matter. If that
536 // changes, or if this code is copied into some other project, this should
537 // probably have a heuristic to allocate-copy-free when doing so will save
538 // "enough" space.
539 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
540 if (size <= old_size)
541 return ptr;
542
543 void* new_ptr = nullptr;
544 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
545 return nullptr;
546 if (ptr) {
547 memcpy(new_ptr, ptr, std::min(old_size, size));
548 free(ptr);
549 }
550 return new_ptr;
551}
552
553VKAPI_ATTR void DefaultFree(void*, void* ptr) {
554 ALOGD_CALLSTACK("Free: %p", ptr);
555 free(ptr);
556}
557
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800558InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
559 void* data_mem = allocator.pfnAllocation(
560 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
561 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
562 if (!data_mem)
563 return nullptr;
564
565 return new (data_mem) InstanceData(allocator);
566}
567
568void FreeInstanceData(InstanceData* data,
569 const VkAllocationCallbacks& allocator) {
570 data->~InstanceData();
571 allocator.pfnFree(allocator.pUserData, data);
572}
573
Chia-I Wu950d6e12016-05-03 09:12:35 +0800574DeviceData* AllocateDeviceData(
575 const VkAllocationCallbacks& allocator,
576 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800577 void* data_mem = allocator.pfnAllocation(
578 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
579 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
580 if (!data_mem)
581 return nullptr;
582
Chia-I Wu950d6e12016-05-03 09:12:35 +0800583 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800584}
585
586void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
587 data->~DeviceData();
588 allocator.pfnFree(allocator.pUserData, data);
589}
590
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800591} // anonymous namespace
592
Chia-I Wu9d518162016-03-24 14:55:27 +0800593bool Debuggable() {
594 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
595}
596
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800597bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800598 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800599}
600
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800601const VkAllocationCallbacks& GetDefaultAllocator() {
602 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
603 .pUserData = nullptr,
604 .pfnAllocation = DefaultAllocate,
605 .pfnReallocation = DefaultReallocate,
606 .pfnFree = DefaultFree,
607 };
608
609 return kDefaultAllocCallbacks;
610}
611
Chia-I Wueb7db122016-03-24 09:11:06 +0800612PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
613 const ProcHook* hook = GetProcHook(pName);
614 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800615 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800616
617 if (!instance) {
618 if (hook->type == ProcHook::GLOBAL)
619 return hook->proc;
620
Chia-I Wu109f8982016-04-22 06:40:40 +0800621 // v0 layers expect
622 //
623 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
624 //
625 // to work.
626 if (strcmp(pName, "vkCreateDevice") == 0)
627 return hook->proc;
628
Chia-I Wueb7db122016-03-24 09:11:06 +0800629 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800630 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800631 pName);
632
Chia-I Wu109f8982016-04-22 06:40:40 +0800633 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800634 }
635
636 PFN_vkVoidFunction proc;
637
638 switch (hook->type) {
639 case ProcHook::INSTANCE:
640 proc = (GetData(instance).hook_extensions[hook->extension])
641 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800642 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800643 break;
644 case ProcHook::DEVICE:
645 proc = (hook->extension == ProcHook::EXTENSION_CORE)
646 ? hook->proc
647 : hook->checked_proc;
648 break;
649 default:
650 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800651 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800652 pName);
653 proc = nullptr;
654 break;
655 }
656
657 return proc;
658}
659
660PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
661 const ProcHook* hook = GetProcHook(pName);
662 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800663 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800664
665 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800666 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800667 return nullptr;
668 }
669
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800670 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
671 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800672}
673
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800674VkResult EnumerateInstanceExtensionProperties(
675 const char* pLayerName,
676 uint32_t* pPropertyCount,
677 VkExtensionProperties* pProperties) {
Chris Forbes2452cf72017-03-16 16:30:17 +1300678 static const std::array<VkExtensionProperties, 4> loader_extensions = {{
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800679 // WSI extensions
680 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION},
681 {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
682 VK_KHR_ANDROID_SURFACE_SPEC_VERSION},
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700683 {VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
684 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION},
Chris Forbes2452cf72017-03-16 16:30:17 +1300685 {VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
686 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION},
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800687 }};
Chia-I Wu31938252016-05-23 15:31:02 +0800688 static const VkExtensionProperties loader_debug_report_extension = {
689 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
690 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800691
692 // enumerate our extensions first
693 if (!pLayerName && pProperties) {
694 uint32_t count = std::min(
695 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
696
697 std::copy_n(loader_extensions.begin(), count, pProperties);
698
699 if (count < loader_extensions.size()) {
700 *pPropertyCount = count;
701 return VK_INCOMPLETE;
702 }
703
704 pProperties += count;
705 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800706
707 if (Hal::Get().GetDebugReportIndex() < 0) {
708 if (!*pPropertyCount) {
709 *pPropertyCount = count;
710 return VK_INCOMPLETE;
711 }
712
713 pProperties[0] = loader_debug_report_extension;
714 pProperties += 1;
715 *pPropertyCount -= 1;
716 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800717 }
718
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800719 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800720 pLayerName, pPropertyCount, pProperties);
721
Chia-I Wu31938252016-05-23 15:31:02 +0800722 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
723 int idx = Hal::Get().GetDebugReportIndex();
724 if (idx < 0) {
725 *pPropertyCount += 1;
726 } else if (pProperties &&
727 static_cast<uint32_t>(idx) < *pPropertyCount) {
728 pProperties[idx].specVersion =
729 std::min(pProperties[idx].specVersion,
730 loader_debug_report_extension.specVersion);
731 }
732
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800733 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800734 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800735
736 return result;
737}
738
Chris Forbesfa25e632017-02-22 12:36:02 +1300739bool QueryPresentationProperties(
740 VkPhysicalDevice physicalDevice,
741 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
742{
743 const InstanceData& data = GetData(physicalDevice);
744
745 // GPDP2 must be present and enabled on the instance.
746 if (!data.driver.GetPhysicalDeviceProperties2KHR)
747 return false;
748
749 // Request the android-specific presentation properties via GPDP2
750 VkPhysicalDeviceProperties2KHR properties = {
751 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
752 presentation_properties,
753 {}
754 };
755
756#pragma clang diagnostic push
757#pragma clang diagnostic ignored "-Wold-style-cast"
758 presentation_properties->sType =
759 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
760#pragma clang diagnostic pop
761 presentation_properties->pNext = nullptr;
762 presentation_properties->sharedImage = VK_FALSE;
763
764 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
765 &properties);
766
767 return true;
768}
769
Chia-I Wu01cf3052016-03-24 16:16:21 +0800770VkResult EnumerateDeviceExtensionProperties(
771 VkPhysicalDevice physicalDevice,
772 const char* pLayerName,
773 uint32_t* pPropertyCount,
774 VkExtensionProperties* pProperties) {
775 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300776 // extensions that are unconditionally exposed by the loader
777 android::Vector<VkExtensionProperties> loader_extensions;
778 loader_extensions.push_back({
779 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
780 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
781 loader_extensions.push_back({
782 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
783 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300784
785 // conditionally add shared_presentable_image if supportable
786 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
787 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
788 presentation_properties.sharedImage) {
789 loader_extensions.push_back({
790 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
791 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
792 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700793
794 // enumerate our extensions first
795 if (!pLayerName && pProperties) {
796 uint32_t count = std::min(
797 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
798
799 std::copy_n(loader_extensions.begin(), count, pProperties);
800
801 if (count < loader_extensions.size()) {
802 *pPropertyCount = count;
803 return VK_INCOMPLETE;
804 }
805
806 pProperties += count;
807 *pPropertyCount -= count;
808 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800809
810 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
811 physicalDevice, pLayerName, pPropertyCount, pProperties);
Chia-I Wu01cf3052016-03-24 16:16:21 +0800812
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700813 if (pProperties) {
814 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
815 for (uint32_t i = 0; i < *pPropertyCount; i++) {
816 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800817
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700818 if (strcmp(prop.extensionName,
819 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
820 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800821
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700822 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
823 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
824 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
825 }
826 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800827
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700828 // restore loader extension count
829 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
830 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800831 }
832
833 return result;
834}
835
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800836VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
837 const VkAllocationCallbacks* pAllocator,
838 VkInstance* pInstance) {
839 const VkAllocationCallbacks& data_allocator =
840 (pAllocator) ? *pAllocator : GetDefaultAllocator();
841
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800842 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800843 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800844 if (result != VK_SUCCESS)
845 return result;
846
847 InstanceData* data = AllocateInstanceData(data_allocator);
848 if (!data)
849 return VK_ERROR_OUT_OF_HOST_MEMORY;
850
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800851 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800852
853 // call into the driver
854 VkInstance instance;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800855 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800856 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
857 &instance);
858 if (result != VK_SUCCESS) {
859 FreeInstanceData(data, data_allocator);
860 return result;
861 }
862
863 // initialize InstanceDriverTable
864 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800865 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800866 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800867 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800868 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800869 if (data->driver.DestroyInstance)
870 data->driver.DestroyInstance(instance, pAllocator);
871
872 FreeInstanceData(data, data_allocator);
873
874 return VK_ERROR_INCOMPATIBLE_DRIVER;
875 }
876
877 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800878 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800879 if (!data->get_device_proc_addr) {
880 data->driver.DestroyInstance(instance, pAllocator);
881 FreeInstanceData(data, data_allocator);
882
883 return VK_ERROR_INCOMPATIBLE_DRIVER;
884 }
885
886 *pInstance = instance;
887
888 return VK_SUCCESS;
889}
890
891void DestroyInstance(VkInstance instance,
892 const VkAllocationCallbacks* pAllocator) {
893 InstanceData& data = GetData(instance);
894 data.driver.DestroyInstance(instance, pAllocator);
895
896 VkAllocationCallbacks local_allocator;
897 if (!pAllocator) {
898 local_allocator = data.allocator;
899 pAllocator = &local_allocator;
900 }
901
902 FreeInstanceData(&data, *pAllocator);
903}
904
Chia-I Wu4901db72016-03-24 16:38:58 +0800905VkResult CreateDevice(VkPhysicalDevice physicalDevice,
906 const VkDeviceCreateInfo* pCreateInfo,
907 const VkAllocationCallbacks* pAllocator,
908 VkDevice* pDevice) {
909 const InstanceData& instance_data = GetData(physicalDevice);
910 const VkAllocationCallbacks& data_allocator =
911 (pAllocator) ? *pAllocator : instance_data.allocator;
912
913 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800914 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800915 if (result != VK_SUCCESS)
916 return result;
917
Chia-I Wu950d6e12016-05-03 09:12:35 +0800918 DeviceData* data = AllocateDeviceData(data_allocator,
919 instance_data.debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800920 if (!data)
921 return VK_ERROR_OUT_OF_HOST_MEMORY;
922
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800923 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800924
925 // call into the driver
926 VkDevice dev;
927 result = instance_data.driver.CreateDevice(
928 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
929 pAllocator, &dev);
930 if (result != VK_SUCCESS) {
931 FreeDeviceData(data, data_allocator);
932 return result;
933 }
934
935 // initialize DeviceDriverTable
936 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800937 !InitDriverTable(dev, instance_data.get_device_proc_addr,
938 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800939 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
940 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
941 if (data->driver.DestroyDevice)
942 data->driver.DestroyDevice(dev, pAllocator);
943
944 FreeDeviceData(data, data_allocator);
945
946 return VK_ERROR_INCOMPATIBLE_DRIVER;
947 }
Chris Forbesd8277912017-02-10 14:59:59 +1300948
949 // sanity check ANDROID_native_buffer implementation, whose set of
950 // entrypoints varies according to the spec version.
951 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
952 !data->driver.GetSwapchainGrallocUsageANDROID &&
953 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
954 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
955 " must expose at least one of "
956 "vkGetSwapchainGrallocUsageANDROID or "
957 "vkGetSwapchainGrallocUsage2ANDROID");
958
959 data->driver.DestroyDevice(dev, pAllocator);
960 FreeDeviceData(data, data_allocator);
961
962 return VK_ERROR_INCOMPATIBLE_DRIVER;
963 }
964
Jesse Hall85bb0c52017-02-09 22:13:02 -0800965 VkPhysicalDeviceProperties properties;
966 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
967 &properties);
968
Jesse Halldc225072016-05-30 22:40:14 -0700969 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -0800970 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +0800971
972 *pDevice = dev;
973
974 return VK_SUCCESS;
975}
976
977void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
978 DeviceData& data = GetData(device);
979 data.driver.DestroyDevice(device, pAllocator);
980
981 VkAllocationCallbacks local_allocator;
982 if (!pAllocator) {
983 local_allocator = data.allocator;
984 pAllocator = &local_allocator;
985 }
986
987 FreeDeviceData(&data, *pAllocator);
988}
989
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800990VkResult EnumeratePhysicalDevices(VkInstance instance,
991 uint32_t* pPhysicalDeviceCount,
992 VkPhysicalDevice* pPhysicalDevices) {
993 const auto& data = GetData(instance);
994
995 VkResult result = data.driver.EnumeratePhysicalDevices(
996 instance, pPhysicalDeviceCount, pPhysicalDevices);
997 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
998 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
999 SetData(pPhysicalDevices[i], data);
1000 }
1001
1002 return result;
1003}
1004
Chia-I Wuba0be412016-03-24 16:24:40 +08001005void GetDeviceQueue(VkDevice device,
1006 uint32_t queueFamilyIndex,
1007 uint32_t queueIndex,
1008 VkQueue* pQueue) {
1009 const auto& data = GetData(device);
1010
1011 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1012 SetData(*pQueue, data);
1013}
1014
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001015VKAPI_ATTR VkResult
1016AllocateCommandBuffers(VkDevice device,
1017 const VkCommandBufferAllocateInfo* pAllocateInfo,
1018 VkCommandBuffer* pCommandBuffers) {
1019 const auto& data = GetData(device);
1020
1021 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1022 pCommandBuffers);
1023 if (result == VK_SUCCESS) {
1024 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1025 SetData(pCommandBuffers[i], data);
1026 }
1027
1028 return result;
1029}
1030
Chia-I Wu9d518162016-03-24 14:55:27 +08001031} // namespace driver
1032} // namespace vulkan