blob: 5d366fa019c0d01af53aae6a7df76b0740a72180 [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 Hall80523e22016-01-06 16:47:54 -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;
181void LoadVulkanHAL() {
182 static const hwvulkan_module_t* module;
183 int result =
184 hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
185 if (result != 0) {
186 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
187 return;
188 }
189 result = module->common.methods->open(
190 &module->common, HWVULKAN_DEVICE_0,
191 reinterpret_cast<hw_device_t**>(&g_hwdevice));
192 if (result != 0) {
193 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
194 result);
195 module = nullptr;
196 return;
197 }
198}
199
Jesse Hall04f4f472015-08-16 19:51:04 -0700200bool EnsureInitialized() {
201 static std::once_flag once_flag;
Jesse Hall04f4f472015-08-16 19:51:04 -0700202 std::call_once(once_flag, []() {
Jesse Hall80523e22016-01-06 16:47:54 -0800203 LoadVulkanHAL();
204 DiscoverLayers();
Jesse Hall04f4f472015-08-16 19:51:04 -0700205 });
Jesse Hall80523e22016-01-06 16:47:54 -0800206 return g_hwdevice != nullptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700207}
208
Jesse Hall1f91d392015-12-11 16:28:44 -0800209// -----------------------------------------------------------------------------
210
211struct Instance {
212 Instance(const VkAllocationCallbacks* alloc_callbacks)
213 : dispatch_ptr(&dispatch),
214 handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
215 get_instance_proc_addr(nullptr),
216 alloc(alloc_callbacks),
217 num_physical_devices(0),
Jesse Hall80523e22016-01-06 16:47:54 -0800218 active_layers(CallbackAllocator<LayerRef>(alloc)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800219 message(VK_NULL_HANDLE) {
220 memset(&dispatch, 0, sizeof(dispatch));
221 memset(physical_devices, 0, sizeof(physical_devices));
Jesse Hall1f91d392015-12-11 16:28:44 -0800222 drv.instance = VK_NULL_HANDLE;
223 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
224 drv.num_physical_devices = 0;
225 }
226
Jesse Hall80523e22016-01-06 16:47:54 -0800227 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800228
229 const InstanceDispatchTable* dispatch_ptr;
230 const VkInstance handle;
231 InstanceDispatchTable dispatch;
232
233 // TODO(jessehall): Only needed by GetInstanceProcAddr_Top for
234 // vkDbg*MessageCallback. Points to the outermost layer's function. Remove
235 // once the DEBUG_CALLBACK is integrated into the API file.
236 PFN_vkGetInstanceProcAddr get_instance_proc_addr;
237
238 const VkAllocationCallbacks* alloc;
239 uint32_t num_physical_devices;
240 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
241
Jesse Hall80523e22016-01-06 16:47:54 -0800242 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800243 VkDbgMsgCallback message;
244
245 struct {
246 VkInstance instance;
247 DriverDispatchTable dispatch;
248 uint32_t num_physical_devices;
249 } drv; // may eventually be an array
250};
251
252struct Device {
253 Device(Instance* instance_)
254 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800255 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800256 memset(&dispatch, 0, sizeof(dispatch));
257 }
258 DeviceDispatchTable dispatch;
259 Instance* instance;
260 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800261 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800262};
263
264template <typename THandle>
265struct HandleTraits {};
266template <>
267struct HandleTraits<VkInstance> {
268 typedef Instance LoaderObjectType;
269};
270template <>
271struct HandleTraits<VkPhysicalDevice> {
272 typedef Instance LoaderObjectType;
273};
274template <>
275struct HandleTraits<VkDevice> {
276 typedef Device LoaderObjectType;
277};
278template <>
279struct HandleTraits<VkQueue> {
280 typedef Device LoaderObjectType;
281};
282template <>
283struct HandleTraits<VkCommandBuffer> {
284 typedef Device LoaderObjectType;
285};
286
287template <typename THandle>
288typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
289 THandle handle) {
290 // TODO(jessehall): Make Instance and Device POD types (by removing the
291 // non-default constructors), so that offsetof is actually legal to use.
292 // The specific case we're using here is safe in gcc/clang (and probably
293 // most other C++ compilers), but isn't guaranteed by C++.
294 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
295#pragma clang diagnostic push
296#pragma clang diagnostic ignored "-Winvalid-offsetof"
297 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
298#pragma clang diagnostic pop
299
300 const auto& dispatch = GetDispatchTable(handle);
301 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
302 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
303 return *reinterpret_cast<ObjectType*>(object_addr);
304}
305
306// -----------------------------------------------------------------------------
307
Jesse Hall04f4f472015-08-16 19:51:04 -0700308void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800309 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700310 device->~Device();
311 alloc->pfnFree(alloc->pUserData, device);
312}
313
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500314template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800315bool ActivateLayer(TObject* object, const char* name) {
316 LayerRef layer(GetLayerRef(name));
317 if (!layer)
318 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500319 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall80523e22016-01-06 16:47:54 -0800320 layer) == object->active_layers.end())
321 object->active_layers.push_back(std::move(layer));
322 ALOGV("activated layer '%s'", name);
323 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500324}
325
Michael Lentine9da191b2015-10-13 11:08:45 -0500326struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500327 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500328 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500329};
330
Michael Lentine9da191b2015-10-13 11:08:45 -0500331void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500332 const char* value,
333 void* data) {
334 const char prefix[] = "debug.vulkan.layer.";
335 const size_t prefixlen = sizeof(prefix) - 1;
336 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
337 return;
Michael Lentine9da191b2015-10-13 11:08:45 -0500338 const char* number_str = name + prefixlen;
339 long layer_number = strtol(number_str, nullptr, 10);
340 if (layer_number <= 0 || layer_number == LONG_MAX) {
341 ALOGW("Cannot use a layer at number %ld from string %s", layer_number,
342 number_str);
343 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500344 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500345 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
346 Vector<String>* layer_names = instance_names_pair->layer_names;
347 Instance* instance = instance_names_pair->instance;
348 size_t layer_size = static_cast<size_t>(layer_number);
349 if (layer_size > layer_names->size()) {
350 layer_names->resize(layer_size,
351 String(CallbackAllocator<char>(instance->alloc)));
352 }
353 (*layer_names)[layer_size - 1] = value;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500354}
355
356template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800357VkResult ActivateAllLayers(TInfo create_info,
358 Instance* instance,
359 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500360 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
361 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
362 "Cannot activate layers for unknown object %p", object);
363 CallbackAllocator<char> string_allocator(instance->alloc);
364 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800365 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500366 char layer_prop[PROPERTY_VALUE_MAX];
367 property_get("debug.vulkan.layers", layer_prop, "");
368 String layer_name(string_allocator);
369 String layer_prop_str(layer_prop, string_allocator);
370 size_t end, start = 0;
371 while ((end = layer_prop_str.find(':', start)) != std::string::npos) {
372 layer_name = layer_prop_str.substr(start, end - start);
Jesse Hall80523e22016-01-06 16:47:54 -0800373 ActivateLayer(object, layer_name.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500374 start = end + 1;
375 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500376 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
377 InstanceNamesPair instance_names_pair = {.instance = instance,
378 .layer_names = &layer_names};
379 property_list(SetLayerNamesFromProperty,
380 static_cast<void*>(&instance_names_pair));
381 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800382 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500383 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500384 }
385 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800386 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800387 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700388 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800389 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
390 ? "instance"
391 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800392 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700393 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500394 }
395 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700396 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500397}
398
399template <class TCreateInfo>
400bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
401 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800402 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800403 for (uint32_t i = 0; i < local_create_info.enabledExtensionCount; ++i) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500404 if (!strcmp(extension_name,
405 local_create_info.ppEnabledExtensionNames[i])) {
406 return false;
407 }
408 }
Jesse Hall3dd678a2016-01-08 21:52:01 -0800409 uint32_t extension_count = local_create_info.enabledExtensionCount;
410 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800411 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800412 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800413 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
414 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500415 if (mem) {
416 const char** enabled_extensions = static_cast<const char**>(mem);
417 for (uint32_t i = 0; i < extension_count; ++i) {
418 enabled_extensions[i] =
419 local_create_info.ppEnabledExtensionNames[i];
420 }
421 enabled_extensions[extension_count] = extension_name;
422 local_create_info.ppEnabledExtensionNames = enabled_extensions;
423 } else {
424 ALOGW("%s extension cannot be enabled: memory allocation failed",
425 extension_name);
Jesse Hall3dd678a2016-01-08 21:52:01 -0800426 local_create_info.enabledExtensionCount--;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500427 return false;
428 }
429 return true;
430}
431
432template <class T>
433void FreeAllocatedCreateInfo(T& local_create_info,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800434 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500435 alloc->pfnFree(
436 alloc->pUserData,
437 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
438}
439
Jesse Halle1b12782015-11-30 11:27:32 -0800440VKAPI_ATTR
Michael Lentineeb970862015-10-15 12:42:22 -0500441VkBool32 LogDebugMessageCallback(VkFlags message_flags,
442 VkDbgObjectType /*obj_type*/,
443 uint64_t /*src_object*/,
444 size_t /*location*/,
445 int32_t message_code,
446 const char* layer_prefix,
447 const char* message,
448 void* /*user_data*/) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500449 if (message_flags & VK_DBG_REPORT_ERROR_BIT) {
450 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
451 } else if (message_flags & VK_DBG_REPORT_WARN_BIT) {
452 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
453 }
Michael Lentineeb970862015-10-15 12:42:22 -0500454 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500455}
456
Jesse Hall06193802015-12-03 16:12:51 -0800457VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500458 return VK_SUCCESS;
459}
460
Jesse Hall1f91d392015-12-11 16:28:44 -0800461} // anonymous namespace
462
463namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500464
Jesse Hall04f4f472015-08-16 19:51:04 -0700465// -----------------------------------------------------------------------------
466// "Bottom" functions. These are called at the end of the instance dispatch
467// chain.
468
Jesse Hall1f91d392015-12-11 16:28:44 -0800469VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
470 const VkAllocationCallbacks* allocator,
471 VkInstance* vkinstance) {
472 Instance& instance = GetDispatchParent(*vkinstance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700473 VkResult result;
474
Jesse Halla7ac76d2016-01-08 22:29:42 -0800475 VkInstanceCreateInfo driver_create_info = *create_info;
476 driver_create_info.enabledLayerCount = 0;
477 driver_create_info.ppEnabledLayerNames = nullptr;
478 // TODO(jessehall): We currently only enumerate the VK_KHR_surface and
479 // VK_KHR_android_surface extensions, which we don't allow drivers to
480 // support. As soon as we enumerate instance extensions supported by the
481 // driver, we should instead filter the requested extension list here to
482 // only the extensions supported by the driver.
483 driver_create_info.enabledExtensionCount = 0;
484 driver_create_info.ppEnabledExtensionNames = nullptr;
485
486 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800487 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700488 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800489 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700490 return result;
491 }
492
Jesse Hall1f91d392015-12-11 16:28:44 -0800493 if (!LoadDriverDispatchTable(instance.drv.instance,
494 g_hwdevice->GetInstanceProcAddr,
495 instance.drv.dispatch)) {
496 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700497 return VK_ERROR_INITIALIZATION_FAILED;
498 }
499
Jesse Hall1f91d392015-12-11 16:28:44 -0800500 hwvulkan_dispatch_t* drv_dispatch =
501 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
502 if (drv_dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
503 // Skip setting drv_dispatch->vtbl, since we never call through it;
504 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700505 } else {
506 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800507 drv_dispatch->magic);
508 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700509 return VK_ERROR_INITIALIZATION_FAILED;
510 }
511
512 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800513 result = instance.drv.dispatch.EnumeratePhysicalDevices(
514 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700515 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800516 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700517 return VK_ERROR_INITIALIZATION_FAILED;
518 }
519 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800520 result = instance.drv.dispatch.EnumeratePhysicalDevices(
521 instance.drv.instance, &num_physical_devices,
522 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700523 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800524 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700525 return VK_ERROR_INITIALIZATION_FAILED;
526 }
527 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800528 hwvulkan_dispatch_t* pdev_dispatch =
529 reinterpret_cast<hwvulkan_dispatch_t*>(
530 instance.physical_devices[i]);
531 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700532 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800533 pdev_dispatch->magic);
534 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700535 return VK_ERROR_INITIALIZATION_FAILED;
536 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800537 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700538 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800539 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700540
Jesse Hall1f91d392015-12-11 16:28:44 -0800541 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700542 return VK_SUCCESS;
543}
544
Jesse Hall1f91d392015-12-11 16:28:44 -0800545PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
546 PFN_vkVoidFunction pfn;
547 if ((pfn = GetLoaderBottomProcAddr(name)))
548 return pfn;
549 // TODO: Possibly move this into the instance table
550 // TODO: Possibly register the callbacks in the loader
551 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
552 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
553 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
554 }
555 return nullptr;
556}
557
558VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
559 uint32_t* pdev_count,
560 VkPhysicalDevice* pdevs) {
561 Instance& instance = GetDispatchParent(vkinstance);
562 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700563 if (pdevs) {
564 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800565 std::copy(instance.physical_devices, instance.physical_devices + count,
566 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700567 }
568 *pdev_count = count;
569 return VK_SUCCESS;
570}
571
Jesse Hall1f91d392015-12-11 16:28:44 -0800572void GetPhysicalDeviceProperties_Bottom(
573 VkPhysicalDevice pdev,
574 VkPhysicalDeviceProperties* properties) {
575 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
576 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700577}
578
Jesse Hall1f91d392015-12-11 16:28:44 -0800579void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
580 VkPhysicalDeviceFeatures* features) {
581 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
582 features);
583}
584
585void GetPhysicalDeviceMemoryProperties_Bottom(
586 VkPhysicalDevice pdev,
587 VkPhysicalDeviceMemoryProperties* properties) {
588 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
589 pdev, properties);
590}
591
592void GetPhysicalDeviceQueueFamilyProperties_Bottom(
593 VkPhysicalDevice pdev,
594 uint32_t* pCount,
595 VkQueueFamilyProperties* properties) {
596 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
597 pdev, pCount, properties);
598}
599
600void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
601 VkFormat format,
602 VkFormatProperties* properties) {
603 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700604 pdev, format, properties);
605}
606
Jesse Hall1f91d392015-12-11 16:28:44 -0800607VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700608 VkPhysicalDevice pdev,
609 VkFormat format,
610 VkImageType type,
611 VkImageTiling tiling,
612 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700613 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700614 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800615 return GetDispatchParent(pdev)
616 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800617 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700618}
619
Jesse Hall1f91d392015-12-11 16:28:44 -0800620void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700621 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800622 VkFormat format,
623 VkImageType type,
624 VkSampleCountFlagBits samples,
625 VkImageUsageFlags usage,
626 VkImageTiling tiling,
627 uint32_t* properties_count,
628 VkSparseImageFormatProperties* properties) {
629 GetDispatchParent(pdev)
630 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
631 pdev, format, type, samples, usage, tiling, properties_count,
632 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700633}
634
Jesse Halle1b12782015-11-30 11:27:32 -0800635VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800636VkResult EnumerateDeviceExtensionProperties_Bottom(
Jesse Hall80523e22016-01-06 16:47:54 -0800637 VkPhysicalDevice /*pdev*/,
638 const char* /*layer_name*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800639 uint32_t* properties_count,
Jesse Hall80523e22016-01-06 16:47:54 -0800640 VkExtensionProperties* /*properties*/) {
641 // TODO(jessehall): Implement me...
642 *properties_count = 0;
643 return VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700644}
645
Jesse Halle1b12782015-11-30 11:27:32 -0800646VKAPI_ATTR
Jesse Hall80523e22016-01-06 16:47:54 -0800647VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice /*pdev*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800648 uint32_t* properties_count,
Jesse Hall80523e22016-01-06 16:47:54 -0800649 VkLayerProperties* /*properties*/) {
650 // TODO(jessehall): Implement me...
651 *properties_count = 0;
652 return VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800653}
654
655VKAPI_ATTR
656VkResult CreateDevice_Bottom(VkPhysicalDevice pdev,
657 const VkDeviceCreateInfo* create_info,
658 const VkAllocationCallbacks* allocator,
659 VkDevice* device_out) {
660 Instance& instance = GetDispatchParent(pdev);
Jesse Hall04f4f472015-08-16 19:51:04 -0700661 VkResult result;
662
Jesse Hall03b6fe12015-11-24 12:44:21 -0800663 if (!allocator) {
664 if (instance.alloc)
665 allocator = instance.alloc;
666 else
667 allocator = &kDefaultAllocCallbacks;
668 }
669
Jesse Hall3fbc8562015-11-29 22:10:52 -0800670 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
671 alignof(Device),
672 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700673 if (!mem)
674 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500675 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700676
Jesse Hall9a16f972015-10-28 15:59:53 -0700677 result = ActivateAllLayers(create_info, &instance, device);
678 if (result != VK_SUCCESS) {
679 DestroyDevice(device);
680 return result;
681 }
682
Jesse Halla7ac76d2016-01-08 22:29:42 -0800683 const char* kAndroidNativeBufferExtensionName = "VK_ANDROID_native_buffer";
684 VkDeviceCreateInfo driver_create_info = *create_info;
685 driver_create_info.enabledLayerCount = 0;
686 driver_create_info.ppEnabledLayerNames = nullptr;
687 // TODO(jessehall): As soon as we enumerate device extensions supported by
688 // the driver, we need to filter the requested extension list to those
689 // supported by the driver here. Also, add the VK_ANDROID_native_buffer
690 // extension to the list iff the VK_KHR_swapchain extension was requested,
691 // instead of adding it unconditionally like we do now.
692 driver_create_info.enabledExtensionCount = 1;
693 driver_create_info.ppEnabledExtensionNames = &kAndroidNativeBufferExtensionName;
694
Jesse Hall04f4f472015-08-16 19:51:04 -0700695 VkDevice drv_device;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800696 result = instance.drv.dispatch.CreateDevice(pdev, &driver_create_info, allocator,
Jesse Hall1f91d392015-12-11 16:28:44 -0800697 &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700698 if (result != VK_SUCCESS) {
699 DestroyDevice(device);
700 return result;
701 }
702
Jesse Hall1f91d392015-12-11 16:28:44 -0800703 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700704 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800705 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
706 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
707 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500708 PFN_vkDestroyDevice destroy_device =
709 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800710 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
711 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800712 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700713 DestroyDevice(device);
714 return VK_ERROR_INITIALIZATION_FAILED;
715 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800716 drv_dispatch->vtbl = &device->dispatch;
717 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
718 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
719 "vkGetDeviceProcAddr"));
Jesse Hall04f4f472015-08-16 19:51:04 -0700720
Michael Lentine03c64b02015-08-26 18:27:26 -0500721 void* base_object = static_cast<void*>(drv_device);
722 void* next_object = base_object;
723 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800724 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetDeviceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500725 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500726 device->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500727 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
728
729 for (size_t i = elem_list.size(); i > 0; i--) {
730 size_t idx = i - 1;
731 next_element = &elem_list[idx];
732 next_element->get_proc_addr =
733 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
734 next_element->base_object = base_object;
735 next_element->next_element = next_object;
736 next_object = static_cast<void*>(next_element);
737
Jesse Hall80523e22016-01-06 16:47:54 -0800738 next_get_proc_addr = device->active_layers[idx].GetGetDeviceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500739 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800740 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500741 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800742 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500743 }
744 }
745
Jesse Hall1f91d392015-12-11 16:28:44 -0800746 // This is the magic call that initializes all the layer devices and
747 // allows them to create their device_handle -> device_data mapping.
748 next_get_proc_addr(static_cast<VkDevice>(next_object),
749 "vkGetDeviceProcAddr");
750
751 // We must create all the layer devices *before* retrieving the device
752 // procaddrs, so that the layers know which extensions are enabled and
753 // therefore which functions to return procaddrs for.
754 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
755 next_get_proc_addr(drv_device, "vkCreateDevice"));
756 create_device(pdev, create_info, allocator, &drv_device);
757
758 if (!LoadDeviceDispatchTable(static_cast<VkDevice>(base_object),
759 next_get_proc_addr, device->dispatch)) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500760 DestroyDevice(device);
761 return VK_ERROR_INITIALIZATION_FAILED;
762 }
763
Jesse Hall1f91d392015-12-11 16:28:44 -0800764 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700765 return VK_SUCCESS;
766}
767
Jesse Hall1f91d392015-12-11 16:28:44 -0800768void DestroyInstance_Bottom(VkInstance vkinstance,
769 const VkAllocationCallbacks* allocator) {
770 Instance& instance = GetDispatchParent(vkinstance);
771
772 // These checks allow us to call DestroyInstance_Bottom from any error
773 // path in CreateInstance_Bottom, before the driver instance is fully
774 // initialized.
775 if (instance.drv.instance != VK_NULL_HANDLE &&
776 instance.drv.dispatch.DestroyInstance) {
777 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
778 }
779 if (instance.message) {
780 PFN_vkDbgDestroyMsgCallback DebugDestroyMessageCallback;
781 DebugDestroyMessageCallback =
782 reinterpret_cast<PFN_vkDbgDestroyMsgCallback>(
783 vkGetInstanceProcAddr(vkinstance, "vkDbgDestroyMsgCallback"));
784 DebugDestroyMessageCallback(vkinstance, instance.message);
785 }
Jesse Hall80523e22016-01-06 16:47:54 -0800786 instance.active_layers.clear();
Jesse Hall1f91d392015-12-11 16:28:44 -0800787 const VkAllocationCallbacks* alloc = instance.alloc;
788 instance.~Instance();
789 alloc->pfnFree(alloc->pUserData, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700790}
791
Jesse Hall1f91d392015-12-11 16:28:44 -0800792PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
793 const char* name) {
794 if (strcmp(name, "vkCreateDevice") == 0) {
795 // TODO(jessehall): Blegh, having this here is disgusting. The current
796 // layer init process can't call through the instance dispatch table's
797 // vkCreateDevice, because that goes through the instance layers rather
798 // than through the device layers. So we need to be able to get the
799 // vkCreateDevice pointer through the *device* layer chain.
800 //
801 // Because we've already created the driver device before calling
802 // through the layer vkCreateDevice functions, the loader bottom proc
803 // is a no-op.
Michael Lentine03c64b02015-08-26 18:27:26 -0500804 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
805 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800806
807 // VK_ANDROID_native_buffer should be hidden from applications and layers.
808 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
809 PFN_vkVoidFunction pfn;
810 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
811 strcmp(name, "vkAcquireImageANDROID") == 0 ||
812 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
813 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -0500814 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800815 if ((pfn = GetLoaderBottomProcAddr(name)))
816 return pfn;
817 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -0700818}
819
Jesse Hall04f4f472015-08-16 19:51:04 -0700820// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -0800821// Loader top functions. These are called directly from the loader entry
822// points or from the application (via vkGetInstanceProcAddr) without going
823// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -0700824
Jesse Hall1f91d392015-12-11 16:28:44 -0800825VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -0800826 const char* layer_name,
827 uint32_t* properties_count,
828 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700829 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700830 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700831
Jesse Hall80523e22016-01-06 16:47:54 -0800832 const VkExtensionProperties* extensions = nullptr;
833 uint32_t num_extensions = 0;
834 if (layer_name) {
835 GetLayerExtensions(layer_name, &extensions, &num_extensions);
836 } else {
Jesse Hall543a7ff2016-01-08 16:38:30 -0800837 static const VkExtensionProperties kInstanceExtensions[] = {
838 {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION},
839 {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
840 VK_KHR_ANDROID_SURFACE_SPEC_VERSION}};
Jesse Hall80523e22016-01-06 16:47:54 -0800841 extensions = kInstanceExtensions;
842 num_extensions = sizeof(kInstanceExtensions) / sizeof(kInstanceExtensions[0]);
Jesse Halla7ac76d2016-01-08 22:29:42 -0800843
Jesse Hall80523e22016-01-06 16:47:54 -0800844 // TODO(jessehall): We need to also enumerate extensions supported by
845 // implicitly-enabled layers. Currently we don't have that list of
846 // layers until instance creation.
Jesse Halla7ac76d2016-01-08 22:29:42 -0800847
848 // TODO(jessehall): We need to also enumerate extensions supported by
849 // any driver.
Jesse Hall80523e22016-01-06 16:47:54 -0800850 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700851
Jesse Hall80523e22016-01-06 16:47:54 -0800852 if (!properties || *properties_count > num_extensions)
853 *properties_count = num_extensions;
854 if (properties)
855 std::copy(extensions, extensions + *properties_count, properties);
856 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700857}
858
Jesse Hall80523e22016-01-06 16:47:54 -0800859VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
860 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700861 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700862 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700863
Jesse Hall80523e22016-01-06 16:47:54 -0800864 uint32_t layer_count =
865 EnumerateLayers(properties ? *properties_count : 0, properties);
866 if (!properties || *properties_count > layer_count)
867 *properties_count = layer_count;
868 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700869}
870
Jesse Hall1f91d392015-12-11 16:28:44 -0800871VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
872 const VkAllocationCallbacks* allocator,
873 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700874 VkResult result;
875
876 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700877 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700878
Jesse Hall03b6fe12015-11-24 12:44:21 -0800879 if (!allocator)
880 allocator = &kDefaultAllocCallbacks;
881
Jesse Hall04f4f472015-08-16 19:51:04 -0700882 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -0700883 create_info = &local_create_info;
884
Jesse Hall3fbc8562015-11-29 22:10:52 -0800885 void* instance_mem = allocator->pfnAllocation(
886 allocator->pUserData, sizeof(Instance), alignof(Instance),
887 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700888 if (!instance_mem)
889 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800890 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700891
Jesse Hall9a16f972015-10-28 15:59:53 -0700892 result = ActivateAllLayers(create_info, instance, instance);
893 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800894 DestroyInstance_Bottom(instance->handle, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -0700895 return result;
896 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500897
Jesse Hall1f91d392015-12-11 16:28:44 -0800898 void* base_object = static_cast<void*>(instance->handle);
Michael Lentine03c64b02015-08-26 18:27:26 -0500899 void* next_object = base_object;
900 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800901 PFN_vkGetInstanceProcAddr next_get_proc_addr = GetInstanceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500902 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine1f0f5392015-09-11 14:54:34 -0700903 instance->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500904 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
905
906 for (size_t i = elem_list.size(); i > 0; i--) {
907 size_t idx = i - 1;
908 next_element = &elem_list[idx];
909 next_element->get_proc_addr =
910 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
911 next_element->base_object = base_object;
912 next_element->next_element = next_object;
913 next_object = static_cast<void*>(next_element);
914
Jesse Hall80523e22016-01-06 16:47:54 -0800915 next_get_proc_addr =
916 instance->active_layers[idx].GetGetInstanceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500917 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800918 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500919 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800920 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500921 }
922 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800923 instance->get_instance_proc_addr = next_get_proc_addr;
Michael Lentine03c64b02015-08-26 18:27:26 -0500924
Jesse Hall1f91d392015-12-11 16:28:44 -0800925 // This is the magic call that initializes all the layer instances and
926 // allows them to create their instance_handle -> instance_data mapping.
927 next_get_proc_addr(static_cast<VkInstance>(next_object),
928 "vkGetInstanceProcAddr");
929
930 if (!LoadInstanceDispatchTable(static_cast<VkInstance>(base_object),
931 next_get_proc_addr, instance->dispatch)) {
932 DestroyInstance_Bottom(instance->handle, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -0500933 return VK_ERROR_INITIALIZATION_FAILED;
934 }
935
Michael Lentine950bb4f2015-09-14 13:26:30 -0500936 // Force enable callback extension if required
Jesse Hall21597662015-12-18 13:48:24 -0800937 bool enable_callback = false;
938 bool enable_logging = false;
939 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
940 enable_callback =
941 property_get_bool("debug.vulkan.enable_callback", false);
942 enable_logging = enable_callback;
943 if (enable_callback) {
944 enable_callback = AddExtensionToCreateInfo(
945 local_create_info, "DEBUG_REPORT", instance->alloc);
946 }
Michael Lentine950bb4f2015-09-14 13:26:30 -0500947 }
948
Jesse Hall1f91d392015-12-11 16:28:44 -0800949 *instance_out = instance->handle;
950 PFN_vkCreateInstance create_instance =
951 reinterpret_cast<PFN_vkCreateInstance>(
952 next_get_proc_addr(instance->handle, "vkCreateInstance"));
953 result = create_instance(create_info, allocator, instance_out);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500954 if (enable_callback)
955 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall04f4f472015-08-16 19:51:04 -0700956 if (result <= 0) {
957 // For every layer, including the loader top and bottom layers:
958 // - If a call to the next CreateInstance fails, the layer must clean
959 // up anything it has successfully done so far, and propagate the
960 // error upwards.
961 // - If a layer successfully calls the next layer's CreateInstance, and
962 // afterwards must fail for some reason, it must call the next layer's
963 // DestroyInstance before returning.
964 // - The layer must not call the next layer's DestroyInstance if that
965 // layer's CreateInstance wasn't called, or returned failure.
966
Jesse Hall1f91d392015-12-11 16:28:44 -0800967 // On failure, CreateInstance_Bottom frees the instance struct, so it's
Jesse Hall04f4f472015-08-16 19:51:04 -0700968 // already gone at this point. Nothing to do.
969 }
970
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500971 if (enable_logging) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800972 PFN_vkDbgCreateMsgCallback dbg_create_msg_callback;
973 dbg_create_msg_callback = reinterpret_cast<PFN_vkDbgCreateMsgCallback>(
974 GetInstanceProcAddr_Top(instance->handle,
975 "vkDbgCreateMsgCallback"));
976 dbg_create_msg_callback(
977 instance->handle, VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT,
978 LogDebugMessageCallback, nullptr, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500979 }
980
Jesse Hall04f4f472015-08-16 19:51:04 -0700981 return result;
982}
983
Jesse Hall1f91d392015-12-11 16:28:44 -0800984PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
985 const char* name) {
986 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
987 if (!vkinstance)
988 return GetLoaderGlobalProcAddr(name);
989
990 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
991 PFN_vkVoidFunction pfn;
992 // Always go through the loader-top function if there is one.
993 if ((pfn = GetLoaderTopProcAddr(name)))
994 return pfn;
995 // Otherwise, look up the handler in the instance dispatch table
996 if ((pfn = GetDispatchProcAddr(dispatch, name)))
997 return pfn;
998 // TODO(jessehall): Generate these into the instance dispatch table, and
999 // add loader-bottom procs for them.
Michael Lentine03c64b02015-08-26 18:27:26 -05001000 if (strcmp(name, "vkDbgCreateMsgCallback") == 0 ||
1001 strcmp(name, "vkDbgDestroyMsgCallback") == 0) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001002 return GetDispatchParent(vkinstance)
1003 .get_instance_proc_addr(vkinstance, name);
Michael Lentine03c64b02015-08-26 18:27:26 -05001004 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001005 // Anything not handled already must be a device-dispatched function
1006 // without a loader-top. We must return a function that will dispatch based
1007 // on the dispatchable object parameter -- which is exactly what the
1008 // exported functions do. So just return them here.
1009 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001010}
1011
Jesse Hall1f91d392015-12-11 16:28:44 -08001012void DestroyInstance_Top(VkInstance instance,
1013 const VkAllocationCallbacks* allocator) {
1014 if (!instance)
1015 return;
1016 GetDispatchTable(instance).DestroyInstance(instance, allocator);
1017}
1018
1019PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1020 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001021 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001022 return nullptr;
1023 if ((pfn = GetLoaderTopProcAddr(name)))
1024 return pfn;
1025 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001026}
1027
Jesse Hall1f91d392015-12-11 16:28:44 -08001028void GetDeviceQueue_Top(VkDevice vkdevice,
1029 uint32_t family,
1030 uint32_t index,
1031 VkQueue* queue_out) {
1032 const auto& table = GetDispatchTable(vkdevice);
1033 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1034 hwvulkan_dispatch_t* queue_dispatch =
1035 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1036 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1037 queue_dispatch->vtbl != &table)
1038 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1039 queue_dispatch->magic);
1040 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001041}
1042
Jesse Hall1f91d392015-12-11 16:28:44 -08001043VkResult AllocateCommandBuffers_Top(
1044 VkDevice vkdevice,
1045 const VkCommandBufferAllocateInfo* alloc_info,
1046 VkCommandBuffer* cmdbufs) {
1047 const auto& table = GetDispatchTable(vkdevice);
1048 VkResult result =
1049 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001050 if (result != VK_SUCCESS)
1051 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001052 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001053 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001054 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001055 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001056 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001057 cmdbuf_dispatch->magic);
1058 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001059 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001060 return VK_SUCCESS;
1061}
1062
Jesse Hall1f91d392015-12-11 16:28:44 -08001063void DestroyDevice_Top(VkDevice vkdevice,
1064 const VkAllocationCallbacks* /*allocator*/) {
1065 if (!vkdevice)
1066 return;
1067 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001068 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1069 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001070}
1071
Jesse Hall1f91d392015-12-11 16:28:44 -08001072// -----------------------------------------------------------------------------
1073
1074const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1075 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001076}
1077
Jesse Hall1f91d392015-12-11 16:28:44 -08001078const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1079 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001080}
1081
Jesse Hall1f91d392015-12-11 16:28:44 -08001082const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1083 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001084}
1085
Jesse Hall1f91d392015-12-11 16:28:44 -08001086const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1087 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001088}
1089
Jesse Hall04f4f472015-08-16 19:51:04 -07001090} // namespace vulkan