blob: 079352b6045d9bf9aa67c4c93088ca6059e4c4c0 [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
Jesse Hall504db7f2016-01-14 15:53:57 -080017// #define LOG_NDEBUG 0
Michael Lentine9dbe67f2015-09-16 15:53:50 -050018
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>
Jesse Hall04f4f472015-08-16 19:51:04 -070025#include <pthread.h>
Jesse Hall03b6fe12015-11-24 12:44:21 -080026#include <stdlib.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070027#include <string.h>
Jesse Hall21597662015-12-18 13:48:24 -080028#include <sys/prctl.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070029// standard C++ headers
30#include <algorithm>
31#include <mutex>
Michael Lentine03c64b02015-08-26 18:27:26 -050032#include <sstream>
33#include <string>
34#include <unordered_map>
35#include <vector>
Jesse Hall04f4f472015-08-16 19:51:04 -070036// platform/library headers
Michael Lentine03c64b02015-08-26 18:27:26 -050037#include <cutils/properties.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070038#include <hardware/hwvulkan.h>
39#include <log/log.h>
Michael Lentinecd6cabf2015-09-14 17:32:59 -050040#include <vulkan/vk_debug_report_lunarg.h>
Michael Lentine1c69b9e2015-09-14 13:26:59 -050041#include <vulkan/vulkan_loader_data.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070042
43using namespace vulkan;
44
45static const uint32_t kMaxPhysicalDevices = 4;
46
Michael Lentine03c64b02015-08-26 18:27:26 -050047namespace {
48
49// These definitions are taken from the LunarG Vulkan Loader. They are used to
50// enforce compatability between the Loader and Layers.
51typedef void* (*PFN_vkGetProcAddr)(void* obj, const char* pName);
52
53typedef struct VkLayerLinkedListElem_ {
54 PFN_vkGetProcAddr get_proc_addr;
55 void* next_element;
56 void* base_object;
57} VkLayerLinkedListElem;
58
Jesse Hall1f91d392015-12-11 16:28:44 -080059// ----------------------------------------------------------------------------
Michael Lentine03c64b02015-08-26 18:27:26 -050060
Jesse Hall3fbc8562015-11-29 22:10:52 -080061// Standard-library allocator that delegates to VkAllocationCallbacks.
Jesse Hall03b6fe12015-11-24 12:44:21 -080062//
63// TODO(jessehall): This class currently always uses
Jesse Hall3fbc8562015-11-29 22:10:52 -080064// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template
Jesse Hall03b6fe12015-11-24 12:44:21 -080065// parameter or a constructor parameter. The former would help catch bugs
66// where we use the wrong scope, e.g. adding a command-scope string to an
67// instance-scope vector. But that might also be pretty annoying to deal with.
Michael Lentine03c64b02015-08-26 18:27:26 -050068template <class T>
69class CallbackAllocator {
70 public:
71 typedef T value_type;
72
Jesse Hall3fbc8562015-11-29 22:10:52 -080073 CallbackAllocator(const VkAllocationCallbacks* alloc_input)
Michael Lentine03c64b02015-08-26 18:27:26 -050074 : alloc(alloc_input) {}
75
76 template <class T2>
77 CallbackAllocator(const CallbackAllocator<T2>& other)
78 : alloc(other.alloc) {}
79
80 T* allocate(std::size_t n) {
Jesse Hall3fbc8562015-11-29 22:10:52 -080081 void* mem =
82 alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T),
83 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine03c64b02015-08-26 18:27:26 -050084 return static_cast<T*>(mem);
85 }
86
87 void deallocate(T* array, std::size_t /*n*/) {
88 alloc->pfnFree(alloc->pUserData, array);
89 }
90
Jesse Hall3fbc8562015-11-29 22:10:52 -080091 const VkAllocationCallbacks* alloc;
Michael Lentine03c64b02015-08-26 18:27:26 -050092};
93// These are needed in order to move Strings
94template <class T>
95bool operator==(const CallbackAllocator<T>& alloc1,
96 const CallbackAllocator<T>& alloc2) {
97 return alloc1.alloc == alloc2.alloc;
98}
99template <class T>
100bool operator!=(const CallbackAllocator<T>& alloc1,
101 const CallbackAllocator<T>& alloc2) {
102 return !(alloc1 == alloc2);
103}
104
105template <class Key,
106 class T,
107 class Hash = std::hash<Key>,
Jesse Hall1f91d392015-12-11 16:28:44 -0800108 class Pred = std::equal_to<Key>>
Michael Lentine03c64b02015-08-26 18:27:26 -0500109using UnorderedMap =
110 std::unordered_map<Key,
111 T,
112 Hash,
113 Pred,
Jesse Hall1f91d392015-12-11 16:28:44 -0800114 CallbackAllocator<std::pair<const Key, T>>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500115
116template <class T>
Jesse Hall1f91d392015-12-11 16:28:44 -0800117using Vector = std::vector<T, CallbackAllocator<T>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500118
Jesse Hall1f91d392015-12-11 16:28:44 -0800119typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>>
120 String;
Michael Lentine03c64b02015-08-26 18:27:26 -0500121
Jesse Hall1f91d392015-12-11 16:28:44 -0800122// ----------------------------------------------------------------------------
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500123
Jesse Halle1b12782015-11-30 11:27:32 -0800124VKAPI_ATTR void* DefaultAllocate(void*,
125 size_t size,
126 size_t alignment,
127 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800128 void* ptr = nullptr;
129 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
130 // additionally requires that it be at least sizeof(void*).
131 return posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0
132 ? ptr
133 : nullptr;
134}
135
Jesse Halle1b12782015-11-30 11:27:32 -0800136VKAPI_ATTR void* DefaultReallocate(void*,
137 void* ptr,
138 size_t size,
139 size_t alignment,
140 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800141 if (size == 0) {
142 free(ptr);
143 return nullptr;
144 }
145
146 // TODO(jessehall): Right now we never shrink allocations; if the new
147 // request is smaller than the existing chunk, we just continue using it.
148 // Right now the loader never reallocs, so this doesn't matter. If that
149 // changes, or if this code is copied into some other project, this should
150 // probably have a heuristic to allocate-copy-free when doing so will save
151 // "enough" space.
152 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
153 if (size <= old_size)
154 return ptr;
155
156 void* new_ptr = nullptr;
157 if (posix_memalign(&new_ptr, alignment, size) != 0)
158 return nullptr;
159 if (ptr) {
160 memcpy(new_ptr, ptr, std::min(old_size, size));
161 free(ptr);
162 }
163 return new_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700164}
165
Jesse Halle1b12782015-11-30 11:27:32 -0800166VKAPI_ATTR void DefaultFree(void*, void* pMem) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700167 free(pMem);
168}
169
Jesse Hall3fbc8562015-11-29 22:10:52 -0800170const VkAllocationCallbacks kDefaultAllocCallbacks = {
Jesse Hall04f4f472015-08-16 19:51:04 -0700171 .pUserData = nullptr,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800172 .pfnAllocation = DefaultAllocate,
173 .pfnReallocation = DefaultReallocate,
Jesse Hall04f4f472015-08-16 19:51:04 -0700174 .pfnFree = DefaultFree,
175};
176
Jesse Hall1f91d392015-12-11 16:28:44 -0800177// ----------------------------------------------------------------------------
Jesse Hall80523e22016-01-06 16:47:54 -0800178// Global Data and Initialization
Jesse Hall1f91d392015-12-11 16:28:44 -0800179
Jesse Hall80523e22016-01-06 16:47:54 -0800180hwvulkan_device_t* g_hwdevice = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800181InstanceExtensionSet g_driver_instance_extensions;
182
Jesse Hall80523e22016-01-06 16:47:54 -0800183void LoadVulkanHAL() {
184 static const hwvulkan_module_t* module;
185 int result =
186 hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
187 if (result != 0) {
188 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
189 return;
190 }
191 result = module->common.methods->open(
192 &module->common, HWVULKAN_DEVICE_0,
193 reinterpret_cast<hw_device_t**>(&g_hwdevice));
194 if (result != 0) {
195 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
196 result);
197 module = nullptr;
198 return;
199 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800200
201 VkResult vkresult;
202 uint32_t count;
203 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
204 nullptr, &count, nullptr)) != VK_SUCCESS) {
205 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
206 vkresult);
207 g_hwdevice->common.close(&g_hwdevice->common);
208 g_hwdevice = nullptr;
209 module = nullptr;
210 return;
211 }
212 VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>(
213 alloca(count * sizeof(VkExtensionProperties)));
214 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
215 nullptr, &count, extensions)) != VK_SUCCESS) {
216 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
217 vkresult);
218 g_hwdevice->common.close(&g_hwdevice->common);
219 g_hwdevice = nullptr;
220 module = nullptr;
221 return;
222 }
223 ALOGV_IF(count > 0, "Driver-supported instance extensions:");
224 for (uint32_t i = 0; i < count; i++) {
225 ALOGV(" %s (v%u)", extensions[i].extensionName,
226 extensions[i].specVersion);
227 InstanceExtension id =
228 InstanceExtensionFromName(extensions[i].extensionName);
229 if (id != kInstanceExtensionCount)
230 g_driver_instance_extensions.set(id);
231 }
232 // Ignore driver attempts to support loader extensions
233 g_driver_instance_extensions.reset(kKHR_surface);
234 g_driver_instance_extensions.reset(kKHR_android_surface);
Jesse Hall80523e22016-01-06 16:47:54 -0800235}
236
Jesse Hall04f4f472015-08-16 19:51:04 -0700237bool EnsureInitialized() {
238 static std::once_flag once_flag;
Jesse Hall04f4f472015-08-16 19:51:04 -0700239 std::call_once(once_flag, []() {
Jesse Hall80523e22016-01-06 16:47:54 -0800240 LoadVulkanHAL();
241 DiscoverLayers();
Jesse Hall04f4f472015-08-16 19:51:04 -0700242 });
Jesse Hall80523e22016-01-06 16:47:54 -0800243 return g_hwdevice != nullptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700244}
245
Jesse Hall1f91d392015-12-11 16:28:44 -0800246// -----------------------------------------------------------------------------
247
248struct Instance {
249 Instance(const VkAllocationCallbacks* alloc_callbacks)
250 : dispatch_ptr(&dispatch),
251 handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
252 get_instance_proc_addr(nullptr),
253 alloc(alloc_callbacks),
254 num_physical_devices(0),
Jesse Hall80523e22016-01-06 16:47:54 -0800255 active_layers(CallbackAllocator<LayerRef>(alloc)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800256 message(VK_NULL_HANDLE) {
257 memset(&dispatch, 0, sizeof(dispatch));
258 memset(physical_devices, 0, sizeof(physical_devices));
Jesse Hall1f91d392015-12-11 16:28:44 -0800259 drv.instance = VK_NULL_HANDLE;
260 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
261 drv.num_physical_devices = 0;
262 }
263
Jesse Hall80523e22016-01-06 16:47:54 -0800264 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800265
266 const InstanceDispatchTable* dispatch_ptr;
267 const VkInstance handle;
268 InstanceDispatchTable dispatch;
269
270 // TODO(jessehall): Only needed by GetInstanceProcAddr_Top for
271 // vkDbg*MessageCallback. Points to the outermost layer's function. Remove
272 // once the DEBUG_CALLBACK is integrated into the API file.
273 PFN_vkGetInstanceProcAddr get_instance_proc_addr;
274
275 const VkAllocationCallbacks* alloc;
276 uint32_t num_physical_devices;
277 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
278
Jesse Hall80523e22016-01-06 16:47:54 -0800279 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800280 VkDbgMsgCallback message;
281
282 struct {
283 VkInstance instance;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800284 InstanceExtensionSet supported_extensions;
Jesse Hall1f91d392015-12-11 16:28:44 -0800285 DriverDispatchTable dispatch;
286 uint32_t num_physical_devices;
287 } drv; // may eventually be an array
288};
289
290struct Device {
291 Device(Instance* instance_)
292 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800293 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800294 memset(&dispatch, 0, sizeof(dispatch));
295 }
296 DeviceDispatchTable dispatch;
297 Instance* instance;
298 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800299 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800300};
301
302template <typename THandle>
303struct HandleTraits {};
304template <>
305struct HandleTraits<VkInstance> {
306 typedef Instance LoaderObjectType;
307};
308template <>
309struct HandleTraits<VkPhysicalDevice> {
310 typedef Instance LoaderObjectType;
311};
312template <>
313struct HandleTraits<VkDevice> {
314 typedef Device LoaderObjectType;
315};
316template <>
317struct HandleTraits<VkQueue> {
318 typedef Device LoaderObjectType;
319};
320template <>
321struct HandleTraits<VkCommandBuffer> {
322 typedef Device LoaderObjectType;
323};
324
325template <typename THandle>
326typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
327 THandle handle) {
328 // TODO(jessehall): Make Instance and Device POD types (by removing the
329 // non-default constructors), so that offsetof is actually legal to use.
330 // The specific case we're using here is safe in gcc/clang (and probably
331 // most other C++ compilers), but isn't guaranteed by C++.
332 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
333#pragma clang diagnostic push
334#pragma clang diagnostic ignored "-Winvalid-offsetof"
335 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
336#pragma clang diagnostic pop
337
338 const auto& dispatch = GetDispatchTable(handle);
339 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
340 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
341 return *reinterpret_cast<ObjectType*>(object_addr);
342}
343
344// -----------------------------------------------------------------------------
345
Jesse Hall04f4f472015-08-16 19:51:04 -0700346void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800347 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700348 device->~Device();
349 alloc->pfnFree(alloc->pUserData, device);
350}
351
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500352template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800353bool ActivateLayer(TObject* object, const char* name) {
354 LayerRef layer(GetLayerRef(name));
355 if (!layer)
356 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500357 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall80523e22016-01-06 16:47:54 -0800358 layer) == object->active_layers.end())
359 object->active_layers.push_back(std::move(layer));
360 ALOGV("activated layer '%s'", name);
361 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500362}
363
Michael Lentine9da191b2015-10-13 11:08:45 -0500364struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500365 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500366 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500367};
368
Michael Lentine9da191b2015-10-13 11:08:45 -0500369void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500370 const char* value,
371 void* data) {
372 const char prefix[] = "debug.vulkan.layer.";
373 const size_t prefixlen = sizeof(prefix) - 1;
374 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
375 return;
Michael Lentine9da191b2015-10-13 11:08:45 -0500376 const char* number_str = name + prefixlen;
377 long layer_number = strtol(number_str, nullptr, 10);
378 if (layer_number <= 0 || layer_number == LONG_MAX) {
379 ALOGW("Cannot use a layer at number %ld from string %s", layer_number,
380 number_str);
381 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500382 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500383 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
384 Vector<String>* layer_names = instance_names_pair->layer_names;
385 Instance* instance = instance_names_pair->instance;
386 size_t layer_size = static_cast<size_t>(layer_number);
387 if (layer_size > layer_names->size()) {
388 layer_names->resize(layer_size,
389 String(CallbackAllocator<char>(instance->alloc)));
390 }
391 (*layer_names)[layer_size - 1] = value;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500392}
393
394template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800395VkResult ActivateAllLayers(TInfo create_info,
396 Instance* instance,
397 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500398 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
399 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
400 "Cannot activate layers for unknown object %p", object);
401 CallbackAllocator<char> string_allocator(instance->alloc);
402 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800403 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500404 char layer_prop[PROPERTY_VALUE_MAX];
405 property_get("debug.vulkan.layers", layer_prop, "");
406 String layer_name(string_allocator);
407 String layer_prop_str(layer_prop, string_allocator);
408 size_t end, start = 0;
409 while ((end = layer_prop_str.find(':', start)) != std::string::npos) {
410 layer_name = layer_prop_str.substr(start, end - start);
Jesse Hall80523e22016-01-06 16:47:54 -0800411 ActivateLayer(object, layer_name.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500412 start = end + 1;
413 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500414 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
415 InstanceNamesPair instance_names_pair = {.instance = instance,
416 .layer_names = &layer_names};
417 property_list(SetLayerNamesFromProperty,
418 static_cast<void*>(&instance_names_pair));
419 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800420 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500421 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500422 }
423 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800424 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800425 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700426 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800427 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
428 ? "instance"
429 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800430 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700431 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500432 }
433 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700434 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500435}
436
437template <class TCreateInfo>
438bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
439 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800440 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800441 for (uint32_t i = 0; i < local_create_info.enabledExtensionCount; ++i) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500442 if (!strcmp(extension_name,
443 local_create_info.ppEnabledExtensionNames[i])) {
444 return false;
445 }
446 }
Jesse Hall3dd678a2016-01-08 21:52:01 -0800447 uint32_t extension_count = local_create_info.enabledExtensionCount;
448 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800449 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800450 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800451 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
452 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500453 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);
Jesse Hall3dd678a2016-01-08 21:52:01 -0800464 local_create_info.enabledExtensionCount--;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500465 return false;
466 }
467 return true;
468}
469
470template <class T>
471void FreeAllocatedCreateInfo(T& local_create_info,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800472 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500473 alloc->pfnFree(
474 alloc->pUserData,
475 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
476}
477
Jesse Halle1b12782015-11-30 11:27:32 -0800478VKAPI_ATTR
Michael Lentineeb970862015-10-15 12:42:22 -0500479VkBool32 LogDebugMessageCallback(VkFlags message_flags,
480 VkDbgObjectType /*obj_type*/,
481 uint64_t /*src_object*/,
482 size_t /*location*/,
483 int32_t message_code,
484 const char* layer_prefix,
485 const char* message,
486 void* /*user_data*/) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500487 if (message_flags & VK_DBG_REPORT_ERROR_BIT) {
488 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
489 } else if (message_flags & VK_DBG_REPORT_WARN_BIT) {
490 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
491 }
Michael Lentineeb970862015-10-15 12:42:22 -0500492 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500493}
494
Jesse Hall06193802015-12-03 16:12:51 -0800495VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500496 return VK_SUCCESS;
497}
498
Jesse Hall1f91d392015-12-11 16:28:44 -0800499} // anonymous namespace
500
501namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500502
Jesse Hall04f4f472015-08-16 19:51:04 -0700503// -----------------------------------------------------------------------------
504// "Bottom" functions. These are called at the end of the instance dispatch
505// chain.
506
Jesse Hall1f91d392015-12-11 16:28:44 -0800507VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
508 const VkAllocationCallbacks* allocator,
509 VkInstance* vkinstance) {
510 Instance& instance = GetDispatchParent(*vkinstance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700511 VkResult result;
512
Jesse Halla7ac76d2016-01-08 22:29:42 -0800513 VkInstanceCreateInfo driver_create_info = *create_info;
514 driver_create_info.enabledLayerCount = 0;
515 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800516
517 InstanceExtensionSet enabled_extensions;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800518 driver_create_info.enabledExtensionCount = 0;
519 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800520 size_t max_names = std::min(create_info->enabledExtensionCount,
521 g_driver_instance_extensions.count());
522 if (max_names > 0) {
523 const char** names =
524 static_cast<const char**>(alloca(max_names * sizeof(char*)));
525 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
526 InstanceExtension id = InstanceExtensionFromName(
527 create_info->ppEnabledExtensionNames[i]);
528 if (id != kInstanceExtensionCount &&
529 g_driver_instance_extensions[id]) {
530 names[driver_create_info.enabledExtensionCount++] =
531 create_info->ppEnabledExtensionNames[i];
532 enabled_extensions.set(id);
533 }
534 }
535 driver_create_info.ppEnabledExtensionNames = names;
536 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800537
538 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800539 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700540 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800541 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700542 return result;
543 }
544
Jesse Hall1f91d392015-12-11 16:28:44 -0800545 if (!LoadDriverDispatchTable(instance.drv.instance,
546 g_hwdevice->GetInstanceProcAddr,
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800547 enabled_extensions, instance.drv.dispatch)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800548 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700549 return VK_ERROR_INITIALIZATION_FAILED;
550 }
551
Jesse Hall1f91d392015-12-11 16:28:44 -0800552 hwvulkan_dispatch_t* drv_dispatch =
553 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
554 if (drv_dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
555 // Skip setting drv_dispatch->vtbl, since we never call through it;
556 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700557 } else {
558 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800559 drv_dispatch->magic);
560 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700561 return VK_ERROR_INITIALIZATION_FAILED;
562 }
563
564 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800565 result = instance.drv.dispatch.EnumeratePhysicalDevices(
566 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700567 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800568 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700569 return VK_ERROR_INITIALIZATION_FAILED;
570 }
571 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800572 result = instance.drv.dispatch.EnumeratePhysicalDevices(
573 instance.drv.instance, &num_physical_devices,
574 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700575 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800576 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700577 return VK_ERROR_INITIALIZATION_FAILED;
578 }
579 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800580 hwvulkan_dispatch_t* pdev_dispatch =
581 reinterpret_cast<hwvulkan_dispatch_t*>(
582 instance.physical_devices[i]);
583 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700584 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800585 pdev_dispatch->magic);
586 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700587 return VK_ERROR_INITIALIZATION_FAILED;
588 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800589 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700590 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800591 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700592
Jesse Hall1f91d392015-12-11 16:28:44 -0800593 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700594 return VK_SUCCESS;
595}
596
Jesse Hall1f91d392015-12-11 16:28:44 -0800597PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
598 PFN_vkVoidFunction pfn;
599 if ((pfn = GetLoaderBottomProcAddr(name)))
600 return pfn;
601 // TODO: Possibly move this into the instance table
602 // TODO: Possibly register the callbacks in the loader
603 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
604 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
605 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
606 }
607 return nullptr;
608}
609
610VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
611 uint32_t* pdev_count,
612 VkPhysicalDevice* pdevs) {
613 Instance& instance = GetDispatchParent(vkinstance);
614 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700615 if (pdevs) {
616 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800617 std::copy(instance.physical_devices, instance.physical_devices + count,
618 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700619 }
620 *pdev_count = count;
621 return VK_SUCCESS;
622}
623
Jesse Hall1f91d392015-12-11 16:28:44 -0800624void GetPhysicalDeviceProperties_Bottom(
625 VkPhysicalDevice pdev,
626 VkPhysicalDeviceProperties* properties) {
627 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
628 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700629}
630
Jesse Hall1f91d392015-12-11 16:28:44 -0800631void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
632 VkPhysicalDeviceFeatures* features) {
633 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
634 features);
635}
636
637void GetPhysicalDeviceMemoryProperties_Bottom(
638 VkPhysicalDevice pdev,
639 VkPhysicalDeviceMemoryProperties* properties) {
640 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
641 pdev, properties);
642}
643
644void GetPhysicalDeviceQueueFamilyProperties_Bottom(
645 VkPhysicalDevice pdev,
646 uint32_t* pCount,
647 VkQueueFamilyProperties* properties) {
648 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
649 pdev, pCount, properties);
650}
651
652void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
653 VkFormat format,
654 VkFormatProperties* properties) {
655 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700656 pdev, format, properties);
657}
658
Jesse Hall1f91d392015-12-11 16:28:44 -0800659VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700660 VkPhysicalDevice pdev,
661 VkFormat format,
662 VkImageType type,
663 VkImageTiling tiling,
664 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700665 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700666 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800667 return GetDispatchParent(pdev)
668 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800669 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700670}
671
Jesse Hall1f91d392015-12-11 16:28:44 -0800672void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700673 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800674 VkFormat format,
675 VkImageType type,
676 VkSampleCountFlagBits samples,
677 VkImageUsageFlags usage,
678 VkImageTiling tiling,
679 uint32_t* properties_count,
680 VkSparseImageFormatProperties* properties) {
681 GetDispatchParent(pdev)
682 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
683 pdev, format, type, samples, usage, tiling, properties_count,
684 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700685}
686
Jesse Halle1b12782015-11-30 11:27:32 -0800687VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800688VkResult EnumerateDeviceExtensionProperties_Bottom(
Jesse Hall80523e22016-01-06 16:47:54 -0800689 VkPhysicalDevice /*pdev*/,
690 const char* /*layer_name*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800691 uint32_t* properties_count,
Jesse Hall80523e22016-01-06 16:47:54 -0800692 VkExtensionProperties* /*properties*/) {
693 // TODO(jessehall): Implement me...
694 *properties_count = 0;
695 return VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700696}
697
Jesse Halle1b12782015-11-30 11:27:32 -0800698VKAPI_ATTR
Jesse Hall80523e22016-01-06 16:47:54 -0800699VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice /*pdev*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800700 uint32_t* properties_count,
Jesse Hall80523e22016-01-06 16:47:54 -0800701 VkLayerProperties* /*properties*/) {
702 // TODO(jessehall): Implement me...
703 *properties_count = 0;
704 return VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800705}
706
707VKAPI_ATTR
708VkResult CreateDevice_Bottom(VkPhysicalDevice pdev,
709 const VkDeviceCreateInfo* create_info,
710 const VkAllocationCallbacks* allocator,
711 VkDevice* device_out) {
712 Instance& instance = GetDispatchParent(pdev);
Jesse Hall04f4f472015-08-16 19:51:04 -0700713 VkResult result;
714
Jesse Hall03b6fe12015-11-24 12:44:21 -0800715 if (!allocator) {
716 if (instance.alloc)
717 allocator = instance.alloc;
718 else
719 allocator = &kDefaultAllocCallbacks;
720 }
721
Jesse Hall3fbc8562015-11-29 22:10:52 -0800722 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
723 alignof(Device),
724 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700725 if (!mem)
726 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500727 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700728
Jesse Hall9a16f972015-10-28 15:59:53 -0700729 result = ActivateAllLayers(create_info, &instance, device);
730 if (result != VK_SUCCESS) {
731 DestroyDevice(device);
732 return result;
733 }
734
Jesse Halla7ac76d2016-01-08 22:29:42 -0800735 const char* kAndroidNativeBufferExtensionName = "VK_ANDROID_native_buffer";
736 VkDeviceCreateInfo driver_create_info = *create_info;
737 driver_create_info.enabledLayerCount = 0;
738 driver_create_info.ppEnabledLayerNames = nullptr;
739 // TODO(jessehall): As soon as we enumerate device extensions supported by
740 // the driver, we need to filter the requested extension list to those
741 // supported by the driver here. Also, add the VK_ANDROID_native_buffer
742 // extension to the list iff the VK_KHR_swapchain extension was requested,
743 // instead of adding it unconditionally like we do now.
744 driver_create_info.enabledExtensionCount = 1;
745 driver_create_info.ppEnabledExtensionNames = &kAndroidNativeBufferExtensionName;
746
Jesse Hall04f4f472015-08-16 19:51:04 -0700747 VkDevice drv_device;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800748 result = instance.drv.dispatch.CreateDevice(pdev, &driver_create_info, allocator,
Jesse Hall1f91d392015-12-11 16:28:44 -0800749 &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700750 if (result != VK_SUCCESS) {
751 DestroyDevice(device);
752 return result;
753 }
754
Jesse Hall1f91d392015-12-11 16:28:44 -0800755 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700756 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800757 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
758 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
759 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500760 PFN_vkDestroyDevice destroy_device =
761 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800762 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
763 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800764 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700765 DestroyDevice(device);
766 return VK_ERROR_INITIALIZATION_FAILED;
767 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800768 drv_dispatch->vtbl = &device->dispatch;
769 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
770 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
771 "vkGetDeviceProcAddr"));
Jesse Hall04f4f472015-08-16 19:51:04 -0700772
Michael Lentine03c64b02015-08-26 18:27:26 -0500773 void* base_object = static_cast<void*>(drv_device);
774 void* next_object = base_object;
775 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800776 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetDeviceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500777 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500778 device->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500779 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
780
781 for (size_t i = elem_list.size(); i > 0; i--) {
782 size_t idx = i - 1;
783 next_element = &elem_list[idx];
784 next_element->get_proc_addr =
785 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
786 next_element->base_object = base_object;
787 next_element->next_element = next_object;
788 next_object = static_cast<void*>(next_element);
789
Jesse Hall80523e22016-01-06 16:47:54 -0800790 next_get_proc_addr = device->active_layers[idx].GetGetDeviceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500791 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800792 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500793 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800794 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500795 }
796 }
797
Jesse Hall1f91d392015-12-11 16:28:44 -0800798 // This is the magic call that initializes all the layer devices and
799 // allows them to create their device_handle -> device_data mapping.
800 next_get_proc_addr(static_cast<VkDevice>(next_object),
801 "vkGetDeviceProcAddr");
802
803 // We must create all the layer devices *before* retrieving the device
804 // procaddrs, so that the layers know which extensions are enabled and
805 // therefore which functions to return procaddrs for.
806 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
807 next_get_proc_addr(drv_device, "vkCreateDevice"));
808 create_device(pdev, create_info, allocator, &drv_device);
809
810 if (!LoadDeviceDispatchTable(static_cast<VkDevice>(base_object),
811 next_get_proc_addr, device->dispatch)) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500812 DestroyDevice(device);
813 return VK_ERROR_INITIALIZATION_FAILED;
814 }
815
Jesse Hall1f91d392015-12-11 16:28:44 -0800816 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700817 return VK_SUCCESS;
818}
819
Jesse Hall1f91d392015-12-11 16:28:44 -0800820void DestroyInstance_Bottom(VkInstance vkinstance,
821 const VkAllocationCallbacks* allocator) {
822 Instance& instance = GetDispatchParent(vkinstance);
823
824 // These checks allow us to call DestroyInstance_Bottom from any error
825 // path in CreateInstance_Bottom, before the driver instance is fully
826 // initialized.
827 if (instance.drv.instance != VK_NULL_HANDLE &&
828 instance.drv.dispatch.DestroyInstance) {
829 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
830 }
831 if (instance.message) {
832 PFN_vkDbgDestroyMsgCallback DebugDestroyMessageCallback;
833 DebugDestroyMessageCallback =
834 reinterpret_cast<PFN_vkDbgDestroyMsgCallback>(
835 vkGetInstanceProcAddr(vkinstance, "vkDbgDestroyMsgCallback"));
836 DebugDestroyMessageCallback(vkinstance, instance.message);
837 }
Jesse Hall80523e22016-01-06 16:47:54 -0800838 instance.active_layers.clear();
Jesse Hall1f91d392015-12-11 16:28:44 -0800839 const VkAllocationCallbacks* alloc = instance.alloc;
840 instance.~Instance();
841 alloc->pfnFree(alloc->pUserData, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700842}
843
Jesse Hall1f91d392015-12-11 16:28:44 -0800844PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
845 const char* name) {
846 if (strcmp(name, "vkCreateDevice") == 0) {
847 // TODO(jessehall): Blegh, having this here is disgusting. The current
848 // layer init process can't call through the instance dispatch table's
849 // vkCreateDevice, because that goes through the instance layers rather
850 // than through the device layers. So we need to be able to get the
851 // vkCreateDevice pointer through the *device* layer chain.
852 //
853 // Because we've already created the driver device before calling
854 // through the layer vkCreateDevice functions, the loader bottom proc
855 // is a no-op.
Michael Lentine03c64b02015-08-26 18:27:26 -0500856 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
857 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800858
859 // VK_ANDROID_native_buffer should be hidden from applications and layers.
860 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
861 PFN_vkVoidFunction pfn;
862 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
863 strcmp(name, "vkAcquireImageANDROID") == 0 ||
864 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
865 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -0500866 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800867 if ((pfn = GetLoaderBottomProcAddr(name)))
868 return pfn;
869 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -0700870}
871
Jesse Hall04f4f472015-08-16 19:51:04 -0700872// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -0800873// Loader top functions. These are called directly from the loader entry
874// points or from the application (via vkGetInstanceProcAddr) without going
875// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -0700876
Jesse Hall1f91d392015-12-11 16:28:44 -0800877VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -0800878 const char* layer_name,
879 uint32_t* properties_count,
880 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700881 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700882 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700883
Jesse Hall80523e22016-01-06 16:47:54 -0800884 const VkExtensionProperties* extensions = nullptr;
885 uint32_t num_extensions = 0;
886 if (layer_name) {
887 GetLayerExtensions(layer_name, &extensions, &num_extensions);
888 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800889 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
890 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
891 available[num_extensions++] = VkExtensionProperties{
892 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
893 available[num_extensions++] =
894 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
895 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
896 if (g_driver_instance_extensions[kEXT_debug_report]) {
897 available[num_extensions++] =
898 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
899 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
900 }
Jesse Hall80523e22016-01-06 16:47:54 -0800901 // TODO(jessehall): We need to also enumerate extensions supported by
902 // implicitly-enabled layers. Currently we don't have that list of
903 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800904 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -0800905 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700906
Jesse Hall80523e22016-01-06 16:47:54 -0800907 if (!properties || *properties_count > num_extensions)
908 *properties_count = num_extensions;
909 if (properties)
910 std::copy(extensions, extensions + *properties_count, properties);
911 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700912}
913
Jesse Hall80523e22016-01-06 16:47:54 -0800914VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
915 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700916 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700917 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700918
Jesse Hall80523e22016-01-06 16:47:54 -0800919 uint32_t layer_count =
920 EnumerateLayers(properties ? *properties_count : 0, properties);
921 if (!properties || *properties_count > layer_count)
922 *properties_count = layer_count;
923 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700924}
925
Jesse Hall1f91d392015-12-11 16:28:44 -0800926VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
927 const VkAllocationCallbacks* allocator,
928 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700929 VkResult result;
930
931 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700932 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700933
Jesse Hall03b6fe12015-11-24 12:44:21 -0800934 if (!allocator)
935 allocator = &kDefaultAllocCallbacks;
936
Jesse Hall04f4f472015-08-16 19:51:04 -0700937 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -0700938 create_info = &local_create_info;
939
Jesse Hall3fbc8562015-11-29 22:10:52 -0800940 void* instance_mem = allocator->pfnAllocation(
941 allocator->pUserData, sizeof(Instance), alignof(Instance),
942 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700943 if (!instance_mem)
944 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800945 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700946
Jesse Hall9a16f972015-10-28 15:59:53 -0700947 result = ActivateAllLayers(create_info, instance, instance);
948 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800949 DestroyInstance_Bottom(instance->handle, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -0700950 return result;
951 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500952
Jesse Hall1f91d392015-12-11 16:28:44 -0800953 void* base_object = static_cast<void*>(instance->handle);
Michael Lentine03c64b02015-08-26 18:27:26 -0500954 void* next_object = base_object;
955 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800956 PFN_vkGetInstanceProcAddr next_get_proc_addr = GetInstanceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500957 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine1f0f5392015-09-11 14:54:34 -0700958 instance->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500959 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
960
961 for (size_t i = elem_list.size(); i > 0; i--) {
962 size_t idx = i - 1;
963 next_element = &elem_list[idx];
964 next_element->get_proc_addr =
965 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
966 next_element->base_object = base_object;
967 next_element->next_element = next_object;
968 next_object = static_cast<void*>(next_element);
969
Jesse Hall80523e22016-01-06 16:47:54 -0800970 next_get_proc_addr =
971 instance->active_layers[idx].GetGetInstanceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500972 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800973 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500974 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800975 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500976 }
977 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800978 instance->get_instance_proc_addr = next_get_proc_addr;
Michael Lentine03c64b02015-08-26 18:27:26 -0500979
Jesse Hall1f91d392015-12-11 16:28:44 -0800980 // This is the magic call that initializes all the layer instances and
981 // allows them to create their instance_handle -> instance_data mapping.
982 next_get_proc_addr(static_cast<VkInstance>(next_object),
983 "vkGetInstanceProcAddr");
984
985 if (!LoadInstanceDispatchTable(static_cast<VkInstance>(base_object),
986 next_get_proc_addr, instance->dispatch)) {
987 DestroyInstance_Bottom(instance->handle, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -0500988 return VK_ERROR_INITIALIZATION_FAILED;
989 }
990
Michael Lentine950bb4f2015-09-14 13:26:30 -0500991 // Force enable callback extension if required
Jesse Hall21597662015-12-18 13:48:24 -0800992 bool enable_callback = false;
993 bool enable_logging = false;
994 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
995 enable_callback =
996 property_get_bool("debug.vulkan.enable_callback", false);
997 enable_logging = enable_callback;
998 if (enable_callback) {
999 enable_callback = AddExtensionToCreateInfo(
1000 local_create_info, "DEBUG_REPORT", instance->alloc);
1001 }
Michael Lentine950bb4f2015-09-14 13:26:30 -05001002 }
1003
Jesse Hall1f91d392015-12-11 16:28:44 -08001004 *instance_out = instance->handle;
1005 PFN_vkCreateInstance create_instance =
1006 reinterpret_cast<PFN_vkCreateInstance>(
1007 next_get_proc_addr(instance->handle, "vkCreateInstance"));
1008 result = create_instance(create_info, allocator, instance_out);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001009 if (enable_callback)
1010 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall04f4f472015-08-16 19:51:04 -07001011 if (result <= 0) {
1012 // For every layer, including the loader top and bottom layers:
1013 // - If a call to the next CreateInstance fails, the layer must clean
1014 // up anything it has successfully done so far, and propagate the
1015 // error upwards.
1016 // - If a layer successfully calls the next layer's CreateInstance, and
1017 // afterwards must fail for some reason, it must call the next layer's
1018 // DestroyInstance before returning.
1019 // - The layer must not call the next layer's DestroyInstance if that
1020 // layer's CreateInstance wasn't called, or returned failure.
1021
Jesse Hall1f91d392015-12-11 16:28:44 -08001022 // On failure, CreateInstance_Bottom frees the instance struct, so it's
Jesse Hall04f4f472015-08-16 19:51:04 -07001023 // already gone at this point. Nothing to do.
1024 }
1025
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001026 if (enable_logging) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001027 PFN_vkDbgCreateMsgCallback dbg_create_msg_callback;
1028 dbg_create_msg_callback = reinterpret_cast<PFN_vkDbgCreateMsgCallback>(
1029 GetInstanceProcAddr_Top(instance->handle,
1030 "vkDbgCreateMsgCallback"));
1031 dbg_create_msg_callback(
1032 instance->handle, VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT,
1033 LogDebugMessageCallback, nullptr, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001034 }
1035
Jesse Hall04f4f472015-08-16 19:51:04 -07001036 return result;
1037}
1038
Jesse Hall1f91d392015-12-11 16:28:44 -08001039PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1040 const char* name) {
1041 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1042 if (!vkinstance)
1043 return GetLoaderGlobalProcAddr(name);
1044
1045 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1046 PFN_vkVoidFunction pfn;
1047 // Always go through the loader-top function if there is one.
1048 if ((pfn = GetLoaderTopProcAddr(name)))
1049 return pfn;
1050 // Otherwise, look up the handler in the instance dispatch table
1051 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1052 return pfn;
1053 // TODO(jessehall): Generate these into the instance dispatch table, and
1054 // add loader-bottom procs for them.
Michael Lentine03c64b02015-08-26 18:27:26 -05001055 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
1056 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001057 return GetDispatchParent(vkinstance)
1058 .get_instance_proc_addr(vkinstance, name);
Michael Lentine03c64b02015-08-26 18:27:26 -05001059 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001060 // Anything not handled already must be a device-dispatched function
1061 // without a loader-top. We must return a function that will dispatch based
1062 // on the dispatchable object parameter -- which is exactly what the
1063 // exported functions do. So just return them here.
1064 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001065}
1066
Jesse Hall1f91d392015-12-11 16:28:44 -08001067void DestroyInstance_Top(VkInstance instance,
1068 const VkAllocationCallbacks* allocator) {
1069 if (!instance)
1070 return;
1071 GetDispatchTable(instance).DestroyInstance(instance, allocator);
1072}
1073
1074PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1075 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001076 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001077 return nullptr;
1078 if ((pfn = GetLoaderTopProcAddr(name)))
1079 return pfn;
1080 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001081}
1082
Jesse Hall1f91d392015-12-11 16:28:44 -08001083void GetDeviceQueue_Top(VkDevice vkdevice,
1084 uint32_t family,
1085 uint32_t index,
1086 VkQueue* queue_out) {
1087 const auto& table = GetDispatchTable(vkdevice);
1088 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1089 hwvulkan_dispatch_t* queue_dispatch =
1090 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1091 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1092 queue_dispatch->vtbl != &table)
1093 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1094 queue_dispatch->magic);
1095 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001096}
1097
Jesse Hall1f91d392015-12-11 16:28:44 -08001098VkResult AllocateCommandBuffers_Top(
1099 VkDevice vkdevice,
1100 const VkCommandBufferAllocateInfo* alloc_info,
1101 VkCommandBuffer* cmdbufs) {
1102 const auto& table = GetDispatchTable(vkdevice);
1103 VkResult result =
1104 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001105 if (result != VK_SUCCESS)
1106 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001107 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001108 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001109 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001110 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001111 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001112 cmdbuf_dispatch->magic);
1113 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001114 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001115 return VK_SUCCESS;
1116}
1117
Jesse Hall1f91d392015-12-11 16:28:44 -08001118void DestroyDevice_Top(VkDevice vkdevice,
1119 const VkAllocationCallbacks* /*allocator*/) {
1120 if (!vkdevice)
1121 return;
1122 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001123 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1124 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001125}
1126
Jesse Hall1f91d392015-12-11 16:28:44 -08001127// -----------------------------------------------------------------------------
1128
1129const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1130 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001131}
1132
Jesse Hall1f91d392015-12-11 16:28:44 -08001133const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1134 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001135}
1136
Jesse Hall1f91d392015-12-11 16:28:44 -08001137const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1138 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001139}
1140
Jesse Hall1f91d392015-12-11 16:28:44 -08001141const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1142 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001143}
1144
Jesse Hall04f4f472015-08-16 19:51:04 -07001145} // namespace vulkan