blob: ba5414e8fe9774778514d0b3b4f52bf5cc1ff250 [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 Hall04f4f472015-08-16 19:51:04 -070017// module header
18#include "loader.h"
19// standard C headers
Michael Lentine03c64b02015-08-26 18:27:26 -050020#include <dirent.h>
21#include <dlfcn.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070022#include <inttypes.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070023#include <pthread.h>
Jesse Hall03b6fe12015-11-24 12:44:21 -080024#include <stdlib.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070025#include <string.h>
Jesse Hall21597662015-12-18 13:48:24 -080026#include <sys/prctl.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070027// standard C++ headers
28#include <algorithm>
29#include <mutex>
Michael Lentine03c64b02015-08-26 18:27:26 -050030#include <sstream>
31#include <string>
32#include <unordered_map>
33#include <vector>
Jesse Hall04f4f472015-08-16 19:51:04 -070034// platform/library headers
Michael Lentine03c64b02015-08-26 18:27:26 -050035#include <cutils/properties.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070036#include <hardware/hwvulkan.h>
37#include <log/log.h>
Michael Lentine1c69b9e2015-09-14 13:26:59 -050038#include <vulkan/vulkan_loader_data.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070039
Jesse Hall26cecff2016-01-21 19:52:25 -080040// #define ENABLE_ALLOC_CALLSTACKS 1
41#if ENABLE_ALLOC_CALLSTACKS
42#include <utils/CallStack.h>
43#define ALOGD_CALLSTACK(...) \
44 do { \
45 ALOGD(__VA_ARGS__); \
46 android::CallStack callstack; \
47 callstack.update(); \
48 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
49 } while (false)
50#else
51#define ALOGD_CALLSTACK(...) \
52 do { \
53 } while (false)
54#endif
55
Jesse Hall04f4f472015-08-16 19:51:04 -070056using namespace vulkan;
57
58static const uint32_t kMaxPhysicalDevices = 4;
59
Michael Lentine03c64b02015-08-26 18:27:26 -050060namespace {
61
62// These definitions are taken from the LunarG Vulkan Loader. They are used to
63// enforce compatability between the Loader and Layers.
64typedef void* (*PFN_vkGetProcAddr)(void* obj, const char* pName);
65
66typedef struct VkLayerLinkedListElem_ {
67 PFN_vkGetProcAddr get_proc_addr;
68 void* next_element;
69 void* base_object;
70} VkLayerLinkedListElem;
71
Jesse Hall1f91d392015-12-11 16:28:44 -080072// ----------------------------------------------------------------------------
Michael Lentine03c64b02015-08-26 18:27:26 -050073
Jesse Hall3fbc8562015-11-29 22:10:52 -080074// Standard-library allocator that delegates to VkAllocationCallbacks.
Jesse Hall03b6fe12015-11-24 12:44:21 -080075//
76// TODO(jessehall): This class currently always uses
Jesse Hall3fbc8562015-11-29 22:10:52 -080077// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template
Jesse Hall03b6fe12015-11-24 12:44:21 -080078// parameter or a constructor parameter. The former would help catch bugs
79// where we use the wrong scope, e.g. adding a command-scope string to an
80// instance-scope vector. But that might also be pretty annoying to deal with.
Michael Lentine03c64b02015-08-26 18:27:26 -050081template <class T>
82class CallbackAllocator {
83 public:
84 typedef T value_type;
85
Jesse Hall3fbc8562015-11-29 22:10:52 -080086 CallbackAllocator(const VkAllocationCallbacks* alloc_input)
Michael Lentine03c64b02015-08-26 18:27:26 -050087 : alloc(alloc_input) {}
88
89 template <class T2>
90 CallbackAllocator(const CallbackAllocator<T2>& other)
91 : alloc(other.alloc) {}
92
93 T* allocate(std::size_t n) {
Jesse Hall3fbc8562015-11-29 22:10:52 -080094 void* mem =
95 alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T),
96 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall26cecff2016-01-21 19:52:25 -080097 if (!mem)
98 throw std::bad_alloc();
Michael Lentine03c64b02015-08-26 18:27:26 -050099 return static_cast<T*>(mem);
100 }
101
Jesse Hall26cecff2016-01-21 19:52:25 -0800102 void deallocate(T* array, std::size_t /*n*/) noexcept {
Michael Lentine03c64b02015-08-26 18:27:26 -0500103 alloc->pfnFree(alloc->pUserData, array);
104 }
105
Jesse Hall3fbc8562015-11-29 22:10:52 -0800106 const VkAllocationCallbacks* alloc;
Michael Lentine03c64b02015-08-26 18:27:26 -0500107};
108// These are needed in order to move Strings
109template <class T>
110bool operator==(const CallbackAllocator<T>& alloc1,
111 const CallbackAllocator<T>& alloc2) {
112 return alloc1.alloc == alloc2.alloc;
113}
114template <class T>
115bool operator!=(const CallbackAllocator<T>& alloc1,
116 const CallbackAllocator<T>& alloc2) {
117 return !(alloc1 == alloc2);
118}
119
Michael Lentine03c64b02015-08-26 18:27:26 -0500120template <class T>
Jesse Hall1f91d392015-12-11 16:28:44 -0800121using Vector = std::vector<T, CallbackAllocator<T>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500122
Jesse Hall1f91d392015-12-11 16:28:44 -0800123typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>>
124 String;
Michael Lentine03c64b02015-08-26 18:27:26 -0500125
Jesse Hall1f91d392015-12-11 16:28:44 -0800126// ----------------------------------------------------------------------------
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500127
Jesse Halle1b12782015-11-30 11:27:32 -0800128VKAPI_ATTR void* DefaultAllocate(void*,
129 size_t size,
130 size_t alignment,
131 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800132 void* ptr = nullptr;
133 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
134 // additionally requires that it be at least sizeof(void*).
Jesse Hall26cecff2016-01-21 19:52:25 -0800135 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
136 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
137 ret, ptr);
138 return ret == 0 ? ptr : nullptr;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800139}
140
Jesse Halle1b12782015-11-30 11:27:32 -0800141VKAPI_ATTR void* DefaultReallocate(void*,
142 void* ptr,
143 size_t size,
144 size_t alignment,
145 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800146 if (size == 0) {
147 free(ptr);
148 return nullptr;
149 }
150
151 // TODO(jessehall): Right now we never shrink allocations; if the new
152 // request is smaller than the existing chunk, we just continue using it.
153 // Right now the loader never reallocs, so this doesn't matter. If that
154 // changes, or if this code is copied into some other project, this should
155 // probably have a heuristic to allocate-copy-free when doing so will save
156 // "enough" space.
157 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
158 if (size <= old_size)
159 return ptr;
160
161 void* new_ptr = nullptr;
162 if (posix_memalign(&new_ptr, alignment, size) != 0)
163 return nullptr;
164 if (ptr) {
165 memcpy(new_ptr, ptr, std::min(old_size, size));
166 free(ptr);
167 }
168 return new_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700169}
170
Jesse Hall26cecff2016-01-21 19:52:25 -0800171VKAPI_ATTR void DefaultFree(void*, void* ptr) {
172 ALOGD_CALLSTACK("Free: %p", ptr);
173 free(ptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700174}
175
Jesse Hall3fbc8562015-11-29 22:10:52 -0800176const VkAllocationCallbacks kDefaultAllocCallbacks = {
Jesse Hall04f4f472015-08-16 19:51:04 -0700177 .pUserData = nullptr,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800178 .pfnAllocation = DefaultAllocate,
179 .pfnReallocation = DefaultReallocate,
Jesse Hall04f4f472015-08-16 19:51:04 -0700180 .pfnFree = DefaultFree,
181};
182
Jesse Hall1f91d392015-12-11 16:28:44 -0800183// ----------------------------------------------------------------------------
Jesse Hall80523e22016-01-06 16:47:54 -0800184// Global Data and Initialization
Jesse Hall1f91d392015-12-11 16:28:44 -0800185
Jesse Hall80523e22016-01-06 16:47:54 -0800186hwvulkan_device_t* g_hwdevice = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800187InstanceExtensionSet g_driver_instance_extensions;
188
Jesse Hall80523e22016-01-06 16:47:54 -0800189void LoadVulkanHAL() {
190 static const hwvulkan_module_t* module;
191 int result =
192 hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
193 if (result != 0) {
194 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
195 return;
196 }
197 result = module->common.methods->open(
198 &module->common, HWVULKAN_DEVICE_0,
199 reinterpret_cast<hw_device_t**>(&g_hwdevice));
200 if (result != 0) {
201 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
202 result);
203 module = nullptr;
204 return;
205 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800206
207 VkResult vkresult;
208 uint32_t count;
209 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
210 nullptr, &count, nullptr)) != VK_SUCCESS) {
211 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
212 vkresult);
213 g_hwdevice->common.close(&g_hwdevice->common);
214 g_hwdevice = nullptr;
215 module = nullptr;
216 return;
217 }
218 VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>(
219 alloca(count * sizeof(VkExtensionProperties)));
220 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
221 nullptr, &count, extensions)) != VK_SUCCESS) {
222 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
223 vkresult);
224 g_hwdevice->common.close(&g_hwdevice->common);
225 g_hwdevice = nullptr;
226 module = nullptr;
227 return;
228 }
229 ALOGV_IF(count > 0, "Driver-supported instance extensions:");
230 for (uint32_t i = 0; i < count; i++) {
231 ALOGV(" %s (v%u)", extensions[i].extensionName,
232 extensions[i].specVersion);
233 InstanceExtension id =
234 InstanceExtensionFromName(extensions[i].extensionName);
235 if (id != kInstanceExtensionCount)
236 g_driver_instance_extensions.set(id);
237 }
238 // Ignore driver attempts to support loader extensions
239 g_driver_instance_extensions.reset(kKHR_surface);
240 g_driver_instance_extensions.reset(kKHR_android_surface);
Jesse Hall80523e22016-01-06 16:47:54 -0800241}
242
Jesse Hall04f4f472015-08-16 19:51:04 -0700243bool EnsureInitialized() {
244 static std::once_flag once_flag;
Jesse Hall04f4f472015-08-16 19:51:04 -0700245 std::call_once(once_flag, []() {
Jesse Hall80523e22016-01-06 16:47:54 -0800246 LoadVulkanHAL();
247 DiscoverLayers();
Jesse Hall04f4f472015-08-16 19:51:04 -0700248 });
Jesse Hall80523e22016-01-06 16:47:54 -0800249 return g_hwdevice != nullptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700250}
251
Jesse Hall1f91d392015-12-11 16:28:44 -0800252// -----------------------------------------------------------------------------
253
254struct Instance {
255 Instance(const VkAllocationCallbacks* alloc_callbacks)
256 : dispatch_ptr(&dispatch),
257 handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800258 alloc(alloc_callbacks),
259 num_physical_devices(0),
Jesse Hall80523e22016-01-06 16:47:54 -0800260 active_layers(CallbackAllocator<LayerRef>(alloc)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800261 message(VK_NULL_HANDLE) {
262 memset(&dispatch, 0, sizeof(dispatch));
263 memset(physical_devices, 0, sizeof(physical_devices));
Jesse Hall1f91d392015-12-11 16:28:44 -0800264 drv.instance = VK_NULL_HANDLE;
265 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
266 drv.num_physical_devices = 0;
267 }
268
Jesse Hall80523e22016-01-06 16:47:54 -0800269 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800270
271 const InstanceDispatchTable* dispatch_ptr;
272 const VkInstance handle;
273 InstanceDispatchTable dispatch;
274
Jesse Hall1f91d392015-12-11 16:28:44 -0800275 const VkAllocationCallbacks* alloc;
276 uint32_t num_physical_devices;
277 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
Jesse Hallb1471272016-01-17 21:36:58 -0800278 DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800279
Jesse Hall80523e22016-01-06 16:47:54 -0800280 Vector<LayerRef> active_layers;
Jesse Hall715b86a2016-01-16 16:34:29 -0800281 VkDebugReportCallbackEXT message;
282 DebugReportCallbackList debug_report_callbacks;
Jesse Hall1f91d392015-12-11 16:28:44 -0800283
284 struct {
285 VkInstance instance;
286 DriverDispatchTable dispatch;
287 uint32_t num_physical_devices;
288 } drv; // may eventually be an array
289};
290
291struct Device {
292 Device(Instance* instance_)
293 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800294 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800295 memset(&dispatch, 0, sizeof(dispatch));
296 }
297 DeviceDispatchTable dispatch;
298 Instance* instance;
299 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800300 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800301};
302
303template <typename THandle>
304struct HandleTraits {};
305template <>
306struct HandleTraits<VkInstance> {
307 typedef Instance LoaderObjectType;
308};
309template <>
310struct HandleTraits<VkPhysicalDevice> {
311 typedef Instance LoaderObjectType;
312};
313template <>
314struct HandleTraits<VkDevice> {
315 typedef Device LoaderObjectType;
316};
317template <>
318struct HandleTraits<VkQueue> {
319 typedef Device LoaderObjectType;
320};
321template <>
322struct HandleTraits<VkCommandBuffer> {
323 typedef Device LoaderObjectType;
324};
325
326template <typename THandle>
327typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
328 THandle handle) {
329 // TODO(jessehall): Make Instance and Device POD types (by removing the
330 // non-default constructors), so that offsetof is actually legal to use.
331 // The specific case we're using here is safe in gcc/clang (and probably
332 // most other C++ compilers), but isn't guaranteed by C++.
333 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
334#pragma clang diagnostic push
335#pragma clang diagnostic ignored "-Winvalid-offsetof"
336 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
337#pragma clang diagnostic pop
338
339 const auto& dispatch = GetDispatchTable(handle);
340 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
341 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
342 return *reinterpret_cast<ObjectType*>(object_addr);
343}
344
345// -----------------------------------------------------------------------------
346
Jesse Hall04f4f472015-08-16 19:51:04 -0700347void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800348 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700349 device->~Device();
350 alloc->pfnFree(alloc->pUserData, device);
351}
352
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500353template <class TObject>
Jesse Hallaa410942016-01-17 13:07:10 -0800354LayerRef GetLayerRef(const char* name);
355template <>
356LayerRef GetLayerRef<Instance>(const char* name) {
357 return GetInstanceLayerRef(name);
358}
359template <>
360LayerRef GetLayerRef<Device>(const char* name) {
361 return GetDeviceLayerRef(name);
362}
363
364template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800365bool ActivateLayer(TObject* object, const char* name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800366 LayerRef layer(GetLayerRef<TObject>(name));
Jesse Hall80523e22016-01-06 16:47:54 -0800367 if (!layer)
368 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500369 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall26cecff2016-01-21 19:52:25 -0800370 layer) == object->active_layers.end()) {
371 try {
372 object->active_layers.push_back(std::move(layer));
373 } catch (std::bad_alloc&) {
374 // TODO(jessehall): We should fail with VK_ERROR_OUT_OF_MEMORY
375 // if we can't enable a requested layer. Callers currently ignore
376 // ActivateLayer's return value.
377 ALOGW("failed to activate layer '%s': out of memory", name);
378 return false;
379 }
380 }
Jesse Hall80523e22016-01-06 16:47:54 -0800381 ALOGV("activated layer '%s'", name);
382 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500383}
384
Michael Lentine9da191b2015-10-13 11:08:45 -0500385struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500386 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500387 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500388};
389
Michael Lentine9da191b2015-10-13 11:08:45 -0500390void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500391 const char* value,
392 void* data) {
Jesse Hall26cecff2016-01-21 19:52:25 -0800393 try {
394 const char prefix[] = "debug.vulkan.layer.";
395 const size_t prefixlen = sizeof(prefix) - 1;
396 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
397 return;
398 const char* number_str = name + prefixlen;
399 long layer_number = strtol(number_str, nullptr, 10);
400 if (layer_number <= 0 || layer_number == LONG_MAX) {
401 ALOGW("Cannot use a layer at number %ld from string %s",
402 layer_number, number_str);
403 return;
404 }
405 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
406 Vector<String>* layer_names = instance_names_pair->layer_names;
407 Instance* instance = instance_names_pair->instance;
408 size_t layer_size = static_cast<size_t>(layer_number);
409 if (layer_size > layer_names->size()) {
410 layer_names->resize(
411 layer_size, String(CallbackAllocator<char>(instance->alloc)));
412 }
413 (*layer_names)[layer_size - 1] = value;
414 } catch (std::bad_alloc&) {
415 ALOGW("failed to handle property '%s'='%s': out of memory", name,
416 value);
Michael Lentine9da191b2015-10-13 11:08:45 -0500417 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500418 }
419}
420
421template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800422VkResult ActivateAllLayers(TInfo create_info,
423 Instance* instance,
424 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500425 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
426 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
427 "Cannot activate layers for unknown object %p", object);
428 CallbackAllocator<char> string_allocator(instance->alloc);
429 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800430 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500431 char layer_prop[PROPERTY_VALUE_MAX];
432 property_get("debug.vulkan.layers", layer_prop, "");
Jesse Hall26cecff2016-01-21 19:52:25 -0800433 char* strtok_state;
434 char* layer_name = nullptr;
435 while ((layer_name = strtok_r(layer_name ? nullptr : layer_prop, ":",
436 &strtok_state))) {
437 ActivateLayer(object, layer_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500438 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500439 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
440 InstanceNamesPair instance_names_pair = {.instance = instance,
441 .layer_names = &layer_names};
442 property_list(SetLayerNamesFromProperty,
443 static_cast<void*>(&instance_names_pair));
444 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800445 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500446 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500447 }
448 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800449 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800450 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700451 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800452 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
453 ? "instance"
454 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800455 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700456 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500457 }
458 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700459 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500460}
461
462template <class TCreateInfo>
463bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
464 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800465 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800466 for (uint32_t i = 0; i < local_create_info.enabledExtensionCount; ++i) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500467 if (!strcmp(extension_name,
468 local_create_info.ppEnabledExtensionNames[i])) {
469 return false;
470 }
471 }
Jesse Hall3dd678a2016-01-08 21:52:01 -0800472 uint32_t extension_count = local_create_info.enabledExtensionCount;
473 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800474 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800475 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800476 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
477 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500478 if (mem) {
479 const char** enabled_extensions = static_cast<const char**>(mem);
480 for (uint32_t i = 0; i < extension_count; ++i) {
481 enabled_extensions[i] =
482 local_create_info.ppEnabledExtensionNames[i];
483 }
484 enabled_extensions[extension_count] = extension_name;
485 local_create_info.ppEnabledExtensionNames = enabled_extensions;
486 } else {
487 ALOGW("%s extension cannot be enabled: memory allocation failed",
488 extension_name);
Jesse Hall3dd678a2016-01-08 21:52:01 -0800489 local_create_info.enabledExtensionCount--;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500490 return false;
491 }
492 return true;
493}
494
495template <class T>
496void FreeAllocatedCreateInfo(T& local_create_info,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800497 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500498 alloc->pfnFree(
499 alloc->pUserData,
500 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
501}
502
Jesse Halle1b12782015-11-30 11:27:32 -0800503VKAPI_ATTR
Jesse Hall715b86a2016-01-16 16:34:29 -0800504VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
505 VkDebugReportObjectTypeEXT /*objectType*/,
506 uint64_t /*object*/,
Michael Lentineeb970862015-10-15 12:42:22 -0500507 size_t /*location*/,
508 int32_t message_code,
509 const char* layer_prefix,
510 const char* message,
511 void* /*user_data*/) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800512 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500513 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
Jesse Hall715b86a2016-01-16 16:34:29 -0800514 } else if (flags & VK_DEBUG_REPORT_WARN_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500515 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
516 }
Michael Lentineeb970862015-10-15 12:42:22 -0500517 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500518}
519
Jesse Hall06193802015-12-03 16:12:51 -0800520VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500521 return VK_SUCCESS;
522}
523
Jesse Hall1f91d392015-12-11 16:28:44 -0800524} // anonymous namespace
525
526namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500527
Jesse Hall04f4f472015-08-16 19:51:04 -0700528// -----------------------------------------------------------------------------
529// "Bottom" functions. These are called at the end of the instance dispatch
530// chain.
531
Jesse Hall1f91d392015-12-11 16:28:44 -0800532VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
533 const VkAllocationCallbacks* allocator,
534 VkInstance* vkinstance) {
535 Instance& instance = GetDispatchParent(*vkinstance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700536 VkResult result;
537
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800538 // Check that all enabled extensions are supported
539 InstanceExtensionSet enabled_extensions;
540 uint32_t num_driver_extensions = 0;
541 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
542 const char* name = create_info->ppEnabledExtensionNames[i];
543 InstanceExtension id = InstanceExtensionFromName(name);
544 if (id != kInstanceExtensionCount) {
545 if (g_driver_instance_extensions[id]) {
546 num_driver_extensions++;
547 enabled_extensions.set(id);
548 continue;
549 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700550 if (id == kKHR_surface || id == kKHR_android_surface) {
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800551 enabled_extensions.set(id);
552 continue;
553 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700554 // The loader natively supports debug report.
555 if (id == kEXT_debug_report) {
556 continue;
557 }
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800558 }
559 bool supported = false;
560 for (const auto& layer : instance.active_layers) {
561 if (layer.SupportsExtension(name))
562 supported = true;
563 }
564 if (!supported) {
565 ALOGE(
566 "requested instance extension '%s' not supported by "
567 "loader, driver, or any active layers",
568 name);
569 DestroyInstance_Bottom(instance.handle, allocator);
570 return VK_ERROR_EXTENSION_NOT_PRESENT;
571 }
572 }
573
Jesse Halla7ac76d2016-01-08 22:29:42 -0800574 VkInstanceCreateInfo driver_create_info = *create_info;
575 driver_create_info.enabledLayerCount = 0;
576 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800577 driver_create_info.enabledExtensionCount = 0;
578 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800579 if (num_driver_extensions > 0) {
580 const char** names = static_cast<const char**>(
581 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800582 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800583 const char* name = create_info->ppEnabledExtensionNames[i];
584 InstanceExtension id = InstanceExtensionFromName(name);
585 if (id != kInstanceExtensionCount) {
586 if (g_driver_instance_extensions[id]) {
587 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800588 continue;
589 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800590 }
591 }
592 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800593 ALOG_ASSERT(
594 driver_create_info.enabledExtensionCount == num_driver_extensions,
595 "counted enabled driver instance extensions twice and got "
596 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800597 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800598
599 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800600 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700601 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800602 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700603 return result;
604 }
605
Jesse Hall1f91d392015-12-11 16:28:44 -0800606 hwvulkan_dispatch_t* drv_dispatch =
607 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
608 if (drv_dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
609 // Skip setting drv_dispatch->vtbl, since we never call through it;
610 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700611 } else {
612 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800613 drv_dispatch->magic);
614 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700615 return VK_ERROR_INITIALIZATION_FAILED;
616 }
617
Courtney Goeltzenleuchteraa6c8722016-01-29 08:57:16 -0700618 if (!LoadDriverDispatchTable(instance.drv.instance,
619 g_hwdevice->GetInstanceProcAddr,
620 enabled_extensions, instance.drv.dispatch)) {
621 DestroyInstance_Bottom(instance.handle, allocator);
622 return VK_ERROR_INITIALIZATION_FAILED;
623 }
624
Jesse Hall04f4f472015-08-16 19:51:04 -0700625 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800626 result = instance.drv.dispatch.EnumeratePhysicalDevices(
627 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700628 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800629 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700630 return VK_ERROR_INITIALIZATION_FAILED;
631 }
632 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800633 result = instance.drv.dispatch.EnumeratePhysicalDevices(
634 instance.drv.instance, &num_physical_devices,
635 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700636 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800637 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700638 return VK_ERROR_INITIALIZATION_FAILED;
639 }
Jesse Hallb1471272016-01-17 21:36:58 -0800640
641 Vector<VkExtensionProperties> extensions(
642 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700643 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800644 hwvulkan_dispatch_t* pdev_dispatch =
645 reinterpret_cast<hwvulkan_dispatch_t*>(
646 instance.physical_devices[i]);
647 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700648 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800649 pdev_dispatch->magic);
650 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700651 return VK_ERROR_INITIALIZATION_FAILED;
652 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800653 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800654
655 uint32_t count;
656 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
657 instance.physical_devices[i], nullptr, &count, nullptr)) !=
658 VK_SUCCESS) {
659 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
660 result);
661 continue;
662 }
Jesse Hall26cecff2016-01-21 19:52:25 -0800663 try {
664 extensions.resize(count);
665 } catch (std::bad_alloc&) {
666 ALOGE("instance creation failed: out of memory");
667 DestroyInstance_Bottom(instance.handle, allocator);
668 return VK_ERROR_OUT_OF_HOST_MEMORY;
669 }
Jesse Hallb1471272016-01-17 21:36:58 -0800670 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
671 instance.physical_devices[i], nullptr, &count,
672 extensions.data())) != VK_SUCCESS) {
673 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
674 result);
675 continue;
676 }
677 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
678 for (const auto& extension : extensions) {
679 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
680 DeviceExtension id =
681 DeviceExtensionFromName(extension.extensionName);
682 if (id == kDeviceExtensionCount) {
683 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
684 extension.extensionName);
685 } else {
686 instance.physical_device_driver_extensions[i].set(id);
687 }
688 }
689 // Ignore driver attempts to support loader extensions
690 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700691 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800692 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800693 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800694
Jesse Hall04f4f472015-08-16 19:51:04 -0700695 return VK_SUCCESS;
696}
697
Jesse Hall1f91d392015-12-11 16:28:44 -0800698PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
699 PFN_vkVoidFunction pfn;
700 if ((pfn = GetLoaderBottomProcAddr(name)))
701 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800702 return nullptr;
703}
704
705VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
706 uint32_t* pdev_count,
707 VkPhysicalDevice* pdevs) {
708 Instance& instance = GetDispatchParent(vkinstance);
709 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700710 if (pdevs) {
711 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800712 std::copy(instance.physical_devices, instance.physical_devices + count,
713 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700714 }
715 *pdev_count = count;
716 return VK_SUCCESS;
717}
718
Jesse Hall1f91d392015-12-11 16:28:44 -0800719void GetPhysicalDeviceProperties_Bottom(
720 VkPhysicalDevice pdev,
721 VkPhysicalDeviceProperties* properties) {
722 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
723 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700724}
725
Jesse Hall1f91d392015-12-11 16:28:44 -0800726void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
727 VkPhysicalDeviceFeatures* features) {
728 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
729 features);
730}
731
732void GetPhysicalDeviceMemoryProperties_Bottom(
733 VkPhysicalDevice pdev,
734 VkPhysicalDeviceMemoryProperties* properties) {
735 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
736 pdev, properties);
737}
738
739void GetPhysicalDeviceQueueFamilyProperties_Bottom(
740 VkPhysicalDevice pdev,
741 uint32_t* pCount,
742 VkQueueFamilyProperties* properties) {
743 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
744 pdev, pCount, properties);
745}
746
747void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
748 VkFormat format,
749 VkFormatProperties* properties) {
750 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700751 pdev, format, properties);
752}
753
Jesse Hall1f91d392015-12-11 16:28:44 -0800754VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700755 VkPhysicalDevice pdev,
756 VkFormat format,
757 VkImageType type,
758 VkImageTiling tiling,
759 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700760 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700761 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800762 return GetDispatchParent(pdev)
763 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800764 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700765}
766
Jesse Hall1f91d392015-12-11 16:28:44 -0800767void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700768 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800769 VkFormat format,
770 VkImageType type,
771 VkSampleCountFlagBits samples,
772 VkImageUsageFlags usage,
773 VkImageTiling tiling,
774 uint32_t* properties_count,
775 VkSparseImageFormatProperties* properties) {
776 GetDispatchParent(pdev)
777 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
778 pdev, format, type, samples, usage, tiling, properties_count,
779 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700780}
781
Jesse Halle1b12782015-11-30 11:27:32 -0800782VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800783VkResult EnumerateDeviceExtensionProperties_Bottom(
Jesse Hallb1471272016-01-17 21:36:58 -0800784 VkPhysicalDevice gpu,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800785 const char* layer_name,
Jesse Hall1f91d392015-12-11 16:28:44 -0800786 uint32_t* properties_count,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800787 VkExtensionProperties* properties) {
788 const VkExtensionProperties* extensions = nullptr;
789 uint32_t num_extensions = 0;
790 if (layer_name) {
791 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
792 } else {
Jesse Hallb1471272016-01-17 21:36:58 -0800793 Instance& instance = GetDispatchParent(gpu);
794 size_t gpu_idx = 0;
795 while (instance.physical_devices[gpu_idx] != gpu)
796 gpu_idx++;
797 const DeviceExtensionSet driver_extensions =
798 instance.physical_device_driver_extensions[gpu_idx];
799
800 // We only support VK_KHR_swapchain if the GPU supports
801 // VK_ANDROID_native_buffer
802 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
803 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
804 if (driver_extensions[kANDROID_native_buffer]) {
805 available[num_extensions++] = VkExtensionProperties{
806 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
807 }
808
809 // TODO(jessehall): We need to also enumerate extensions supported by
810 // implicitly-enabled layers. Currently we don't have that list of
811 // layers until instance creation.
812 extensions = available;
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800813 }
814
815 if (!properties || *properties_count > num_extensions)
816 *properties_count = num_extensions;
817 if (properties)
818 std::copy(extensions, extensions + *properties_count, properties);
819 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700820}
821
Jesse Halle1b12782015-11-30 11:27:32 -0800822VKAPI_ATTR
Jesse Hall80523e22016-01-06 16:47:54 -0800823VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice /*pdev*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800824 uint32_t* properties_count,
Jesse Hallaa410942016-01-17 13:07:10 -0800825 VkLayerProperties* properties) {
826 uint32_t layer_count =
827 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
828 if (!properties || *properties_count > layer_count)
829 *properties_count = layer_count;
830 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800831}
832
833VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800834VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800835 const VkDeviceCreateInfo* create_info,
836 const VkAllocationCallbacks* allocator,
837 VkDevice* device_out) {
Jesse Hallb1471272016-01-17 21:36:58 -0800838 Instance& instance = GetDispatchParent(gpu);
Jesse Hall04f4f472015-08-16 19:51:04 -0700839 VkResult result;
840
Jesse Hall9f763492016-01-21 21:54:49 -0800841 // FIXME(jessehall): We don't have good conventions or infrastructure yet to
842 // do better than just using the instance allocator and scope for
843 // everything. See b/26732122.
844 if (true /*!allocator*/)
845 allocator = instance.alloc;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800846
Jesse Hall3fbc8562015-11-29 22:10:52 -0800847 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
848 alignof(Device),
849 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700850 if (!mem)
851 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500852 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700853
Jesse Hall9a16f972015-10-28 15:59:53 -0700854 result = ActivateAllLayers(create_info, &instance, device);
855 if (result != VK_SUCCESS) {
856 DestroyDevice(device);
857 return result;
858 }
859
Jesse Hallb1471272016-01-17 21:36:58 -0800860 size_t gpu_idx = 0;
861 while (instance.physical_devices[gpu_idx] != gpu)
862 gpu_idx++;
863
864 uint32_t num_driver_extensions = 0;
865 const char** driver_extensions = static_cast<const char**>(
866 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
867 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
868 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -0800869 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -0800870 if (id != kDeviceExtensionCount) {
871 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
872 driver_extensions[num_driver_extensions++] = name;
873 continue;
874 }
875 if (id == kKHR_swapchain &&
876 instance.physical_device_driver_extensions
877 [gpu_idx][kANDROID_native_buffer]) {
878 driver_extensions[num_driver_extensions++] =
879 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
880 continue;
881 }
Jesse Hallb1471272016-01-17 21:36:58 -0800882 }
Jesse Hallb1471272016-01-17 21:36:58 -0800883 bool supported = false;
884 for (const auto& layer : device->active_layers) {
885 if (layer.SupportsExtension(name))
886 supported = true;
887 }
888 if (!supported) {
889 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -0800890 "requested device extension '%s' not supported by loader, "
891 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -0800892 name);
893 DestroyDevice(device);
894 return VK_ERROR_EXTENSION_NOT_PRESENT;
895 }
896 }
897
Jesse Halla7ac76d2016-01-08 22:29:42 -0800898 VkDeviceCreateInfo driver_create_info = *create_info;
899 driver_create_info.enabledLayerCount = 0;
900 driver_create_info.ppEnabledLayerNames = nullptr;
901 // TODO(jessehall): As soon as we enumerate device extensions supported by
902 // the driver, we need to filter the requested extension list to those
903 // supported by the driver here. Also, add the VK_ANDROID_native_buffer
904 // extension to the list iff the VK_KHR_swapchain extension was requested,
905 // instead of adding it unconditionally like we do now.
Jesse Hallb1471272016-01-17 21:36:58 -0800906 driver_create_info.enabledExtensionCount = num_driver_extensions;
907 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800908
Jesse Hall04f4f472015-08-16 19:51:04 -0700909 VkDevice drv_device;
Jesse Hallb1471272016-01-17 21:36:58 -0800910 result = instance.drv.dispatch.CreateDevice(gpu, &driver_create_info,
911 allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700912 if (result != VK_SUCCESS) {
913 DestroyDevice(device);
914 return result;
915 }
916
Jesse Hall1f91d392015-12-11 16:28:44 -0800917 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700918 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800919 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
920 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
921 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500922 PFN_vkDestroyDevice destroy_device =
923 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800924 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
925 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800926 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700927 DestroyDevice(device);
928 return VK_ERROR_INITIALIZATION_FAILED;
929 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800930 drv_dispatch->vtbl = &device->dispatch;
931 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
932 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
933 "vkGetDeviceProcAddr"));
Jesse Hall04f4f472015-08-16 19:51:04 -0700934
Michael Lentine03c64b02015-08-26 18:27:26 -0500935 void* base_object = static_cast<void*>(drv_device);
936 void* next_object = base_object;
937 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800938 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetDeviceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500939 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine03c64b02015-08-26 18:27:26 -0500940 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
Jesse Hall26cecff2016-01-21 19:52:25 -0800941 try {
942 elem_list.resize(device->active_layers.size());
943 } catch (std::bad_alloc&) {
944 ALOGE("device creation failed: out of memory");
945 PFN_vkDestroyDevice destroy_device =
946 reinterpret_cast<PFN_vkDestroyDevice>(
947 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
948 "vkDestroyDevice"));
949 destroy_device(drv_device, allocator);
950 DestroyDevice(device);
951 return VK_ERROR_OUT_OF_HOST_MEMORY;
952 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500953
954 for (size_t i = elem_list.size(); i > 0; i--) {
955 size_t idx = i - 1;
956 next_element = &elem_list[idx];
957 next_element->get_proc_addr =
958 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
959 next_element->base_object = base_object;
960 next_element->next_element = next_object;
961 next_object = static_cast<void*>(next_element);
962
Jesse Hall80523e22016-01-06 16:47:54 -0800963 next_get_proc_addr = device->active_layers[idx].GetGetDeviceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500964 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800965 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500966 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800967 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500968 }
969 }
970
Jesse Hall1f91d392015-12-11 16:28:44 -0800971 // This is the magic call that initializes all the layer devices and
972 // allows them to create their device_handle -> device_data mapping.
973 next_get_proc_addr(static_cast<VkDevice>(next_object),
974 "vkGetDeviceProcAddr");
975
976 // We must create all the layer devices *before* retrieving the device
977 // procaddrs, so that the layers know which extensions are enabled and
978 // therefore which functions to return procaddrs for.
979 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
980 next_get_proc_addr(drv_device, "vkCreateDevice"));
Jesse Hallb1471272016-01-17 21:36:58 -0800981 create_device(gpu, create_info, allocator, &drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800982
983 if (!LoadDeviceDispatchTable(static_cast<VkDevice>(base_object),
984 next_get_proc_addr, device->dispatch)) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500985 DestroyDevice(device);
986 return VK_ERROR_INITIALIZATION_FAILED;
987 }
988
Jesse Hall1f91d392015-12-11 16:28:44 -0800989 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700990 return VK_SUCCESS;
991}
992
Jesse Hall1f91d392015-12-11 16:28:44 -0800993void DestroyInstance_Bottom(VkInstance vkinstance,
994 const VkAllocationCallbacks* allocator) {
995 Instance& instance = GetDispatchParent(vkinstance);
996
997 // These checks allow us to call DestroyInstance_Bottom from any error
998 // path in CreateInstance_Bottom, before the driver instance is fully
999 // initialized.
1000 if (instance.drv.instance != VK_NULL_HANDLE &&
1001 instance.drv.dispatch.DestroyInstance) {
1002 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
1003 }
1004 if (instance.message) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001005 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
1006 destroy_debug_report_callback =
1007 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
1008 vkGetInstanceProcAddr(vkinstance,
1009 "vkDestroyDebugReportCallbackEXT"));
1010 destroy_debug_report_callback(vkinstance, instance.message, allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -08001011 }
Jesse Hall80523e22016-01-06 16:47:54 -08001012 instance.active_layers.clear();
Jesse Hall1f91d392015-12-11 16:28:44 -08001013 const VkAllocationCallbacks* alloc = instance.alloc;
1014 instance.~Instance();
1015 alloc->pfnFree(alloc->pUserData, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -07001016}
1017
Jesse Hall1f91d392015-12-11 16:28:44 -08001018PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
1019 const char* name) {
1020 if (strcmp(name, "vkCreateDevice") == 0) {
1021 // TODO(jessehall): Blegh, having this here is disgusting. The current
1022 // layer init process can't call through the instance dispatch table's
1023 // vkCreateDevice, because that goes through the instance layers rather
1024 // than through the device layers. So we need to be able to get the
1025 // vkCreateDevice pointer through the *device* layer chain.
1026 //
1027 // Because we've already created the driver device before calling
1028 // through the layer vkCreateDevice functions, the loader bottom proc
1029 // is a no-op.
Michael Lentine03c64b02015-08-26 18:27:26 -05001030 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
1031 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001032
1033 // VK_ANDROID_native_buffer should be hidden from applications and layers.
1034 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
1035 PFN_vkVoidFunction pfn;
1036 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
1037 strcmp(name, "vkAcquireImageANDROID") == 0 ||
1038 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
1039 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001040 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001041 if ((pfn = GetLoaderBottomProcAddr(name)))
1042 return pfn;
1043 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001044}
1045
Jesse Hall04f4f472015-08-16 19:51:04 -07001046// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -08001047// Loader top functions. These are called directly from the loader entry
1048// points or from the application (via vkGetInstanceProcAddr) without going
1049// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -07001050
Jesse Hall1f91d392015-12-11 16:28:44 -08001051VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -08001052 const char* layer_name,
1053 uint32_t* properties_count,
1054 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001055 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001056 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001057
Jesse Hall80523e22016-01-06 16:47:54 -08001058 const VkExtensionProperties* extensions = nullptr;
1059 uint32_t num_extensions = 0;
1060 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -08001061 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -08001062 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001063 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1064 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
1065 available[num_extensions++] = VkExtensionProperties{
1066 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
1067 available[num_extensions++] =
1068 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1069 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
1070 if (g_driver_instance_extensions[kEXT_debug_report]) {
1071 available[num_extensions++] =
1072 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1073 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1074 }
Jesse Hall80523e22016-01-06 16:47:54 -08001075 // TODO(jessehall): We need to also enumerate extensions supported by
1076 // implicitly-enabled layers. Currently we don't have that list of
1077 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001078 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001079 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001080
Jesse Hall80523e22016-01-06 16:47:54 -08001081 if (!properties || *properties_count > num_extensions)
1082 *properties_count = num_extensions;
1083 if (properties)
1084 std::copy(extensions, extensions + *properties_count, properties);
1085 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001086}
1087
Jesse Hall80523e22016-01-06 16:47:54 -08001088VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1089 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001090 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001091 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001092
Jesse Hall80523e22016-01-06 16:47:54 -08001093 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001094 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001095 if (!properties || *properties_count > layer_count)
1096 *properties_count = layer_count;
1097 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001098}
1099
Jesse Hall1f91d392015-12-11 16:28:44 -08001100VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1101 const VkAllocationCallbacks* allocator,
1102 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001103 VkResult result;
1104
1105 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001106 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001107
Jesse Hall03b6fe12015-11-24 12:44:21 -08001108 if (!allocator)
1109 allocator = &kDefaultAllocCallbacks;
1110
Jesse Hall04f4f472015-08-16 19:51:04 -07001111 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001112 create_info = &local_create_info;
1113
Jesse Hall3fbc8562015-11-29 22:10:52 -08001114 void* instance_mem = allocator->pfnAllocation(
1115 allocator->pUserData, sizeof(Instance), alignof(Instance),
1116 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001117 if (!instance_mem)
1118 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001119 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001120
Jesse Hall9a16f972015-10-28 15:59:53 -07001121 result = ActivateAllLayers(create_info, instance, instance);
1122 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001123 DestroyInstance_Bottom(instance->handle, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001124 return result;
1125 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001126
Jesse Hall1f91d392015-12-11 16:28:44 -08001127 void* base_object = static_cast<void*>(instance->handle);
Michael Lentine03c64b02015-08-26 18:27:26 -05001128 void* next_object = base_object;
1129 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -08001130 PFN_vkGetInstanceProcAddr next_get_proc_addr = GetInstanceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -05001131 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine03c64b02015-08-26 18:27:26 -05001132 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
Jesse Hall26cecff2016-01-21 19:52:25 -08001133 try {
1134 elem_list.resize(instance->active_layers.size());
1135 } catch (std::bad_alloc&) {
1136 ALOGE("instance creation failed: out of memory");
1137 DestroyInstance_Bottom(instance->handle, allocator);
1138 return VK_ERROR_OUT_OF_HOST_MEMORY;
1139 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001140
1141 for (size_t i = elem_list.size(); i > 0; i--) {
1142 size_t idx = i - 1;
1143 next_element = &elem_list[idx];
1144 next_element->get_proc_addr =
1145 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
1146 next_element->base_object = base_object;
1147 next_element->next_element = next_object;
1148 next_object = static_cast<void*>(next_element);
1149
Jesse Hall80523e22016-01-06 16:47:54 -08001150 next_get_proc_addr =
1151 instance->active_layers[idx].GetGetInstanceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -05001152 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -08001153 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -05001154 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -08001155 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -05001156 }
1157 }
1158
Jesse Hall1f91d392015-12-11 16:28:44 -08001159 // This is the magic call that initializes all the layer instances and
1160 // allows them to create their instance_handle -> instance_data mapping.
1161 next_get_proc_addr(static_cast<VkInstance>(next_object),
1162 "vkGetInstanceProcAddr");
1163
1164 if (!LoadInstanceDispatchTable(static_cast<VkInstance>(base_object),
1165 next_get_proc_addr, instance->dispatch)) {
1166 DestroyInstance_Bottom(instance->handle, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001167 return VK_ERROR_INITIALIZATION_FAILED;
1168 }
1169
Michael Lentine950bb4f2015-09-14 13:26:30 -05001170 // Force enable callback extension if required
Jesse Hall21597662015-12-18 13:48:24 -08001171 bool enable_callback = false;
1172 bool enable_logging = false;
1173 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1174 enable_callback =
1175 property_get_bool("debug.vulkan.enable_callback", false);
1176 enable_logging = enable_callback;
1177 if (enable_callback) {
1178 enable_callback = AddExtensionToCreateInfo(
Jesse Hall715b86a2016-01-16 16:34:29 -08001179 local_create_info, "VK_EXT_debug_report", instance->alloc);
Jesse Hall21597662015-12-18 13:48:24 -08001180 }
Michael Lentine950bb4f2015-09-14 13:26:30 -05001181 }
1182
Jesse Hallc55fa942016-01-17 21:44:16 -08001183 VkInstance handle = instance->handle;
Jesse Hall1f91d392015-12-11 16:28:44 -08001184 PFN_vkCreateInstance create_instance =
1185 reinterpret_cast<PFN_vkCreateInstance>(
1186 next_get_proc_addr(instance->handle, "vkCreateInstance"));
Jesse Hallc55fa942016-01-17 21:44:16 -08001187 result = create_instance(create_info, allocator, &handle);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001188 if (enable_callback)
1189 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall993849c2016-01-18 00:59:45 -08001190 if (result >= 0) {
1191 *instance_out = instance->handle;
1192 } else {
Jesse Hall04f4f472015-08-16 19:51:04 -07001193 // For every layer, including the loader top and bottom layers:
1194 // - If a call to the next CreateInstance fails, the layer must clean
1195 // up anything it has successfully done so far, and propagate the
1196 // error upwards.
1197 // - If a layer successfully calls the next layer's CreateInstance, and
1198 // afterwards must fail for some reason, it must call the next layer's
1199 // DestroyInstance before returning.
1200 // - The layer must not call the next layer's DestroyInstance if that
1201 // layer's CreateInstance wasn't called, or returned failure.
1202
Jesse Hall1f91d392015-12-11 16:28:44 -08001203 // On failure, CreateInstance_Bottom frees the instance struct, so it's
Jesse Hall04f4f472015-08-16 19:51:04 -07001204 // already gone at this point. Nothing to do.
1205 }
1206
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001207 if (enable_logging) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001208 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1209 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1210 .flags =
1211 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARN_BIT_EXT,
1212 .pfnCallback = LogDebugMessageCallback,
1213 };
1214 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1215 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1216 GetInstanceProcAddr_Top(instance->handle,
1217 "vkCreateDebugReportCallbackEXT"));
1218 create_debug_report_callback(instance->handle, &callback_create_info,
1219 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001220 }
1221
Jesse Hall04f4f472015-08-16 19:51:04 -07001222 return result;
1223}
1224
Jesse Hall1f91d392015-12-11 16:28:44 -08001225PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1226 const char* name) {
1227 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1228 if (!vkinstance)
1229 return GetLoaderGlobalProcAddr(name);
1230
1231 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1232 PFN_vkVoidFunction pfn;
1233 // Always go through the loader-top function if there is one.
1234 if ((pfn = GetLoaderTopProcAddr(name)))
1235 return pfn;
1236 // Otherwise, look up the handler in the instance dispatch table
1237 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1238 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001239 // Anything not handled already must be a device-dispatched function
1240 // without a loader-top. We must return a function that will dispatch based
1241 // on the dispatchable object parameter -- which is exactly what the
1242 // exported functions do. So just return them here.
1243 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001244}
1245
Jesse Hall1f91d392015-12-11 16:28:44 -08001246void DestroyInstance_Top(VkInstance instance,
1247 const VkAllocationCallbacks* allocator) {
1248 if (!instance)
1249 return;
1250 GetDispatchTable(instance).DestroyInstance(instance, allocator);
1251}
1252
1253PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1254 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001255 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001256 return nullptr;
1257 if ((pfn = GetLoaderTopProcAddr(name)))
1258 return pfn;
1259 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001260}
1261
Jesse Hall1f91d392015-12-11 16:28:44 -08001262void GetDeviceQueue_Top(VkDevice vkdevice,
1263 uint32_t family,
1264 uint32_t index,
1265 VkQueue* queue_out) {
1266 const auto& table = GetDispatchTable(vkdevice);
1267 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1268 hwvulkan_dispatch_t* queue_dispatch =
1269 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1270 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1271 queue_dispatch->vtbl != &table)
1272 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1273 queue_dispatch->magic);
1274 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001275}
1276
Jesse Hall1f91d392015-12-11 16:28:44 -08001277VkResult AllocateCommandBuffers_Top(
1278 VkDevice vkdevice,
1279 const VkCommandBufferAllocateInfo* alloc_info,
1280 VkCommandBuffer* cmdbufs) {
1281 const auto& table = GetDispatchTable(vkdevice);
1282 VkResult result =
1283 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001284 if (result != VK_SUCCESS)
1285 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001286 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001287 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001288 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001289 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001290 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001291 cmdbuf_dispatch->magic);
1292 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001293 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001294 return VK_SUCCESS;
1295}
1296
Jesse Hall1f91d392015-12-11 16:28:44 -08001297void DestroyDevice_Top(VkDevice vkdevice,
1298 const VkAllocationCallbacks* /*allocator*/) {
1299 if (!vkdevice)
1300 return;
1301 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001302 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1303 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001304}
1305
Jesse Hall1f91d392015-12-11 16:28:44 -08001306// -----------------------------------------------------------------------------
1307
1308const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1309 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001310}
1311
Jesse Hall1f91d392015-12-11 16:28:44 -08001312const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1313 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001314}
1315
Jesse Hall715b86a2016-01-16 16:34:29 -08001316VkInstance GetDriverInstance(VkInstance instance) {
1317 return GetDispatchParent(instance).drv.instance;
1318}
1319
1320const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1321 return GetDispatchParent(instance).drv.dispatch;
1322}
1323
Jesse Hall1f91d392015-12-11 16:28:44 -08001324const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1325 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001326}
1327
Jesse Hall1f91d392015-12-11 16:28:44 -08001328const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1329 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001330}
1331
Jesse Hall715b86a2016-01-16 16:34:29 -08001332DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1333 return GetDispatchParent(instance).debug_report_callbacks;
1334}
1335
Jesse Hall04f4f472015-08-16 19:51:04 -07001336} // namespace vulkan