blob: a44026f96dd2fce7710aaa6a8860ff6de14962bb [file] [log] [blame]
Jesse Halld02edcb2015-09-08 07:44:48 -07001/*
2 * Copyright 2015 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
Michael Lentine9dbe67f2015-09-16 15:53:50 -050017//#define LOG_NDEBUG 0
18
Jesse Hall04f4f472015-08-16 19:51:04 -070019// module header
20#include "loader.h"
21// standard C headers
Michael Lentine03c64b02015-08-26 18:27:26 -050022#include <dirent.h>
23#include <dlfcn.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070024#include <inttypes.h>
25#include <malloc.h>
26#include <pthread.h>
27#include <string.h>
28// standard C++ headers
29#include <algorithm>
30#include <mutex>
Michael Lentine03c64b02015-08-26 18:27:26 -050031#include <sstream>
32#include <string>
33#include <unordered_map>
34#include <vector>
Jesse Hall04f4f472015-08-16 19:51:04 -070035// platform/library headers
Michael Lentine03c64b02015-08-26 18:27:26 -050036#include <cutils/properties.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070037#include <hardware/hwvulkan.h>
38#include <log/log.h>
Michael Lentinecd6cabf2015-09-14 17:32:59 -050039#include <vulkan/vk_debug_report_lunarg.h>
Michael Lentine1c69b9e2015-09-14 13:26:59 -050040#include <vulkan/vulkan_loader_data.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070041
42using namespace vulkan;
43
44static const uint32_t kMaxPhysicalDevices = 4;
45
Michael Lentine03c64b02015-08-26 18:27:26 -050046namespace {
47
48// These definitions are taken from the LunarG Vulkan Loader. They are used to
49// enforce compatability between the Loader and Layers.
50typedef void* (*PFN_vkGetProcAddr)(void* obj, const char* pName);
51
52typedef struct VkLayerLinkedListElem_ {
53 PFN_vkGetProcAddr get_proc_addr;
54 void* next_element;
55 void* base_object;
56} VkLayerLinkedListElem;
57
58// Define Handle typedef to be void* as returned from dlopen.
59typedef void* SharedLibraryHandle;
60
61// Custom versions of std classes that use the vulkan alloc callback.
62template <class T>
63class CallbackAllocator {
64 public:
65 typedef T value_type;
66
67 CallbackAllocator(const VkAllocCallbacks* alloc_input)
68 : alloc(alloc_input) {}
69
70 template <class T2>
71 CallbackAllocator(const CallbackAllocator<T2>& other)
72 : alloc(other.alloc) {}
73
74 T* allocate(std::size_t n) {
75 void* mem = alloc->pfnAlloc(alloc->pUserData, n * sizeof(T), alignof(T),
76 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
77 return static_cast<T*>(mem);
78 }
79
80 void deallocate(T* array, std::size_t /*n*/) {
81 alloc->pfnFree(alloc->pUserData, array);
82 }
83
84 const VkAllocCallbacks* alloc;
85};
86// These are needed in order to move Strings
87template <class T>
88bool operator==(const CallbackAllocator<T>& alloc1,
89 const CallbackAllocator<T>& alloc2) {
90 return alloc1.alloc == alloc2.alloc;
91}
92template <class T>
93bool operator!=(const CallbackAllocator<T>& alloc1,
94 const CallbackAllocator<T>& alloc2) {
95 return !(alloc1 == alloc2);
96}
97
98template <class Key,
99 class T,
100 class Hash = std::hash<Key>,
101 class Pred = std::equal_to<Key> >
102using UnorderedMap =
103 std::unordered_map<Key,
104 T,
105 Hash,
106 Pred,
107 CallbackAllocator<std::pair<const Key, T> > >;
108
109template <class T>
110using Vector = std::vector<T, CallbackAllocator<T> >;
111
112typedef std::basic_string<char,
113 std::char_traits<char>,
114 CallbackAllocator<char> > String;
115
116} // namespace
117
118// -----------------------------------------------------------------------------
119
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500120namespace {
121
122struct LayerData {
123 String path;
124 SharedLibraryHandle handle;
125 uint32_t ref_count;
126};
127
128typedef UnorderedMap<String, LayerData>::iterator LayerMapIterator;
129
130} // namespace
131
Jesse Hall04f4f472015-08-16 19:51:04 -0700132struct VkInstance_T {
133 VkInstance_T(const VkAllocCallbacks* alloc_callbacks)
Michael Lentine03c64b02015-08-26 18:27:26 -0500134 : vtbl(&vtbl_storage),
135 alloc(alloc_callbacks),
136 num_physical_devices(0),
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500137 layers(CallbackAllocator<std::pair<String, LayerData> >(alloc)),
138 active_layers(CallbackAllocator<String>(alloc)) {
139 pthread_mutex_init(&layer_lock, 0);
Jesse Hall04f4f472015-08-16 19:51:04 -0700140 memset(&vtbl_storage, 0, sizeof(vtbl_storage));
141 memset(physical_devices, 0, sizeof(physical_devices));
142 memset(&drv.vtbl, 0, sizeof(drv.vtbl));
143 drv.GetDeviceProcAddr = nullptr;
144 drv.num_physical_devices = 0;
145 }
146
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500147 ~VkInstance_T() { pthread_mutex_destroy(&layer_lock); }
148
Jesse Hall04f4f472015-08-16 19:51:04 -0700149 InstanceVtbl* vtbl;
150 InstanceVtbl vtbl_storage;
151
152 const VkAllocCallbacks* alloc;
153 uint32_t num_physical_devices;
154 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
155
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500156 pthread_mutex_t layer_lock;
157 // Map of layer names to layer data
158 UnorderedMap<String, LayerData> layers;
159 // Vector of layers active for this instance
160 Vector<LayerMapIterator> active_layers;
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500161 VkDbgMsgCallback message;
Michael Lentine03c64b02015-08-26 18:27:26 -0500162
Jesse Hall04f4f472015-08-16 19:51:04 -0700163 struct Driver {
164 // Pointers to driver entry points. Used explicitly by the loader; not
165 // set as the dispatch table for any objects.
166 InstanceVtbl vtbl;
167
168 // Pointer to the driver's get_device_proc_addr, must be valid for any
169 // of the driver's physical devices. Not part of the InstanceVtbl since
170 // it's not an Instance/PhysicalDevice function.
171 PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
172
173 // Number of physical devices owned by this driver.
174 uint32_t num_physical_devices;
175 } drv; // may eventually be an array
176};
177
178// -----------------------------------------------------------------------------
179
180namespace {
181
182typedef VkInstance_T Instance;
183
184struct Device {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500185 Device(Instance* instance_input)
186 : instance(instance_input),
187 active_layers(CallbackAllocator<LayerMapIterator>(instance->alloc)) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700188 memset(&vtbl_storage, 0, sizeof(vtbl_storage));
189 vtbl_storage.device = this;
190 }
191 DeviceVtbl vtbl_storage;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500192 Instance* instance;
193 // Vector of layers active for this device
194 Vector<LayerMapIterator> active_layers;
Jesse Hall04f4f472015-08-16 19:51:04 -0700195};
196
197// -----------------------------------------------------------------------------
198// Utility Code
199
200inline const InstanceVtbl* GetVtbl(VkPhysicalDevice physicalDevice) {
201 return *reinterpret_cast<InstanceVtbl**>(physicalDevice);
202}
203
204inline const DeviceVtbl* GetVtbl(VkDevice device) {
205 return *reinterpret_cast<DeviceVtbl**>(device);
206}
Jesse Halld7b994a2015-09-07 14:17:37 -0700207inline const DeviceVtbl* GetVtbl(VkQueue queue) {
208 return *reinterpret_cast<DeviceVtbl**>(queue);
209}
Jesse Hall04f4f472015-08-16 19:51:04 -0700210
211void* DefaultAlloc(void*, size_t size, size_t alignment, VkSystemAllocType) {
212 return memalign(alignment, size);
213}
214
215void DefaultFree(void*, void* pMem) {
216 free(pMem);
217}
218
219const VkAllocCallbacks kDefaultAllocCallbacks = {
220 .pUserData = nullptr,
221 .pfnAlloc = DefaultAlloc,
222 .pfnFree = DefaultFree,
223};
224
225hwvulkan_device_t* g_hwdevice;
226bool EnsureInitialized() {
227 static std::once_flag once_flag;
228 static const hwvulkan_module_t* module;
229
230 std::call_once(once_flag, []() {
231 int result;
232 result = hw_get_module("vulkan",
233 reinterpret_cast<const hw_module_t**>(&module));
234 if (result != 0) {
235 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result),
236 result);
237 return;
238 }
239 result = module->common.methods->open(
240 &module->common, HWVULKAN_DEVICE_0,
241 reinterpret_cast<hw_device_t**>(&g_hwdevice));
242 if (result != 0) {
243 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
244 result);
245 module = nullptr;
246 return;
247 }
248 });
249
250 return module != nullptr && g_hwdevice != nullptr;
251}
252
253void DestroyDevice(Device* device) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500254 const VkAllocCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700255 device->~Device();
256 alloc->pfnFree(alloc->pUserData, device);
257}
258
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500259void FindLayersInDirectory(Instance& instance, const String& dir_name) {
Jesse Hall0ecdd3e2015-10-29 11:20:07 -0700260 DIR* directory = opendir(dir_name.c_str());
261 if (!directory) {
262 android_LogPriority log_priority =
263 (errno == ENOENT) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_ERROR;
264 LOG_PRI(log_priority, LOG_TAG,
265 "failed to open layer directory '%s': %s (%d)",
266 dir_name.c_str(), strerror(errno), errno);
267 return;
Michael Lentine03c64b02015-08-26 18:27:26 -0500268 }
Jesse Hall0ecdd3e2015-10-29 11:20:07 -0700269
270 Vector<VkLayerProperties> properties(
271 CallbackAllocator<VkLayerProperties>(instance.alloc));
272 struct dirent* entry;
273 while ((entry = readdir(directory))) {
274 size_t length = strlen(entry->d_name);
275 if (strncmp(entry->d_name, "libVKLayer", 10) != 0 ||
276 strncmp(entry->d_name + length - 3, ".so", 3) != 0)
277 continue;
278 // Open so
279 SharedLibraryHandle layer_handle =
280 dlopen((dir_name + entry->d_name).c_str(), RTLD_NOW | RTLD_LOCAL);
281 if (!layer_handle) {
282 ALOGE("%s failed to load with error %s; Skipping", entry->d_name,
283 dlerror());
284 continue;
285 }
286
287 // Get Layers in so
288 PFN_vkEnumerateInstanceLayerProperties get_layer_properties =
289 reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
290 dlsym(layer_handle, "vkEnumerateInstanceLayerProperties"));
291 if (!get_layer_properties) {
292 ALOGE(
293 "%s failed to find vkEnumerateInstanceLayerProperties with "
294 "error %s; Skipping",
295 entry->d_name, dlerror());
296 dlclose(layer_handle);
297 continue;
298 }
299 uint32_t count;
300 get_layer_properties(&count, nullptr);
301
302 properties.resize(count);
303 get_layer_properties(&count, &properties[0]);
304
305 // Add Layers to potential list
306 for (uint32_t i = 0; i < count; ++i) {
307 String layer_name(properties[i].layerName,
308 CallbackAllocator<char>(instance.alloc));
309 LayerData layer_data = {dir_name + entry->d_name, 0, 0};
310 instance.layers.insert(std::make_pair(layer_name, layer_data));
311 ALOGV("Found layer %s", properties[i].layerName);
312 }
313 dlclose(layer_handle);
314 }
315
316 closedir(directory);
Michael Lentine03c64b02015-08-26 18:27:26 -0500317}
318
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500319template <class TObject>
320void ActivateLayer(TObject* object, Instance* instance, const String& name) {
321 // If object has layer, do nothing
322 auto element = instance->layers.find(name);
Michael Lentine233ac732015-11-18 18:28:07 -0800323 if (element == instance->layers.end()) {
324 return;
325 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500326 if (std::find(object->active_layers.begin(), object->active_layers.end(),
327 element) != object->active_layers.end()) {
328 ALOGW("Layer %s already activated; skipping", name.c_str());
329 return;
330 }
331 // If layer is not open, open it
332 LayerData& layer_data = element->second;
333 pthread_mutex_lock(&instance->layer_lock);
334 if (layer_data.ref_count == 0) {
335 SharedLibraryHandle layer_handle =
336 dlopen(layer_data.path.c_str(), RTLD_NOW | RTLD_LOCAL);
337 if (!layer_handle) {
338 pthread_mutex_unlock(&instance->layer_lock);
339 ALOGE("%s failed to load with error %s; Skipping",
340 layer_data.path.c_str(), dlerror());
341 return;
342 }
343 layer_data.handle = layer_handle;
344 }
345 layer_data.ref_count++;
346 pthread_mutex_unlock(&instance->layer_lock);
347 ALOGV("Activating layer %s", name.c_str());
348 object->active_layers.push_back(element);
349}
350
Michael Lentine1d1e65f2015-11-19 14:23:06 -0800351void DeactivateLayer(Instance* instance,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500352 Vector<LayerMapIterator>::iterator& element) {
353 LayerMapIterator& layer_map_data = *element;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500354 LayerData& layer_data = layer_map_data->second;
355 pthread_mutex_lock(&instance->layer_lock);
356 layer_data.ref_count--;
357 if (!layer_data.ref_count) {
358 dlclose(layer_data.handle);
359 }
360 pthread_mutex_unlock(&instance->layer_lock);
361}
362
Michael Lentine9da191b2015-10-13 11:08:45 -0500363struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500364 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500365 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500366};
367
Michael Lentine9da191b2015-10-13 11:08:45 -0500368void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500369 const char* value,
370 void* data) {
371 const char prefix[] = "debug.vulkan.layer.";
372 const size_t prefixlen = sizeof(prefix) - 1;
373 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
374 return;
Michael Lentine9da191b2015-10-13 11:08:45 -0500375 const char* number_str = name + prefixlen;
376 long layer_number = strtol(number_str, nullptr, 10);
377 if (layer_number <= 0 || layer_number == LONG_MAX) {
378 ALOGW("Cannot use a layer at number %ld from string %s", layer_number,
379 number_str);
380 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500381 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500382 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
383 Vector<String>* layer_names = instance_names_pair->layer_names;
384 Instance* instance = instance_names_pair->instance;
385 size_t layer_size = static_cast<size_t>(layer_number);
386 if (layer_size > layer_names->size()) {
387 layer_names->resize(layer_size,
388 String(CallbackAllocator<char>(instance->alloc)));
389 }
390 (*layer_names)[layer_size - 1] = value;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500391}
392
393template <class TInfo, class TObject>
Jesse Hall9a16f972015-10-28 15:59:53 -0700394VkResult ActivateAllLayers(TInfo create_info, Instance* instance, TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500395 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
396 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
397 "Cannot activate layers for unknown object %p", object);
398 CallbackAllocator<char> string_allocator(instance->alloc);
399 // Load system layers
400 {
401 char layer_prop[PROPERTY_VALUE_MAX];
402 property_get("debug.vulkan.layers", layer_prop, "");
403 String layer_name(string_allocator);
404 String layer_prop_str(layer_prop, string_allocator);
405 size_t end, start = 0;
406 while ((end = layer_prop_str.find(':', start)) != std::string::npos) {
407 layer_name = layer_prop_str.substr(start, end - start);
Michael Lentine233ac732015-11-18 18:28:07 -0800408 ActivateLayer(object, instance, layer_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500409 start = end + 1;
410 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500411 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
412 InstanceNamesPair instance_names_pair = {.instance = instance,
413 .layer_names = &layer_names};
414 property_list(SetLayerNamesFromProperty,
415 static_cast<void*>(&instance_names_pair));
416 for (auto layer_name_element : layer_names) {
417 ActivateLayer(object, instance, layer_name_element);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500418 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500419 }
420 // Load app layers
421 for (uint32_t i = 0; i < create_info->layerCount; ++i) {
422 String layer_name(create_info->ppEnabledLayerNames[i],
423 string_allocator);
424 auto element = instance->layers.find(layer_name);
425 if (element == instance->layers.end()) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700426 ALOGE("requested %s layer '%s' not present",
427 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ?
428 "instance" : "device",
429 layer_name.c_str());
430 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500431 } else {
432 ActivateLayer(object, instance, layer_name);
433 }
434 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700435 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500436}
437
438template <class TCreateInfo>
439bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
440 const char* extension_name,
441 const VkAllocCallbacks* alloc) {
442 for (uint32_t i = 0; i < local_create_info.extensionCount; ++i) {
443 if (!strcmp(extension_name,
444 local_create_info.ppEnabledExtensionNames[i])) {
445 return false;
446 }
447 }
448 uint32_t extension_count = local_create_info.extensionCount;
449 local_create_info.extensionCount++;
450 void* mem = alloc->pfnAlloc(
451 alloc->pUserData, local_create_info.extensionCount * sizeof(char*),
452 alignof(char*), VK_SYSTEM_ALLOC_TYPE_INTERNAL);
453 if (mem) {
454 const char** enabled_extensions = static_cast<const char**>(mem);
455 for (uint32_t i = 0; i < extension_count; ++i) {
456 enabled_extensions[i] =
457 local_create_info.ppEnabledExtensionNames[i];
458 }
459 enabled_extensions[extension_count] = extension_name;
460 local_create_info.ppEnabledExtensionNames = enabled_extensions;
461 } else {
462 ALOGW("%s extension cannot be enabled: memory allocation failed",
463 extension_name);
464 local_create_info.extensionCount--;
465 return false;
466 }
467 return true;
468}
469
470template <class T>
471void FreeAllocatedCreateInfo(T& local_create_info,
472 const VkAllocCallbacks* alloc) {
473 alloc->pfnFree(
474 alloc->pUserData,
475 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
476}
477
Michael Lentineeb970862015-10-15 12:42:22 -0500478VkBool32 LogDebugMessageCallback(VkFlags message_flags,
479 VkDbgObjectType /*obj_type*/,
480 uint64_t /*src_object*/,
481 size_t /*location*/,
482 int32_t message_code,
483 const char* layer_prefix,
484 const char* message,
485 void* /*user_data*/) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500486 if (message_flags & VK_DBG_REPORT_ERROR_BIT) {
487 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
488 } else if (message_flags & VK_DBG_REPORT_WARN_BIT) {
489 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
490 }
Michael Lentineeb970862015-10-15 12:42:22 -0500491 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500492}
493
Michael Lentined1d5e5e2015-11-02 18:32:04 -0800494VkResult Noop(...) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500495 return VK_SUCCESS;
496}
497
498PFN_vkVoidFunction GetLayerDeviceProcAddr(VkDevice device, const char* name) {
499 if (strcmp(name, "vkGetDeviceProcAddr") == 0) {
500 return reinterpret_cast<PFN_vkVoidFunction>(GetLayerDeviceProcAddr);
501 }
502 if (strcmp(name, "vkCreateDevice") == 0) {
Michael Lentined1d5e5e2015-11-02 18:32:04 -0800503 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
Michael Lentine03c64b02015-08-26 18:27:26 -0500504 }
Michael Lentine88594d72015-11-12 12:49:45 -0800505 // WSI extensions are not in the driver so return the loader functions
506 if (strcmp(name, "vkGetSurfacePropertiesKHR") == 0) {
507 return reinterpret_cast<PFN_vkVoidFunction>(GetSurfacePropertiesKHR);
508 }
509 if (strcmp(name, "vkGetSurfaceFormatsKHR") == 0) {
510 return reinterpret_cast<PFN_vkVoidFunction>(GetSurfaceFormatsKHR);
511 }
512 if (strcmp(name, "vkGetSurfacePresentModesKHR") == 0) {
513 return reinterpret_cast<PFN_vkVoidFunction>(GetSurfacePresentModesKHR);
514 }
515 if (strcmp(name, "vkCreateSwapchainKHR") == 0) {
516 return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
517 }
518 if (strcmp(name, "vkDestroySwapchainKHR") == 0) {
519 return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
520 }
521 if (strcmp(name, "vkGetSwapchainImagesKHR") == 0) {
522 return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
523 }
524 if (strcmp(name, "vkAcquireNextImageKHR") == 0) {
525 return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
526 }
527 if (strcmp(name, "vkQueuePresentKHR") == 0) {
528 return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
529 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500530 if (!device)
531 return GetGlobalDeviceProcAddr(name);
532 Device* loader_device = reinterpret_cast<Device*>(GetVtbl(device)->device);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500533 return loader_device->instance->drv.GetDeviceProcAddr(device, name);
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500534}
535
Jesse Hall04f4f472015-08-16 19:51:04 -0700536// -----------------------------------------------------------------------------
537// "Bottom" functions. These are called at the end of the instance dispatch
538// chain.
539
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700540void DestroyInstanceBottom(VkInstance instance) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700541 // These checks allow us to call DestroyInstanceBottom from any error path
542 // in CreateInstanceBottom, before the driver instance is fully initialized.
543 if (instance->drv.vtbl.instance != VK_NULL_HANDLE &&
544 instance->drv.vtbl.DestroyInstance) {
545 instance->drv.vtbl.DestroyInstance(instance->drv.vtbl.instance);
546 }
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500547 if (instance->message) {
548 PFN_vkDbgDestroyMsgCallback DebugDestroyMessageCallback;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500549 DebugDestroyMessageCallback =
550 reinterpret_cast<PFN_vkDbgDestroyMsgCallback>(
551 vkGetInstanceProcAddr(instance, "vkDbgDestroyMsgCallback"));
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500552 DebugDestroyMessageCallback(instance, instance->message);
553 }
Michael Lentined1d5e5e2015-11-02 18:32:04 -0800554 for (auto it = instance->active_layers.begin();
555 it != instance->active_layers.end(); ++it) {
Michael Lentine1d1e65f2015-11-19 14:23:06 -0800556 DeactivateLayer(instance, it);
Michael Lentined1d5e5e2015-11-02 18:32:04 -0800557 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700558 const VkAllocCallbacks* alloc = instance->alloc;
559 instance->~VkInstance_T();
560 alloc->pfnFree(alloc->pUserData, instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700561}
562
563VkResult CreateInstanceBottom(const VkInstanceCreateInfo* create_info,
564 VkInstance* instance_ptr) {
565 Instance* instance = *instance_ptr;
566 VkResult result;
567
568 result =
569 g_hwdevice->CreateInstance(create_info, &instance->drv.vtbl.instance);
570 if (result != VK_SUCCESS) {
571 DestroyInstanceBottom(instance);
572 return result;
573 }
574
Michael Lentine03c64b02015-08-26 18:27:26 -0500575 if (!LoadInstanceVtbl(
576 instance->drv.vtbl.instance, instance->drv.vtbl.instance,
577 g_hwdevice->GetInstanceProcAddr, instance->drv.vtbl)) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700578 DestroyInstanceBottom(instance);
579 return VK_ERROR_INITIALIZATION_FAILED;
580 }
581
582 // vkGetDeviceProcAddr has a bootstrapping problem. We require that it be
583 // queryable from the Instance, and that the resulting function work for any
584 // VkDevice created from the instance.
585 instance->drv.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
586 g_hwdevice->GetInstanceProcAddr(instance->drv.vtbl.instance,
587 "vkGetDeviceProcAddr"));
588 if (!instance->drv.GetDeviceProcAddr) {
589 ALOGE("missing instance proc: \"%s\"", "vkGetDeviceProcAddr");
590 DestroyInstanceBottom(instance);
591 return VK_ERROR_INITIALIZATION_FAILED;
592 }
593
594 hwvulkan_dispatch_t* dispatch =
595 reinterpret_cast<hwvulkan_dispatch_t*>(instance->drv.vtbl.instance);
596 if (dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
597 // Skip setting dispatch->vtbl on the driver instance handle, since we
598 // never intentionally call through it; we go through Instance::drv.vtbl
599 // instead.
600 } else {
601 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
602 dispatch->magic);
603 DestroyInstanceBottom(instance);
604 return VK_ERROR_INITIALIZATION_FAILED;
605 }
606
607 uint32_t num_physical_devices = 0;
608 result = instance->drv.vtbl.EnumeratePhysicalDevices(
609 instance->drv.vtbl.instance, &num_physical_devices, nullptr);
610 if (result != VK_SUCCESS) {
611 DestroyInstanceBottom(instance);
612 return VK_ERROR_INITIALIZATION_FAILED;
613 }
614 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
615 result = instance->drv.vtbl.EnumeratePhysicalDevices(
616 instance->drv.vtbl.instance, &num_physical_devices,
617 instance->physical_devices);
618 if (result != VK_SUCCESS) {
619 DestroyInstanceBottom(instance);
620 return VK_ERROR_INITIALIZATION_FAILED;
621 }
622 for (uint32_t i = 0; i < num_physical_devices; i++) {
623 dispatch = reinterpret_cast<hwvulkan_dispatch_t*>(
624 instance->physical_devices[i]);
625 if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
626 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
627 dispatch->magic);
628 DestroyInstanceBottom(instance);
629 return VK_ERROR_INITIALIZATION_FAILED;
630 }
631 dispatch->vtbl = instance->vtbl;
632 }
633 instance->drv.num_physical_devices = num_physical_devices;
634
635 instance->num_physical_devices = instance->drv.num_physical_devices;
636 return VK_SUCCESS;
637}
638
639VkResult EnumeratePhysicalDevicesBottom(VkInstance instance,
640 uint32_t* pdev_count,
641 VkPhysicalDevice* pdevs) {
642 uint32_t count = instance->num_physical_devices;
643 if (pdevs) {
644 count = std::min(count, *pdev_count);
645 std::copy(instance->physical_devices,
646 instance->physical_devices + count, pdevs);
647 }
648 *pdev_count = count;
649 return VK_SUCCESS;
650}
651
Jesse Hall606a54e2015-11-19 22:17:28 -0800652void GetPhysicalDeviceFeaturesBottom(VkPhysicalDevice pdev,
653 VkPhysicalDeviceFeatures* features) {
654 GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceFeatures(pdev, features);
Jesse Hall04f4f472015-08-16 19:51:04 -0700655}
656
Jesse Hall606a54e2015-11-19 22:17:28 -0800657void GetPhysicalDeviceFormatPropertiesBottom(VkPhysicalDevice pdev,
658 VkFormat format,
659 VkFormatProperties* properties) {
660 GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700661 pdev, format, properties);
662}
663
Jesse Hall606a54e2015-11-19 22:17:28 -0800664void GetPhysicalDeviceImageFormatPropertiesBottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700665 VkPhysicalDevice pdev,
666 VkFormat format,
667 VkImageType type,
668 VkImageTiling tiling,
669 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700670 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700671 VkImageFormatProperties* properties) {
Jesse Hall606a54e2015-11-19 22:17:28 -0800672 GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceImageFormatProperties(
673 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700674}
675
Jesse Hall606a54e2015-11-19 22:17:28 -0800676void GetPhysicalDevicePropertiesBottom(VkPhysicalDevice pdev,
677 VkPhysicalDeviceProperties* properties) {
678 GetVtbl(pdev)
Jesse Hall04f4f472015-08-16 19:51:04 -0700679 ->instance->drv.vtbl.GetPhysicalDeviceProperties(pdev, properties);
680}
681
Jesse Hall606a54e2015-11-19 22:17:28 -0800682void GetPhysicalDeviceQueueFamilyPropertiesBottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700683 VkPhysicalDevice pdev,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700684 uint32_t* pCount,
685 VkQueueFamilyProperties* properties) {
Jesse Hall606a54e2015-11-19 22:17:28 -0800686 GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceQueueFamilyProperties(
687 pdev, pCount, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700688}
689
Jesse Hall606a54e2015-11-19 22:17:28 -0800690void GetPhysicalDeviceMemoryPropertiesBottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700691 VkPhysicalDevice pdev,
692 VkPhysicalDeviceMemoryProperties* properties) {
Jesse Hall606a54e2015-11-19 22:17:28 -0800693 GetVtbl(pdev)->instance->drv.vtbl.GetPhysicalDeviceMemoryProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700694 pdev, properties);
695}
696
697VkResult CreateDeviceBottom(VkPhysicalDevice pdev,
698 const VkDeviceCreateInfo* create_info,
699 VkDevice* out_device) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500700 Instance& instance = *static_cast<Instance*>(GetVtbl(pdev)->instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700701 VkResult result;
702
703 void* mem = instance.alloc->pfnAlloc(instance.alloc->pUserData,
704 sizeof(Device), alignof(Device),
705 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
706 if (!mem)
707 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500708 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700709
Jesse Hall9a16f972015-10-28 15:59:53 -0700710 result = ActivateAllLayers(create_info, &instance, device);
711 if (result != VK_SUCCESS) {
712 DestroyDevice(device);
713 return result;
714 }
715
Jesse Hall04f4f472015-08-16 19:51:04 -0700716 VkDevice drv_device;
717 result = instance.drv.vtbl.CreateDevice(pdev, create_info, &drv_device);
718 if (result != VK_SUCCESS) {
719 DestroyDevice(device);
720 return result;
721 }
722
Jesse Hall04f4f472015-08-16 19:51:04 -0700723 hwvulkan_dispatch_t* dispatch =
724 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
725 if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
726 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR, dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500727 PFN_vkDestroyDevice destroy_device =
728 reinterpret_cast<PFN_vkDestroyDevice>(
729 instance.drv.GetDeviceProcAddr(drv_device, "vkDestroyDevice"));
730 destroy_device(drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700731 DestroyDevice(device);
732 return VK_ERROR_INITIALIZATION_FAILED;
733 }
734 dispatch->vtbl = &device->vtbl_storage;
735
Michael Lentine03c64b02015-08-26 18:27:26 -0500736 void* base_object = static_cast<void*>(drv_device);
737 void* next_object = base_object;
738 VkLayerLinkedListElem* next_element;
739 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetLayerDeviceProcAddr;
740 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500741 device->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500742 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
743
744 for (size_t i = elem_list.size(); i > 0; i--) {
745 size_t idx = i - 1;
746 next_element = &elem_list[idx];
747 next_element->get_proc_addr =
748 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
749 next_element->base_object = base_object;
750 next_element->next_element = next_object;
751 next_object = static_cast<void*>(next_element);
752
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500753 auto& name = device->active_layers[idx]->first;
754 auto& handle = device->active_layers[idx]->second.handle;
Michael Lentine03c64b02015-08-26 18:27:26 -0500755 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500756 dlsym(handle, (name + "GetDeviceProcAddr").c_str()));
Michael Lentine03c64b02015-08-26 18:27:26 -0500757 if (!next_get_proc_addr) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500758 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500759 dlsym(handle, "vkGetDeviceProcAddr"));
Michael Lentine1f0f5392015-09-11 14:54:34 -0700760 if (!next_get_proc_addr) {
761 ALOGE("Cannot find vkGetDeviceProcAddr for %s, error is %s",
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500762 name.c_str(), dlerror());
Michael Lentine1f0f5392015-09-11 14:54:34 -0700763 next_object = next_element->next_element;
764 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
765 next_element->get_proc_addr);
766 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500767 }
768 }
769
770 if (!LoadDeviceVtbl(static_cast<VkDevice>(base_object),
771 static_cast<VkDevice>(next_object), next_get_proc_addr,
772 device->vtbl_storage)) {
773 DestroyDevice(device);
774 return VK_ERROR_INITIALIZATION_FAILED;
775 }
776
777 PFN_vkCreateDevice layer_createDevice =
778 reinterpret_cast<PFN_vkCreateDevice>(
779 device->vtbl_storage.GetDeviceProcAddr(drv_device,
780 "vkCreateDevice"));
781 layer_createDevice(pdev, create_info, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700782
Michael Lentine88594d72015-11-12 12:49:45 -0800783 // TODO(mlentine) : This is needed to use WSI layer validation. Remove this
784 // when new version of layer initialization exits.
785 if (!LoadDeviceVtbl(static_cast<VkDevice>(base_object),
786 static_cast<VkDevice>(next_object), next_get_proc_addr,
787 device->vtbl_storage)) {
788 DestroyDevice(device);
789 return VK_ERROR_INITIALIZATION_FAILED;
790 }
791
Jesse Hall04f4f472015-08-16 19:51:04 -0700792 *out_device = drv_device;
793 return VK_SUCCESS;
794}
795
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700796VkResult EnumerateDeviceExtensionPropertiesBottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700797 VkPhysicalDevice pdev,
798 const char* layer_name,
799 uint32_t* properties_count,
800 VkExtensionProperties* properties) {
801 // TODO: what are we supposed to do with layer_name here?
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700802 return GetVtbl(pdev)->instance->drv.vtbl.EnumerateDeviceExtensionProperties(
803 pdev, layer_name, properties_count, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700804}
805
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700806VkResult EnumerateDeviceLayerPropertiesBottom(VkPhysicalDevice pdev,
807 uint32_t* properties_count,
808 VkLayerProperties* properties) {
809 return GetVtbl(pdev)->instance->drv.vtbl.EnumerateDeviceLayerProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700810 pdev, properties_count, properties);
811}
812
Jesse Hall606a54e2015-11-19 22:17:28 -0800813void GetPhysicalDeviceSparseImageFormatPropertiesBottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700814 VkPhysicalDevice pdev,
815 VkFormat format,
816 VkImageType type,
817 uint32_t samples,
818 VkImageUsageFlags usage,
819 VkImageTiling tiling,
820 uint32_t* properties_count,
821 VkSparseImageFormatProperties* properties) {
Jesse Hall606a54e2015-11-19 22:17:28 -0800822 GetVtbl(pdev)
Jesse Hall04f4f472015-08-16 19:51:04 -0700823 ->instance->drv.vtbl.GetPhysicalDeviceSparseImageFormatProperties(
824 pdev, format, type, samples, usage, tiling, properties_count,
825 properties);
826}
827
828PFN_vkVoidFunction GetInstanceProcAddrBottom(VkInstance, const char*);
829
830const InstanceVtbl kBottomInstanceFunctions = {
831 // clang-format off
832 .instance = nullptr,
833 .CreateInstance = CreateInstanceBottom,
834 .DestroyInstance = DestroyInstanceBottom,
835 .GetInstanceProcAddr = GetInstanceProcAddrBottom,
836 .EnumeratePhysicalDevices = EnumeratePhysicalDevicesBottom,
837 .GetPhysicalDeviceFeatures = GetPhysicalDeviceFeaturesBottom,
838 .GetPhysicalDeviceFormatProperties = GetPhysicalDeviceFormatPropertiesBottom,
839 .GetPhysicalDeviceImageFormatProperties = GetPhysicalDeviceImageFormatPropertiesBottom,
Jesse Hall04f4f472015-08-16 19:51:04 -0700840 .GetPhysicalDeviceProperties = GetPhysicalDevicePropertiesBottom,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700841 .GetPhysicalDeviceQueueFamilyProperties = GetPhysicalDeviceQueueFamilyPropertiesBottom,
Jesse Hall04f4f472015-08-16 19:51:04 -0700842 .GetPhysicalDeviceMemoryProperties = GetPhysicalDeviceMemoryPropertiesBottom,
843 .CreateDevice = CreateDeviceBottom,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700844 .EnumerateDeviceExtensionProperties = EnumerateDeviceExtensionPropertiesBottom,
845 .EnumerateDeviceLayerProperties = EnumerateDeviceLayerPropertiesBottom,
Jesse Hall04f4f472015-08-16 19:51:04 -0700846 .GetPhysicalDeviceSparseImageFormatProperties = GetPhysicalDeviceSparseImageFormatPropertiesBottom,
Jesse Hallb1352bc2015-09-04 16:12:33 -0700847 .GetPhysicalDeviceSurfaceSupportKHR = GetPhysicalDeviceSurfaceSupportKHR,
Jesse Hall04f4f472015-08-16 19:51:04 -0700848 // clang-format on
849};
850
851PFN_vkVoidFunction GetInstanceProcAddrBottom(VkInstance, const char* name) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500852 // TODO: Possibly move this into the instance table
853 // TODO: Possibly register the callbacks in the loader
854 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
855 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
856 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
857 }
858 if (strcmp(name, "vkCreateInstance") == 0) {
859 return reinterpret_cast<PFN_vkVoidFunction>(CreateInstanceBottom);
860 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700861 return GetSpecificInstanceProcAddr(&kBottomInstanceFunctions, name);
862}
863
864} // namespace
865
866// -----------------------------------------------------------------------------
867// Global functions. These are called directly from the loader entry points,
868// without going through a dispatch table.
869
870namespace vulkan {
871
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700872VkResult EnumerateInstanceExtensionProperties(
873 const char* /*layer_name*/,
874 uint32_t* count,
875 VkExtensionProperties* /*properties*/) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700876 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700877 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700878
879 // TODO: not yet implemented
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700880 ALOGW("vkEnumerateInstanceExtensionProperties not implemented");
Jesse Hall04f4f472015-08-16 19:51:04 -0700881
882 *count = 0;
883 return VK_SUCCESS;
884}
885
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700886VkResult EnumerateInstanceLayerProperties(uint32_t* count,
887 VkLayerProperties* /*properties*/) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700888 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700889 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700890
891 // TODO: not yet implemented
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700892 ALOGW("vkEnumerateInstanceLayerProperties not implemented");
Jesse Hall04f4f472015-08-16 19:51:04 -0700893
894 *count = 0;
895 return VK_SUCCESS;
896}
897
898VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
899 VkInstance* out_instance) {
900 VkResult result;
901
902 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700903 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700904
905 VkInstanceCreateInfo local_create_info = *create_info;
906 if (!local_create_info.pAllocCb)
907 local_create_info.pAllocCb = &kDefaultAllocCallbacks;
908 create_info = &local_create_info;
909
910 void* instance_mem = create_info->pAllocCb->pfnAlloc(
911 create_info->pAllocCb->pUserData, sizeof(Instance), alignof(Instance),
912 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
913 if (!instance_mem)
914 return VK_ERROR_OUT_OF_HOST_MEMORY;
915 Instance* instance = new (instance_mem) Instance(create_info->pAllocCb);
916
917 instance->vtbl_storage = kBottomInstanceFunctions;
918 instance->vtbl_storage.instance = instance;
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500919 instance->message = VK_NULL_HANDLE;
Jesse Hall04f4f472015-08-16 19:51:04 -0700920
Michael Lentine03c64b02015-08-26 18:27:26 -0500921 // Scan layers
Michael Lentine03c64b02015-08-26 18:27:26 -0500922 CallbackAllocator<char> string_allocator(instance->alloc);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500923
Michael Lentine03c64b02015-08-26 18:27:26 -0500924 String dir_name("/data/local/tmp/vulkan/", string_allocator);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500925 FindLayersInDirectory(*instance, dir_name);
Michael Lentine1c69b9e2015-09-14 13:26:59 -0500926 const std::string& path = LoaderData::GetInstance().layer_path;
927 dir_name.assign(path.c_str(), path.size());
928 dir_name.append("/");
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500929 FindLayersInDirectory(*instance, dir_name);
Jesse Hall04f4f472015-08-16 19:51:04 -0700930
Jesse Hall9a16f972015-10-28 15:59:53 -0700931 result = ActivateAllLayers(create_info, instance, instance);
932 if (result != VK_SUCCESS) {
933 DestroyInstanceBottom(instance);
934 return result;
935 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500936
937 void* base_object = static_cast<void*>(instance);
938 void* next_object = base_object;
939 VkLayerLinkedListElem* next_element;
940 PFN_vkGetInstanceProcAddr next_get_proc_addr =
941 kBottomInstanceFunctions.GetInstanceProcAddr;
942 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine1f0f5392015-09-11 14:54:34 -0700943 instance->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500944 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
945
946 for (size_t i = elem_list.size(); i > 0; i--) {
947 size_t idx = i - 1;
948 next_element = &elem_list[idx];
949 next_element->get_proc_addr =
950 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
951 next_element->base_object = base_object;
952 next_element->next_element = next_object;
953 next_object = static_cast<void*>(next_element);
954
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500955 auto& name = instance->active_layers[idx]->first;
956 auto& handle = instance->active_layers[idx]->second.handle;
Michael Lentine03c64b02015-08-26 18:27:26 -0500957 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500958 dlsym(handle, (name + "GetInstanceProcAddr").c_str()));
Michael Lentine03c64b02015-08-26 18:27:26 -0500959 if (!next_get_proc_addr) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500960 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500961 dlsym(handle, "vkGetInstanceProcAddr"));
Michael Lentine1f0f5392015-09-11 14:54:34 -0700962 if (!next_get_proc_addr) {
963 ALOGE("Cannot find vkGetInstanceProcAddr for %s, error is %s",
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500964 name.c_str(), dlerror());
Michael Lentine1f0f5392015-09-11 14:54:34 -0700965 next_object = next_element->next_element;
966 next_get_proc_addr =
967 reinterpret_cast<PFN_vkGetInstanceProcAddr>(
968 next_element->get_proc_addr);
969 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500970 }
971 }
972
973 if (!LoadInstanceVtbl(static_cast<VkInstance>(base_object),
974 static_cast<VkInstance>(next_object),
975 next_get_proc_addr, instance->vtbl_storage)) {
976 DestroyInstanceBottom(instance);
977 return VK_ERROR_INITIALIZATION_FAILED;
978 }
979
Michael Lentine950bb4f2015-09-14 13:26:30 -0500980 // Force enable callback extension if required
981 bool enable_callback =
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500982 property_get_bool("debug.vulkan.enable_callback", false);
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500983 bool enable_logging = enable_callback;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500984 const char* extension_name = "DEBUG_REPORT";
Michael Lentine950bb4f2015-09-14 13:26:30 -0500985 if (enable_callback) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500986 enable_callback = AddExtensionToCreateInfo(
987 local_create_info, extension_name, instance->alloc);
Michael Lentine950bb4f2015-09-14 13:26:30 -0500988 }
989
Jesse Hall04f4f472015-08-16 19:51:04 -0700990 *out_instance = instance;
Michael Lentine03c64b02015-08-26 18:27:26 -0500991 result = instance->vtbl_storage.CreateInstance(create_info, out_instance);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500992 if (enable_callback)
993 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall04f4f472015-08-16 19:51:04 -0700994 if (result <= 0) {
995 // For every layer, including the loader top and bottom layers:
996 // - If a call to the next CreateInstance fails, the layer must clean
997 // up anything it has successfully done so far, and propagate the
998 // error upwards.
999 // - If a layer successfully calls the next layer's CreateInstance, and
1000 // afterwards must fail for some reason, it must call the next layer's
1001 // DestroyInstance before returning.
1002 // - The layer must not call the next layer's DestroyInstance if that
1003 // layer's CreateInstance wasn't called, or returned failure.
1004
1005 // On failure, CreateInstanceBottom frees the instance struct, so it's
1006 // already gone at this point. Nothing to do.
1007 }
1008
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001009 if (enable_logging) {
1010 PFN_vkDbgCreateMsgCallback DebugCreateMessageCallback;
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001011 DebugCreateMessageCallback =
1012 reinterpret_cast<PFN_vkDbgCreateMsgCallback>(
1013 vkGetInstanceProcAddr(instance, "vkDbgCreateMsgCallback"));
1014 DebugCreateMessageCallback(
1015 instance, VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT,
1016 LogDebugMessageCallback, NULL, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001017 }
1018
Jesse Hall04f4f472015-08-16 19:51:04 -07001019 return result;
1020}
1021
1022PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
1023 if (!instance)
1024 return GetGlobalInstanceProcAddr(name);
Michael Lentine03c64b02015-08-26 18:27:26 -05001025 // TODO: Possibly move this into the instance table
1026 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
1027 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
1028 if (!instance->vtbl)
1029 return NULL;
1030 PFN_vkGetInstanceProcAddr gpa = instance->vtbl->GetInstanceProcAddr;
1031 return reinterpret_cast<PFN_vkVoidFunction>(gpa(instance, name));
1032 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001033 // For special-case functions we always return the loader entry
1034 if (strcmp(name, "vkGetInstanceProcAddr") == 0 ||
1035 strcmp(name, "vkGetDeviceProcAddr") == 0) {
1036 return GetGlobalInstanceProcAddr(name);
1037 }
1038 return GetSpecificInstanceProcAddr(instance->vtbl, name);
1039}
1040
1041PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
1042 if (!device)
1043 return GetGlobalDeviceProcAddr(name);
Michael Lentine03c64b02015-08-26 18:27:26 -05001044 if (strcmp(name, "vkGetDeviceProcAddr") == 0) {
1045 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
1046 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001047 if (strcmp(name, "vkGetDeviceQueue") == 0) {
1048 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue);
1049 }
Jesse Hallfbf97b02015-11-20 14:17:03 -08001050 if (strcmp(name, "vkAllocCommandBuffers") == 0) {
1051 return reinterpret_cast<PFN_vkVoidFunction>(AllocCommandBuffers);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001052 }
1053 if (strcmp(name, "vkDestroyDevice") == 0) {
1054 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice);
1055 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001056 return GetSpecificDeviceProcAddr(GetVtbl(device), name);
1057}
1058
Jesse Hall606a54e2015-11-19 22:17:28 -08001059void GetDeviceQueue(VkDevice drv_device,
1060 uint32_t family,
1061 uint32_t index,
1062 VkQueue* out_queue) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001063 VkResult result;
1064 VkQueue queue;
1065 const DeviceVtbl* vtbl = GetVtbl(drv_device);
Jesse Hall606a54e2015-11-19 22:17:28 -08001066 vtbl->GetDeviceQueue(drv_device, family, index, &queue);
Jesse Hall04f4f472015-08-16 19:51:04 -07001067 hwvulkan_dispatch_t* dispatch =
1068 reinterpret_cast<hwvulkan_dispatch_t*>(queue);
Jesse Hall606a54e2015-11-19 22:17:28 -08001069 if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC && dispatch->vtbl != vtbl)
Jesse Hall04f4f472015-08-16 19:51:04 -07001070 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR, dispatch->magic);
Jesse Hall04f4f472015-08-16 19:51:04 -07001071 dispatch->vtbl = vtbl;
1072 *out_queue = queue;
Jesse Hall04f4f472015-08-16 19:51:04 -07001073}
1074
Jesse Hallfbf97b02015-11-20 14:17:03 -08001075VkResult AllocCommandBuffers(VkDevice device,
1076 const VkCmdBufferAllocInfo* alloc_info,
1077 VkCmdBuffer* cmdbuffers) {
1078 const DeviceVtbl* vtbl = GetVtbl(device);
1079 VkResult result = vtbl->AllocCommandBuffers(device, alloc_info, cmdbuffers);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001080 if (result != VK_SUCCESS)
1081 return result;
Jesse Hallfbf97b02015-11-20 14:17:03 -08001082 for (uint32_t i = 0; i < alloc_info->count; i++) {
1083 hwvulkan_dispatch_t* dispatch =
1084 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbuffers[i]);
1085 ALOGE_IF(dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
1086 "invalid VkCmdBuffer dispatch magic: 0x%" PRIxPTR,
1087 dispatch->magic);
1088 dispatch->vtbl = vtbl;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001089 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001090 return VK_SUCCESS;
1091}
1092
Jesse Hall04f4f472015-08-16 19:51:04 -07001093VkResult DestroyDevice(VkDevice drv_device) {
1094 const DeviceVtbl* vtbl = GetVtbl(drv_device);
1095 Device* device = static_cast<Device*>(vtbl->device);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001096 for (auto it = device->active_layers.begin();
1097 it != device->active_layers.end(); ++it) {
Michael Lentine1d1e65f2015-11-19 14:23:06 -08001098 DeactivateLayer(device->instance, it);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001099 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001100 vtbl->DestroyDevice(drv_device);
1101 DestroyDevice(device);
1102 return VK_SUCCESS;
1103}
1104
Jesse Hall1356b0d2015-11-23 17:24:58 -08001105void* AllocMem(VkInstance instance,
1106 size_t size,
1107 size_t align,
1108 VkSystemAllocType type) {
1109 const VkAllocCallbacks* alloc_cb = instance->alloc;
1110 return alloc_cb->pfnAlloc(alloc_cb->pUserData, size, align, type);
1111}
1112
1113void FreeMem(VkInstance instance, void* ptr) {
1114 const VkAllocCallbacks* alloc_cb = instance->alloc;
1115 alloc_cb->pfnFree(alloc_cb->pUserData, ptr);
1116}
1117
1118void* AllocMem(VkDevice device,
1119 size_t size,
1120 size_t align,
1121 VkSystemAllocType type) {
Jesse Halld7b994a2015-09-07 14:17:37 -07001122 const VkAllocCallbacks* alloc_cb =
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001123 static_cast<Device*>(GetVtbl(device)->device)->instance->alloc;
Jesse Halld7b994a2015-09-07 14:17:37 -07001124 return alloc_cb->pfnAlloc(alloc_cb->pUserData, size, align, type);
1125}
1126
Jesse Hall1356b0d2015-11-23 17:24:58 -08001127void FreeMem(VkDevice device, void* ptr) {
Jesse Halld7b994a2015-09-07 14:17:37 -07001128 const VkAllocCallbacks* alloc_cb =
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001129 static_cast<Device*>(GetVtbl(device)->device)->instance->alloc;
Jesse Halld7b994a2015-09-07 14:17:37 -07001130 alloc_cb->pfnFree(alloc_cb->pUserData, ptr);
1131}
1132
1133const DeviceVtbl& GetDriverVtbl(VkDevice device) {
1134 // TODO(jessehall): This actually returns the API-level vtbl for the
1135 // device, not the driver entry points. Given the current use -- getting
1136 // the driver's private swapchain-related functions -- that works, but is
1137 // misleading and likely to cause bugs. Fix as part of separating the
1138 // loader->driver interface from the app->loader interface.
1139 return static_cast<Device*>(GetVtbl(device)->device)->vtbl_storage;
1140}
1141
1142const DeviceVtbl& GetDriverVtbl(VkQueue queue) {
1143 // TODO(jessehall): This actually returns the API-level vtbl for the
1144 // device, not the driver entry points. Given the current use -- getting
1145 // the driver's private swapchain-related functions -- that works, but is
1146 // misleading and likely to cause bugs. Fix as part of separating the
1147 // loader->driver interface from the app->loader interface.
1148 return static_cast<Device*>(GetVtbl(queue)->device)->vtbl_storage;
1149}
1150
Jesse Hall04f4f472015-08-16 19:51:04 -07001151} // namespace vulkan