blob: 97d78659280aa2584ecdc1b8ff180032a8a87554 [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
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -080022#include <dlfcn.h>
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080023#include <algorithm>
Chia-I Wuff4a6c72016-03-24 16:05:56 +080024#include <array>
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>
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080030#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
31#include <configstore/Utils.h>
Jesse Hall53457db2016-12-14 16:54:06 -080032#include <cutils/properties.h>
Jiyong Park27c39e12017-05-08 13:00:02 +090033#include <graphicsenv/GraphicsEnv.h>
Chris Forbesfa25e632017-02-22 12:36:02 +130034#include <utils/Vector.h>
Jesse Hall53457db2016-12-14 16:54:06 -080035
Wei Wangf9b05ee2017-07-19 20:59:39 -070036#include "android-base/properties.h"
37
Chia-I Wu9d518162016-03-24 14:55:27 +080038#include "driver.h"
Jesse Hallb7c4e3b2016-04-11 13:51:38 -070039#include "stubhal.h"
Chia-I Wu9d518162016-03-24 14:55:27 +080040
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -080041using namespace android::hardware::configstore;
42using namespace android::hardware::configstore::V1_0;
43
Jesse Hall00e61ff2017-04-07 16:48:02 -070044// TODO(b/37049319) Get this from a header once one exists
45extern "C" {
46android_namespace_t* android_get_exported_namespace(const char*);
47}
48
Chia-I Wudbb7e9c2016-03-24 15:09:38 +080049// #define ENABLE_ALLOC_CALLSTACKS 1
50#if ENABLE_ALLOC_CALLSTACKS
51#include <utils/CallStack.h>
52#define ALOGD_CALLSTACK(...) \
53 do { \
54 ALOGD(__VA_ARGS__); \
55 android::CallStack callstack; \
56 callstack.update(); \
57 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
58 } while (false)
59#else
60#define ALOGD_CALLSTACK(...) \
61 do { \
62 } while (false)
63#endif
64
Chia-I Wu9d518162016-03-24 14:55:27 +080065namespace vulkan {
66namespace driver {
67
Chia-I Wu136b8eb2016-03-24 15:01:52 +080068namespace {
69
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080070class Hal {
71 public:
72 static bool Open();
73
74 static const Hal& Get() { return hal_; }
75 static const hwvulkan_device_t& Device() { return *Get().dev_; }
76
Chia-I Wu31938252016-05-23 15:31:02 +080077 int GetDebugReportIndex() const { return debug_report_index_; }
78
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080079 private:
Chia-I Wu31938252016-05-23 15:31:02 +080080 Hal() : dev_(nullptr), debug_report_index_(-1) {}
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080081 Hal(const Hal&) = delete;
82 Hal& operator=(const Hal&) = delete;
83
Chia-I Wu31938252016-05-23 15:31:02 +080084 bool InitDebugReportIndex();
85
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080086 static Hal hal_;
87
88 const hwvulkan_device_t* dev_;
Chia-I Wu31938252016-05-23 15:31:02 +080089 int debug_report_index_;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080090};
91
Chia-I Wu4901db72016-03-24 16:38:58 +080092class CreateInfoWrapper {
93 public:
Chia-I Wu31b2e4f2016-05-23 10:47:57 +080094 CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +080095 const VkAllocationCallbacks& allocator);
Chia-I Wu4901db72016-03-24 16:38:58 +080096 CreateInfoWrapper(VkPhysicalDevice physical_dev,
97 const VkDeviceCreateInfo& create_info,
98 const VkAllocationCallbacks& allocator);
99 ~CreateInfoWrapper();
100
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800101 VkResult Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800102
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800103 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
104 const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800105
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800106 explicit operator const VkInstanceCreateInfo*() const;
Chia-I Wu4901db72016-03-24 16:38:58 +0800107 explicit operator const VkDeviceCreateInfo*() const;
108
109 private:
110 struct ExtensionFilter {
111 VkExtensionProperties* exts;
112 uint32_t ext_count;
113
114 const char** names;
115 uint32_t name_count;
116 };
117
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800118 VkResult SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800119
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800120 VkResult SanitizeLayers();
121 VkResult SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800122
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800123 VkResult QueryExtensionCount(uint32_t& count) const;
124 VkResult EnumerateExtensions(uint32_t& count,
125 VkExtensionProperties* props) const;
126 VkResult InitExtensionFilter();
127 void FilterExtension(const char* name);
Chia-I Wu4901db72016-03-24 16:38:58 +0800128
129 const bool is_instance_;
130 const VkAllocationCallbacks& allocator_;
131
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800132 VkPhysicalDevice physical_dev_;
Chia-I Wu4901db72016-03-24 16:38:58 +0800133
134 union {
135 VkInstanceCreateInfo instance_info_;
136 VkDeviceCreateInfo dev_info_;
137 };
138
139 ExtensionFilter extension_filter_;
140
141 std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
142 std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_;
143};
144
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800145Hal Hal::hal_;
146
Jesse Hall53457db2016-12-14 16:54:06 -0800147void* LoadLibrary(const android_dlextinfo& dlextinfo,
148 const char* subname,
149 int subname_len) {
150 const char kLibFormat[] = "vulkan.%*s.so";
151 char* name = static_cast<char*>(
152 alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
153 sprintf(name, kLibFormat, subname_len, subname);
154 return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
155}
156
157const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
158 "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
159 "ro.board.platform",
160}};
161
Jesse Hall00e61ff2017-04-07 16:48:02 -0700162int LoadDriver(android_namespace_t* library_namespace,
163 const hwvulkan_module_t** module) {
Jesse Hall53457db2016-12-14 16:54:06 -0800164 const android_dlextinfo dlextinfo = {
165 .flags = ANDROID_DLEXT_USE_NAMESPACE,
Jesse Hall00e61ff2017-04-07 16:48:02 -0700166 .library_namespace = library_namespace,
Jesse Hall53457db2016-12-14 16:54:06 -0800167 };
Jesse Hall53457db2016-12-14 16:54:06 -0800168 void* so = nullptr;
169 char prop[PROPERTY_VALUE_MAX];
170 for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
171 int prop_len = property_get(key, prop, nullptr);
172 if (prop_len > 0) {
173 so = LoadLibrary(dlextinfo, prop, prop_len);
174 if (so)
175 break;
176 }
177 }
178 if (!so)
179 return -ENOENT;
180
Jesse Hall00e61ff2017-04-07 16:48:02 -0700181 auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
Jesse Hall53457db2016-12-14 16:54:06 -0800182 if (!hmi) {
183 ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
184 dlclose(so);
185 return -EINVAL;
186 }
187 if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
188 ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
189 dlclose(so);
190 return -EINVAL;
191 }
192 hmi->dso = so;
Jesse Hall00e61ff2017-04-07 16:48:02 -0700193 *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
Jesse Hall53457db2016-12-14 16:54:06 -0800194 return 0;
195}
196
Jesse Hall00e61ff2017-04-07 16:48:02 -0700197int LoadBuiltinDriver(const hwvulkan_module_t** module) {
198 auto ns = android_get_exported_namespace("sphal");
199 if (!ns)
200 return -ENOENT;
201 return LoadDriver(ns, module);
202}
203
204int LoadUpdatedDriver(const hwvulkan_module_t** module) {
205 auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
206 if (!ns)
207 return -ENOENT;
208 return LoadDriver(ns, module);
209}
210
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800211bool Hal::Open() {
Jesse Halldc225072016-05-30 22:40:14 -0700212 ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800213
214 // Use a stub device unless we successfully open a real HAL device.
215 hal_.dev_ = &stubhal::kDevice;
216
Jesse Hall53457db2016-12-14 16:54:06 -0800217 int result;
218 const hwvulkan_module_t* module = nullptr;
219
Jesse Hall00e61ff2017-04-07 16:48:02 -0700220 result = LoadUpdatedDriver(&module);
Jesse Hall53457db2016-12-14 16:54:06 -0800221 if (result == -ENOENT) {
Jesse Hall00e61ff2017-04-07 16:48:02 -0700222 result = LoadBuiltinDriver(&module);
223 if (result != 0) {
224 // -ENOENT means the sphal namespace doesn't exist, not that there
225 // is a problem with the driver.
226 ALOGW_IF(
227 result != -ENOENT,
228 "Failed to load Vulkan driver into sphal namespace. This "
229 "usually means the driver has forbidden library dependencies."
230 "Please fix, this will soon stop working.");
231 result =
232 hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
233 reinterpret_cast<const hw_module_t**>(&module));
234 }
Jesse Hall53457db2016-12-14 16:54:06 -0800235 }
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800236 if (result != 0) {
Jesse Hall53457db2016-12-14 16:54:06 -0800237 ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800238 return true;
239 }
240
241 hwvulkan_device_t* device;
242 result =
243 module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
244 reinterpret_cast<hw_device_t**>(&device));
245 if (result != 0) {
246 // Any device with a Vulkan HAL should be able to open the device.
247 ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
248 result);
249 return false;
250 }
251
252 hal_.dev_ = device;
253
Chia-I Wu31938252016-05-23 15:31:02 +0800254 hal_.InitDebugReportIndex();
255
256 return true;
257}
258
259bool Hal::InitDebugReportIndex() {
260 uint32_t count;
261 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
262 VK_SUCCESS) {
263 ALOGE("failed to get HAL instance extension count");
264 return false;
265 }
266
267 VkExtensionProperties* exts = reinterpret_cast<VkExtensionProperties*>(
268 malloc(sizeof(VkExtensionProperties) * count));
269 if (!exts) {
270 ALOGE("failed to allocate HAL instance extension array");
271 return false;
272 }
273
274 if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, exts) !=
275 VK_SUCCESS) {
276 ALOGE("failed to enumerate HAL instance extensions");
277 free(exts);
278 return false;
279 }
280
281 for (uint32_t i = 0; i < count; i++) {
282 if (strcmp(exts[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
283 0) {
284 debug_report_index_ = static_cast<int>(i);
285 break;
286 }
287 }
288
289 free(exts);
290
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800291 return true;
292}
293
294CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800295 const VkAllocationCallbacks& allocator)
296 : is_instance_(true),
297 allocator_(allocator),
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800298 physical_dev_(VK_NULL_HANDLE),
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800299 instance_info_(create_info),
300 extension_filter_() {
301 hook_extensions_.set(ProcHook::EXTENSION_CORE);
302 hal_extensions_.set(ProcHook::EXTENSION_CORE);
303}
304
Chia-I Wu4901db72016-03-24 16:38:58 +0800305CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
306 const VkDeviceCreateInfo& create_info,
307 const VkAllocationCallbacks& allocator)
308 : is_instance_(false),
309 allocator_(allocator),
310 physical_dev_(physical_dev),
311 dev_info_(create_info),
312 extension_filter_() {
313 hook_extensions_.set(ProcHook::EXTENSION_CORE);
314 hal_extensions_.set(ProcHook::EXTENSION_CORE);
315}
316
317CreateInfoWrapper::~CreateInfoWrapper() {
318 allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts);
319 allocator_.pfnFree(allocator_.pUserData, extension_filter_.names);
320}
321
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800322VkResult CreateInfoWrapper::Validate() {
323 VkResult result = SanitizePNext();
Chia-I Wu4901db72016-03-24 16:38:58 +0800324 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800325 result = SanitizeLayers();
Chia-I Wu4901db72016-03-24 16:38:58 +0800326 if (result == VK_SUCCESS)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800327 result = SanitizeExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800328
329 return result;
330}
331
332const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800333CreateInfoWrapper::GetHookExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800334 return hook_extensions_;
335}
336
337const std::bitset<ProcHook::EXTENSION_COUNT>&
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800338CreateInfoWrapper::GetHalExtensions() const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800339 return hal_extensions_;
340}
341
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800342CreateInfoWrapper::operator const VkInstanceCreateInfo*() const {
343 return &instance_info_;
344}
345
Chia-I Wu4901db72016-03-24 16:38:58 +0800346CreateInfoWrapper::operator const VkDeviceCreateInfo*() const {
347 return &dev_info_;
348}
349
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800350VkResult CreateInfoWrapper::SanitizePNext() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800351 const struct StructHeader {
352 VkStructureType type;
353 const void* next;
354 } * header;
355
356 if (is_instance_) {
357 header = reinterpret_cast<const StructHeader*>(instance_info_.pNext);
358
359 // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs
360 while (header &&
361 header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)
362 header = reinterpret_cast<const StructHeader*>(header->next);
363
364 instance_info_.pNext = header;
365 } else {
366 header = reinterpret_cast<const StructHeader*>(dev_info_.pNext);
367
368 // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs
369 while (header &&
370 header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)
371 header = reinterpret_cast<const StructHeader*>(header->next);
372
373 dev_info_.pNext = header;
374 }
375
376 return VK_SUCCESS;
377}
378
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800379VkResult CreateInfoWrapper::SanitizeLayers() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800380 auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames
381 : dev_info_.ppEnabledLayerNames;
382 auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount
383 : dev_info_.enabledLayerCount;
384
385 // remove all layers
386 layer_names = nullptr;
387 layer_count = 0;
388
389 return VK_SUCCESS;
390}
391
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800392VkResult CreateInfoWrapper::SanitizeExtensions() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800393 auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames
394 : dev_info_.ppEnabledExtensionNames;
395 auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
396 : dev_info_.enabledExtensionCount;
397 if (!ext_count)
398 return VK_SUCCESS;
399
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800400 VkResult result = InitExtensionFilter();
Chia-I Wu4901db72016-03-24 16:38:58 +0800401 if (result != VK_SUCCESS)
402 return result;
403
404 for (uint32_t i = 0; i < ext_count; i++)
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800405 FilterExtension(ext_names[i]);
Chia-I Wu4901db72016-03-24 16:38:58 +0800406
407 ext_names = extension_filter_.names;
408 ext_count = extension_filter_.name_count;
409
410 return VK_SUCCESS;
411}
412
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800413VkResult CreateInfoWrapper::QueryExtensionCount(uint32_t& count) const {
Chia-I Wu4901db72016-03-24 16:38:58 +0800414 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800415 return Hal::Device().EnumerateInstanceExtensionProperties(
416 nullptr, &count, nullptr);
Chia-I Wu4901db72016-03-24 16:38:58 +0800417 } else {
418 const auto& driver = GetData(physical_dev_).driver;
419 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
420 &count, nullptr);
421 }
422}
423
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800424VkResult CreateInfoWrapper::EnumerateExtensions(
Chia-I Wu4901db72016-03-24 16:38:58 +0800425 uint32_t& count,
426 VkExtensionProperties* props) const {
427 if (is_instance_) {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800428 return Hal::Device().EnumerateInstanceExtensionProperties(
429 nullptr, &count, props);
Chia-I Wu4901db72016-03-24 16:38:58 +0800430 } else {
431 const auto& driver = GetData(physical_dev_).driver;
432 return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr,
433 &count, props);
434 }
435}
436
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800437VkResult CreateInfoWrapper::InitExtensionFilter() {
Chia-I Wu4901db72016-03-24 16:38:58 +0800438 // query extension count
439 uint32_t count;
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800440 VkResult result = QueryExtensionCount(count);
Chia-I Wu4901db72016-03-24 16:38:58 +0800441 if (result != VK_SUCCESS || count == 0)
442 return result;
443
444 auto& filter = extension_filter_;
445 filter.exts =
446 reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation(
447 allocator_.pUserData, sizeof(VkExtensionProperties) * count,
448 alignof(VkExtensionProperties),
449 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
450 if (!filter.exts)
451 return VK_ERROR_OUT_OF_HOST_MEMORY;
452
453 // enumerate extensions
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800454 result = EnumerateExtensions(count, filter.exts);
Chia-I Wu4901db72016-03-24 16:38:58 +0800455 if (result != VK_SUCCESS && result != VK_INCOMPLETE)
456 return result;
457
458 if (!count)
459 return VK_SUCCESS;
460
461 filter.ext_count = count;
462
463 // allocate name array
464 uint32_t enabled_ext_count = (is_instance_)
465 ? instance_info_.enabledExtensionCount
466 : dev_info_.enabledExtensionCount;
467 count = std::min(filter.ext_count, enabled_ext_count);
468 filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
469 allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
470 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
471 if (!filter.names)
472 return VK_ERROR_OUT_OF_HOST_MEMORY;
473
474 return VK_SUCCESS;
475}
476
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800477void CreateInfoWrapper::FilterExtension(const char* name) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800478 auto& filter = extension_filter_;
479
480 ProcHook::Extension ext_bit = GetProcHookExtension(name);
481 if (is_instance_) {
482 switch (ext_bit) {
483 case ProcHook::KHR_android_surface:
484 case ProcHook::KHR_surface:
Courtney Goeltzenleuchtere278daf2017-02-02 16:54:57 -0700485 case ProcHook::EXT_swapchain_colorspace:
Chris Forbes2452cf72017-03-16 16:30:17 +1300486 case ProcHook::KHR_get_surface_capabilities2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800487 hook_extensions_.set(ext_bit);
488 // return now as these extensions do not require HAL support
489 return;
490 case ProcHook::EXT_debug_report:
491 // both we and HAL can take part in
492 hook_extensions_.set(ext_bit);
493 break;
494 case ProcHook::EXTENSION_UNKNOWN:
Chris Forbes6aa30db2017-02-20 17:12:53 +1300495 case ProcHook::KHR_get_physical_device_properties2:
Chia-I Wu4901db72016-03-24 16:38:58 +0800496 // HAL's extensions
497 break;
498 default:
499 ALOGW("Ignored invalid instance extension %s", name);
500 return;
501 }
502 } else {
503 switch (ext_bit) {
504 case ProcHook::KHR_swapchain:
505 // map VK_KHR_swapchain to VK_ANDROID_native_buffer
506 name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
507 ext_bit = ProcHook::ANDROID_native_buffer;
508 break;
Ian Elliott9e853732017-02-03 11:24:07 -0700509 case ProcHook::KHR_incremental_present:
Ian Elliott8a977262017-01-19 09:05:58 -0700510 case ProcHook::GOOGLE_display_timing:
Chris Forbesfa25e632017-02-22 12:36:02 +1300511 case ProcHook::KHR_shared_presentable_image:
Ian Elliott8a977262017-01-19 09:05:58 -0700512 hook_extensions_.set(ext_bit);
513 // return now as these extensions do not require HAL support
514 return;
Courtney Goeltzenleuchterd634c482017-01-05 15:55:31 -0700515 case ProcHook::EXT_hdr_metadata:
516 hook_extensions_.set(ext_bit);
517 break;
Chia-I Wu4901db72016-03-24 16:38:58 +0800518 case ProcHook::EXTENSION_UNKNOWN:
519 // HAL's extensions
520 break;
521 default:
522 ALOGW("Ignored invalid device extension %s", name);
523 return;
524 }
525 }
526
527 for (uint32_t i = 0; i < filter.ext_count; i++) {
528 const VkExtensionProperties& props = filter.exts[i];
529 // ignore unknown extensions
530 if (strcmp(name, props.extensionName) != 0)
531 continue;
532
Chia-I Wu4901db72016-03-24 16:38:58 +0800533 filter.names[filter.name_count++] = name;
Chia-I Wu1600e262016-04-12 09:40:06 +0800534 if (ext_bit != ProcHook::EXTENSION_UNKNOWN) {
535 if (ext_bit == ProcHook::ANDROID_native_buffer)
536 hook_extensions_.set(ProcHook::KHR_swapchain);
537
538 hal_extensions_.set(ext_bit);
539 }
Chia-I Wu4901db72016-03-24 16:38:58 +0800540
541 break;
542 }
543}
544
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800545VKAPI_ATTR void* DefaultAllocate(void*,
546 size_t size,
547 size_t alignment,
548 VkSystemAllocationScope) {
549 void* ptr = nullptr;
550 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
551 // additionally requires that it be at least sizeof(void*).
552 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
553 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
554 ret, ptr);
555 return ret == 0 ? ptr : nullptr;
556}
557
558VKAPI_ATTR void* DefaultReallocate(void*,
559 void* ptr,
560 size_t size,
561 size_t alignment,
562 VkSystemAllocationScope) {
563 if (size == 0) {
564 free(ptr);
565 return nullptr;
566 }
567
568 // TODO(jessehall): Right now we never shrink allocations; if the new
569 // request is smaller than the existing chunk, we just continue using it.
570 // Right now the loader never reallocs, so this doesn't matter. If that
571 // changes, or if this code is copied into some other project, this should
572 // probably have a heuristic to allocate-copy-free when doing so will save
573 // "enough" space.
574 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
575 if (size <= old_size)
576 return ptr;
577
578 void* new_ptr = nullptr;
579 if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
580 return nullptr;
581 if (ptr) {
582 memcpy(new_ptr, ptr, std::min(old_size, size));
583 free(ptr);
584 }
585 return new_ptr;
586}
587
588VKAPI_ATTR void DefaultFree(void*, void* ptr) {
589 ALOGD_CALLSTACK("Free: %p", ptr);
590 free(ptr);
591}
592
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800593InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) {
594 void* data_mem = allocator.pfnAllocation(
595 allocator.pUserData, sizeof(InstanceData), alignof(InstanceData),
596 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
597 if (!data_mem)
598 return nullptr;
599
600 return new (data_mem) InstanceData(allocator);
601}
602
603void FreeInstanceData(InstanceData* data,
604 const VkAllocationCallbacks& allocator) {
605 data->~InstanceData();
606 allocator.pfnFree(allocator.pUserData, data);
607}
608
Chia-I Wu950d6e12016-05-03 09:12:35 +0800609DeviceData* AllocateDeviceData(
610 const VkAllocationCallbacks& allocator,
611 const DebugReportCallbackList& debug_report_callbacks) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800612 void* data_mem = allocator.pfnAllocation(
613 allocator.pUserData, sizeof(DeviceData), alignof(DeviceData),
614 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
615 if (!data_mem)
616 return nullptr;
617
Chia-I Wu950d6e12016-05-03 09:12:35 +0800618 return new (data_mem) DeviceData(allocator, debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800619}
620
621void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) {
622 data->~DeviceData();
623 allocator.pfnFree(allocator.pUserData, data);
624}
625
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800626} // anonymous namespace
627
Chia-I Wu9d518162016-03-24 14:55:27 +0800628bool Debuggable() {
629 return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
630}
631
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800632bool OpenHAL() {
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800633 return Hal::Open();
Chia-I Wu136b8eb2016-03-24 15:01:52 +0800634}
635
Chia-I Wudbb7e9c2016-03-24 15:09:38 +0800636const VkAllocationCallbacks& GetDefaultAllocator() {
637 static const VkAllocationCallbacks kDefaultAllocCallbacks = {
638 .pUserData = nullptr,
639 .pfnAllocation = DefaultAllocate,
640 .pfnReallocation = DefaultReallocate,
641 .pfnFree = DefaultFree,
642 };
643
644 return kDefaultAllocCallbacks;
645}
646
Chia-I Wueb7db122016-03-24 09:11:06 +0800647PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
648 const ProcHook* hook = GetProcHook(pName);
649 if (!hook)
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800650 return Hal::Device().GetInstanceProcAddr(instance, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800651
652 if (!instance) {
653 if (hook->type == ProcHook::GLOBAL)
654 return hook->proc;
655
Chia-I Wu109f8982016-04-22 06:40:40 +0800656 // v0 layers expect
657 //
658 // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
659 //
660 // to work.
661 if (strcmp(pName, "vkCreateDevice") == 0)
662 return hook->proc;
663
Chia-I Wueb7db122016-03-24 09:11:06 +0800664 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800665 "internal vkGetInstanceProcAddr called for %s without an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800666 pName);
667
Chia-I Wu109f8982016-04-22 06:40:40 +0800668 return nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800669 }
670
671 PFN_vkVoidFunction proc;
672
673 switch (hook->type) {
674 case ProcHook::INSTANCE:
675 proc = (GetData(instance).hook_extensions[hook->extension])
676 ? hook->proc
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800677 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800678 break;
679 case ProcHook::DEVICE:
680 proc = (hook->extension == ProcHook::EXTENSION_CORE)
681 ? hook->proc
682 : hook->checked_proc;
683 break;
684 default:
685 ALOGE(
Chia-I Wue201c3f2016-05-03 13:26:08 +0800686 "internal vkGetInstanceProcAddr called for %s with an instance",
Chia-I Wueb7db122016-03-24 09:11:06 +0800687 pName);
688 proc = nullptr;
689 break;
690 }
691
692 return proc;
693}
694
695PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
696 const ProcHook* hook = GetProcHook(pName);
697 if (!hook)
Chia-I Wucc5e2762016-03-24 13:01:16 +0800698 return GetData(device).driver.GetDeviceProcAddr(device, pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800699
700 if (hook->type != ProcHook::DEVICE) {
Chia-I Wue201c3f2016-05-03 13:26:08 +0800701 ALOGE("internal vkGetDeviceProcAddr called for %s", pName);
Chia-I Wueb7db122016-03-24 09:11:06 +0800702 return nullptr;
703 }
704
Chia-I Wu36cc00a2016-04-13 16:52:06 +0800705 return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
706 : nullptr;
Chia-I Wueb7db122016-03-24 09:11:06 +0800707}
708
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800709VkResult EnumerateInstanceExtensionProperties(
710 const char* pLayerName,
711 uint32_t* pPropertyCount,
712 VkExtensionProperties* pProperties) {
Ian Elliott34a327b2017-03-28 13:20:35 -0600713
714 android::Vector<VkExtensionProperties> loader_extensions;
715 loader_extensions.push_back({
716 VK_KHR_SURFACE_EXTENSION_NAME,
717 VK_KHR_SURFACE_SPEC_VERSION});
718 loader_extensions.push_back({
719 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
720 VK_KHR_ANDROID_SURFACE_SPEC_VERSION});
721 loader_extensions.push_back({
722 VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
723 VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION});
Chris Forbes16095002017-05-05 15:33:29 -0700724 loader_extensions.push_back({
725 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
726 VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION});
Ian Elliott34a327b2017-03-28 13:20:35 -0600727
Chia-I Wu31938252016-05-23 15:31:02 +0800728 static const VkExtensionProperties loader_debug_report_extension = {
729 VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
730 };
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800731
732 // enumerate our extensions first
733 if (!pLayerName && pProperties) {
734 uint32_t count = std::min(
735 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
736
737 std::copy_n(loader_extensions.begin(), count, pProperties);
738
739 if (count < loader_extensions.size()) {
740 *pPropertyCount = count;
741 return VK_INCOMPLETE;
742 }
743
744 pProperties += count;
745 *pPropertyCount -= count;
Chia-I Wu31938252016-05-23 15:31:02 +0800746
747 if (Hal::Get().GetDebugReportIndex() < 0) {
748 if (!*pPropertyCount) {
749 *pPropertyCount = count;
750 return VK_INCOMPLETE;
751 }
752
753 pProperties[0] = loader_debug_report_extension;
754 pProperties += 1;
755 *pPropertyCount -= 1;
756 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800757 }
758
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800759 VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800760 pLayerName, pPropertyCount, pProperties);
761
Chia-I Wu31938252016-05-23 15:31:02 +0800762 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
763 int idx = Hal::Get().GetDebugReportIndex();
764 if (idx < 0) {
765 *pPropertyCount += 1;
766 } else if (pProperties &&
767 static_cast<uint32_t>(idx) < *pPropertyCount) {
768 pProperties[idx].specVersion =
769 std::min(pProperties[idx].specVersion,
770 loader_debug_report_extension.specVersion);
771 }
772
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800773 *pPropertyCount += loader_extensions.size();
Chia-I Wu31938252016-05-23 15:31:02 +0800774 }
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800775
776 return result;
777}
778
Chris Forbesfa25e632017-02-22 12:36:02 +1300779bool QueryPresentationProperties(
780 VkPhysicalDevice physicalDevice,
781 VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties)
782{
783 const InstanceData& data = GetData(physicalDevice);
784
785 // GPDP2 must be present and enabled on the instance.
786 if (!data.driver.GetPhysicalDeviceProperties2KHR)
787 return false;
788
789 // Request the android-specific presentation properties via GPDP2
790 VkPhysicalDeviceProperties2KHR properties = {
791 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
792 presentation_properties,
793 {}
794 };
795
796#pragma clang diagnostic push
797#pragma clang diagnostic ignored "-Wold-style-cast"
798 presentation_properties->sType =
799 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID;
800#pragma clang diagnostic pop
801 presentation_properties->pNext = nullptr;
802 presentation_properties->sharedImage = VK_FALSE;
803
804 data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
805 &properties);
806
807 return true;
808}
809
Chia-I Wu01cf3052016-03-24 16:16:21 +0800810VkResult EnumerateDeviceExtensionProperties(
811 VkPhysicalDevice physicalDevice,
812 const char* pLayerName,
813 uint32_t* pPropertyCount,
814 VkExtensionProperties* pProperties) {
815 const InstanceData& data = GetData(physicalDevice);
Chris Forbesfa25e632017-02-22 12:36:02 +1300816 // extensions that are unconditionally exposed by the loader
817 android::Vector<VkExtensionProperties> loader_extensions;
818 loader_extensions.push_back({
819 VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
820 VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300821
Courtney Goeltzenleuchter7671d462018-01-24 11:51:01 -0800822 bool hdrBoardConfig =
823 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
824 false);
825 if (hdrBoardConfig) {
826 loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
827 VK_EXT_HDR_METADATA_SPEC_VERSION});
828 }
829
Chris Forbes16095002017-05-05 15:33:29 -0700830 VkPhysicalDevicePresentationPropertiesANDROID presentation_properties;
831 if (QueryPresentationProperties(physicalDevice, &presentation_properties) &&
832 presentation_properties.sharedImage) {
833 loader_extensions.push_back({
834 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
835 VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION});
Chris Forbesfa25e632017-02-22 12:36:02 +1300836 }
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700837
Ian Elliott5c34de22017-04-10 14:42:30 -0600838 // conditionally add VK_GOOGLE_display_timing if present timestamps are
839 // supported by the driver:
Wei Wangf9b05ee2017-07-19 20:59:39 -0700840 const std::string timestamp_property("service.sf.present_timestamp");
841 android::base::WaitForPropertyCreation(timestamp_property);
842 if (android::base::GetBoolProperty(timestamp_property, true)) {
Ian Elliott5c34de22017-04-10 14:42:30 -0600843 loader_extensions.push_back({
844 VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
845 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
846 }
847
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700848 // enumerate our extensions first
849 if (!pLayerName && pProperties) {
850 uint32_t count = std::min(
851 *pPropertyCount, static_cast<uint32_t>(loader_extensions.size()));
852
853 std::copy_n(loader_extensions.begin(), count, pProperties);
854
855 if (count < loader_extensions.size()) {
856 *pPropertyCount = count;
857 return VK_INCOMPLETE;
858 }
859
860 pProperties += count;
861 *pPropertyCount -= count;
862 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800863
864 VkResult result = data.driver.EnumerateDeviceExtensionProperties(
865 physicalDevice, pLayerName, pPropertyCount, pProperties);
Chia-I Wu01cf3052016-03-24 16:16:21 +0800866
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700867 if (pProperties) {
868 // map VK_ANDROID_native_buffer to VK_KHR_swapchain
869 for (uint32_t i = 0; i < *pPropertyCount; i++) {
870 auto& prop = pProperties[i];
Chia-I Wu01cf3052016-03-24 16:16:21 +0800871
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700872 if (strcmp(prop.extensionName,
873 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
874 continue;
Chia-I Wu01cf3052016-03-24 16:16:21 +0800875
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700876 memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
877 sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
878 prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
879 }
880 }
Chia-I Wu01cf3052016-03-24 16:16:21 +0800881
Ian Elliottd4b50aa2017-01-09 16:21:36 -0700882 // restore loader extension count
883 if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
884 *pPropertyCount += loader_extensions.size();
Chia-I Wu01cf3052016-03-24 16:16:21 +0800885 }
886
887 return result;
888}
889
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800890VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
891 const VkAllocationCallbacks* pAllocator,
892 VkInstance* pInstance) {
893 const VkAllocationCallbacks& data_allocator =
894 (pAllocator) ? *pAllocator : GetDefaultAllocator();
895
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800896 CreateInfoWrapper wrapper(*pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800897 VkResult result = wrapper.Validate();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800898 if (result != VK_SUCCESS)
899 return result;
900
901 InstanceData* data = AllocateInstanceData(data_allocator);
902 if (!data)
903 return VK_ERROR_OUT_OF_HOST_MEMORY;
904
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800905 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800906
907 // call into the driver
908 VkInstance instance;
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800909 result = Hal::Device().CreateInstance(
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800910 static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
911 &instance);
912 if (result != VK_SUCCESS) {
913 FreeInstanceData(data, data_allocator);
914 return result;
915 }
916
917 // initialize InstanceDriverTable
918 if (!SetData(instance, *data) ||
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800919 !InitDriverTable(instance, Hal::Device().GetInstanceProcAddr,
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800920 wrapper.GetHalExtensions())) {
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800921 data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800922 Hal::Device().GetInstanceProcAddr(instance, "vkDestroyInstance"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800923 if (data->driver.DestroyInstance)
924 data->driver.DestroyInstance(instance, pAllocator);
925
926 FreeInstanceData(data, data_allocator);
927
928 return VK_ERROR_INCOMPATIBLE_DRIVER;
929 }
930
931 data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Chia-I Wu31b2e4f2016-05-23 10:47:57 +0800932 Hal::Device().GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"));
Chia-I Wuff4a6c72016-03-24 16:05:56 +0800933 if (!data->get_device_proc_addr) {
934 data->driver.DestroyInstance(instance, pAllocator);
935 FreeInstanceData(data, data_allocator);
936
937 return VK_ERROR_INCOMPATIBLE_DRIVER;
938 }
939
940 *pInstance = instance;
941
942 return VK_SUCCESS;
943}
944
945void DestroyInstance(VkInstance instance,
946 const VkAllocationCallbacks* pAllocator) {
947 InstanceData& data = GetData(instance);
948 data.driver.DestroyInstance(instance, pAllocator);
949
950 VkAllocationCallbacks local_allocator;
951 if (!pAllocator) {
952 local_allocator = data.allocator;
953 pAllocator = &local_allocator;
954 }
955
956 FreeInstanceData(&data, *pAllocator);
957}
958
Chia-I Wu4901db72016-03-24 16:38:58 +0800959VkResult CreateDevice(VkPhysicalDevice physicalDevice,
960 const VkDeviceCreateInfo* pCreateInfo,
961 const VkAllocationCallbacks* pAllocator,
962 VkDevice* pDevice) {
963 const InstanceData& instance_data = GetData(physicalDevice);
964 const VkAllocationCallbacks& data_allocator =
965 (pAllocator) ? *pAllocator : instance_data.allocator;
966
967 CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator);
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800968 VkResult result = wrapper.Validate();
Chia-I Wu4901db72016-03-24 16:38:58 +0800969 if (result != VK_SUCCESS)
970 return result;
971
Chia-I Wu950d6e12016-05-03 09:12:35 +0800972 DeviceData* data = AllocateDeviceData(data_allocator,
973 instance_data.debug_report_callbacks);
Chia-I Wu4901db72016-03-24 16:38:58 +0800974 if (!data)
975 return VK_ERROR_OUT_OF_HOST_MEMORY;
976
Chia-I Wu3e6c2d62016-04-11 13:55:56 +0800977 data->hook_extensions |= wrapper.GetHookExtensions();
Chia-I Wu4901db72016-03-24 16:38:58 +0800978
979 // call into the driver
980 VkDevice dev;
981 result = instance_data.driver.CreateDevice(
982 physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
983 pAllocator, &dev);
984 if (result != VK_SUCCESS) {
985 FreeDeviceData(data, data_allocator);
986 return result;
987 }
988
989 // initialize DeviceDriverTable
990 if (!SetData(dev, *data) ||
Chia-I Wucbe07ef2016-04-13 15:01:00 +0800991 !InitDriverTable(dev, instance_data.get_device_proc_addr,
992 wrapper.GetHalExtensions())) {
Chia-I Wu4901db72016-03-24 16:38:58 +0800993 data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
994 instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
995 if (data->driver.DestroyDevice)
996 data->driver.DestroyDevice(dev, pAllocator);
997
998 FreeDeviceData(data, data_allocator);
999
1000 return VK_ERROR_INCOMPATIBLE_DRIVER;
1001 }
Chris Forbesd8277912017-02-10 14:59:59 +13001002
1003 // sanity check ANDROID_native_buffer implementation, whose set of
1004 // entrypoints varies according to the spec version.
1005 if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
1006 !data->driver.GetSwapchainGrallocUsageANDROID &&
1007 !data->driver.GetSwapchainGrallocUsage2ANDROID) {
1008 ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
1009 " must expose at least one of "
1010 "vkGetSwapchainGrallocUsageANDROID or "
1011 "vkGetSwapchainGrallocUsage2ANDROID");
1012
1013 data->driver.DestroyDevice(dev, pAllocator);
1014 FreeDeviceData(data, data_allocator);
1015
1016 return VK_ERROR_INCOMPATIBLE_DRIVER;
1017 }
1018
Jesse Hall85bb0c52017-02-09 22:13:02 -08001019 VkPhysicalDeviceProperties properties;
1020 instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
1021 &properties);
1022
Jesse Halldc225072016-05-30 22:40:14 -07001023 data->driver_device = dev;
Jesse Hall85bb0c52017-02-09 22:13:02 -08001024 data->driver_version = properties.driverVersion;
Chia-I Wu4901db72016-03-24 16:38:58 +08001025
1026 *pDevice = dev;
1027
1028 return VK_SUCCESS;
1029}
1030
1031void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
1032 DeviceData& data = GetData(device);
1033 data.driver.DestroyDevice(device, pAllocator);
1034
1035 VkAllocationCallbacks local_allocator;
1036 if (!pAllocator) {
1037 local_allocator = data.allocator;
1038 pAllocator = &local_allocator;
1039 }
1040
1041 FreeDeviceData(&data, *pAllocator);
1042}
1043
Chia-I Wuff4a6c72016-03-24 16:05:56 +08001044VkResult EnumeratePhysicalDevices(VkInstance instance,
1045 uint32_t* pPhysicalDeviceCount,
1046 VkPhysicalDevice* pPhysicalDevices) {
1047 const auto& data = GetData(instance);
1048
1049 VkResult result = data.driver.EnumeratePhysicalDevices(
1050 instance, pPhysicalDeviceCount, pPhysicalDevices);
1051 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) {
1052 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++)
1053 SetData(pPhysicalDevices[i], data);
1054 }
1055
1056 return result;
1057}
1058
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001059VkResult EnumeratePhysicalDeviceGroups(
1060 VkInstance instance,
1061 uint32_t* pPhysicalDeviceGroupCount,
1062 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001063 VkResult result = VK_SUCCESS;
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001064 const auto& data = GetData(instance);
1065
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001066 if (!data.driver.EnumeratePhysicalDeviceGroups) {
1067 uint32_t device_count = 0;
1068 result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
1069 if (result < 0)
1070 return result;
1071 if (!pPhysicalDeviceGroupProperties) {
1072 *pPhysicalDeviceGroupCount = device_count;
1073 return result;
1074 }
1075
1076 device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
1077 if (!device_count) {
1078 *pPhysicalDeviceGroupCount = 0;
1079 return result;
1080 }
1081
1082 android::Vector<VkPhysicalDevice> devices;
1083 devices.resize(device_count);
1084
1085 result = EnumeratePhysicalDevices(instance, &device_count,
1086 devices.editArray());
1087 if (result < 0)
1088 return result;
1089
1090 devices.resize(device_count);
1091 *pPhysicalDeviceGroupCount = device_count;
1092 for (uint32_t i = 0; i < device_count; ++i) {
1093 pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
1094 pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
1095 pPhysicalDeviceGroupProperties[i].subsetAllocation = 0;
1096 }
1097 } else {
1098 result = data.driver.EnumeratePhysicalDeviceGroups(
1099 instance, pPhysicalDeviceGroupCount,
1100 pPhysicalDeviceGroupProperties);
1101 if ((result == VK_SUCCESS || result == VK_INCOMPLETE) &&
1102 *pPhysicalDeviceGroupCount && pPhysicalDeviceGroupProperties) {
1103 for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
1104 for (uint32_t j = 0;
1105 j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount;
1106 j++) {
1107 SetData(
1108 pPhysicalDeviceGroupProperties[i].physicalDevices[j],
Ian Elliottcd8ad332017-10-13 09:21:12 -06001109 data);
Yiwei Zhang4cd9cc92018-01-08 17:55:50 -08001110 }
Ian Elliottcd8ad332017-10-13 09:21:12 -06001111 }
1112 }
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001113 }
1114
1115 return result;
1116}
1117
Chia-I Wuba0be412016-03-24 16:24:40 +08001118void GetDeviceQueue(VkDevice device,
1119 uint32_t queueFamilyIndex,
1120 uint32_t queueIndex,
1121 VkQueue* pQueue) {
1122 const auto& data = GetData(device);
1123
1124 data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
1125 SetData(*pQueue, data);
1126}
1127
Daniel Kochf25f5bb2017-10-05 00:26:58 -04001128void GetDeviceQueue2(VkDevice device,
1129 const VkDeviceQueueInfo2* pQueueInfo,
1130 VkQueue* pQueue) {
1131 const auto& data = GetData(device);
1132
1133 data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
1134 SetData(*pQueue, data);
1135}
1136
Chia-I Wu6a58a8a2016-03-24 16:29:51 +08001137VKAPI_ATTR VkResult
1138AllocateCommandBuffers(VkDevice device,
1139 const VkCommandBufferAllocateInfo* pAllocateInfo,
1140 VkCommandBuffer* pCommandBuffers) {
1141 const auto& data = GetData(device);
1142
1143 VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
1144 pCommandBuffers);
1145 if (result == VK_SUCCESS) {
1146 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++)
1147 SetData(pCommandBuffers[i], data);
1148 }
1149
1150 return result;
1151}
1152
Chia-I Wu9d518162016-03-24 14:55:27 +08001153} // namespace driver
1154} // namespace vulkan