blob: bc1c3b8b6ad30d0455cacc4e9a957d6ad36b4a87 [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 }
550 if (id == kKHR_surface || id == kKHR_android_surface ||
551 id == kEXT_debug_report) {
552 enabled_extensions.set(id);
553 continue;
554 }
555 }
556 bool supported = false;
557 for (const auto& layer : instance.active_layers) {
558 if (layer.SupportsExtension(name))
559 supported = true;
560 }
561 if (!supported) {
562 ALOGE(
563 "requested instance extension '%s' not supported by "
564 "loader, driver, or any active layers",
565 name);
566 DestroyInstance_Bottom(instance.handle, allocator);
567 return VK_ERROR_EXTENSION_NOT_PRESENT;
568 }
569 }
570
Jesse Halla7ac76d2016-01-08 22:29:42 -0800571 VkInstanceCreateInfo driver_create_info = *create_info;
572 driver_create_info.enabledLayerCount = 0;
573 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800574 driver_create_info.enabledExtensionCount = 0;
575 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800576 if (num_driver_extensions > 0) {
577 const char** names = static_cast<const char**>(
578 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800579 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800580 const char* name = create_info->ppEnabledExtensionNames[i];
581 InstanceExtension id = InstanceExtensionFromName(name);
582 if (id != kInstanceExtensionCount) {
583 if (g_driver_instance_extensions[id]) {
584 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800585 continue;
586 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800587 }
588 }
589 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800590 ALOG_ASSERT(
591 driver_create_info.enabledExtensionCount == num_driver_extensions,
592 "counted enabled driver instance extensions twice and got "
593 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800594 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800595
596 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800597 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700598 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800599 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700600 return result;
601 }
602
Jesse Hall1f91d392015-12-11 16:28:44 -0800603 if (!LoadDriverDispatchTable(instance.drv.instance,
604 g_hwdevice->GetInstanceProcAddr,
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800605 enabled_extensions, instance.drv.dispatch)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800606 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700607 return VK_ERROR_INITIALIZATION_FAILED;
608 }
609
Jesse Hall1f91d392015-12-11 16:28:44 -0800610 hwvulkan_dispatch_t* drv_dispatch =
611 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
612 if (drv_dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
613 // Skip setting drv_dispatch->vtbl, since we never call through it;
614 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700615 } else {
616 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800617 drv_dispatch->magic);
618 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700619 return VK_ERROR_INITIALIZATION_FAILED;
620 }
621
622 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800623 result = instance.drv.dispatch.EnumeratePhysicalDevices(
624 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700625 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800626 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700627 return VK_ERROR_INITIALIZATION_FAILED;
628 }
629 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800630 result = instance.drv.dispatch.EnumeratePhysicalDevices(
631 instance.drv.instance, &num_physical_devices,
632 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700633 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800634 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700635 return VK_ERROR_INITIALIZATION_FAILED;
636 }
Jesse Hallb1471272016-01-17 21:36:58 -0800637
638 Vector<VkExtensionProperties> extensions(
639 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700640 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800641 hwvulkan_dispatch_t* pdev_dispatch =
642 reinterpret_cast<hwvulkan_dispatch_t*>(
643 instance.physical_devices[i]);
644 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700645 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800646 pdev_dispatch->magic);
647 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700648 return VK_ERROR_INITIALIZATION_FAILED;
649 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800650 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800651
652 uint32_t count;
653 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
654 instance.physical_devices[i], nullptr, &count, nullptr)) !=
655 VK_SUCCESS) {
656 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
657 result);
658 continue;
659 }
Jesse Hall26cecff2016-01-21 19:52:25 -0800660 try {
661 extensions.resize(count);
662 } catch (std::bad_alloc&) {
663 ALOGE("instance creation failed: out of memory");
664 DestroyInstance_Bottom(instance.handle, allocator);
665 return VK_ERROR_OUT_OF_HOST_MEMORY;
666 }
Jesse Hallb1471272016-01-17 21:36:58 -0800667 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
668 instance.physical_devices[i], nullptr, &count,
669 extensions.data())) != VK_SUCCESS) {
670 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
671 result);
672 continue;
673 }
674 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
675 for (const auto& extension : extensions) {
676 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
677 DeviceExtension id =
678 DeviceExtensionFromName(extension.extensionName);
679 if (id == kDeviceExtensionCount) {
680 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
681 extension.extensionName);
682 } else {
683 instance.physical_device_driver_extensions[i].set(id);
684 }
685 }
686 // Ignore driver attempts to support loader extensions
687 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700688 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800689 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800690 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800691
Jesse Hall04f4f472015-08-16 19:51:04 -0700692 return VK_SUCCESS;
693}
694
Jesse Hall1f91d392015-12-11 16:28:44 -0800695PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
696 PFN_vkVoidFunction pfn;
697 if ((pfn = GetLoaderBottomProcAddr(name)))
698 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800699 return nullptr;
700}
701
702VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
703 uint32_t* pdev_count,
704 VkPhysicalDevice* pdevs) {
705 Instance& instance = GetDispatchParent(vkinstance);
706 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700707 if (pdevs) {
708 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800709 std::copy(instance.physical_devices, instance.physical_devices + count,
710 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700711 }
712 *pdev_count = count;
713 return VK_SUCCESS;
714}
715
Jesse Hall1f91d392015-12-11 16:28:44 -0800716void GetPhysicalDeviceProperties_Bottom(
717 VkPhysicalDevice pdev,
718 VkPhysicalDeviceProperties* properties) {
719 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
720 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700721}
722
Jesse Hall1f91d392015-12-11 16:28:44 -0800723void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
724 VkPhysicalDeviceFeatures* features) {
725 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
726 features);
727}
728
729void GetPhysicalDeviceMemoryProperties_Bottom(
730 VkPhysicalDevice pdev,
731 VkPhysicalDeviceMemoryProperties* properties) {
732 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
733 pdev, properties);
734}
735
736void GetPhysicalDeviceQueueFamilyProperties_Bottom(
737 VkPhysicalDevice pdev,
738 uint32_t* pCount,
739 VkQueueFamilyProperties* properties) {
740 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
741 pdev, pCount, properties);
742}
743
744void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
745 VkFormat format,
746 VkFormatProperties* properties) {
747 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700748 pdev, format, properties);
749}
750
Jesse Hall1f91d392015-12-11 16:28:44 -0800751VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700752 VkPhysicalDevice pdev,
753 VkFormat format,
754 VkImageType type,
755 VkImageTiling tiling,
756 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700757 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700758 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800759 return GetDispatchParent(pdev)
760 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800761 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700762}
763
Jesse Hall1f91d392015-12-11 16:28:44 -0800764void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700765 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800766 VkFormat format,
767 VkImageType type,
768 VkSampleCountFlagBits samples,
769 VkImageUsageFlags usage,
770 VkImageTiling tiling,
771 uint32_t* properties_count,
772 VkSparseImageFormatProperties* properties) {
773 GetDispatchParent(pdev)
774 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
775 pdev, format, type, samples, usage, tiling, properties_count,
776 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700777}
778
Jesse Halle1b12782015-11-30 11:27:32 -0800779VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800780VkResult EnumerateDeviceExtensionProperties_Bottom(
Jesse Hallb1471272016-01-17 21:36:58 -0800781 VkPhysicalDevice gpu,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800782 const char* layer_name,
Jesse Hall1f91d392015-12-11 16:28:44 -0800783 uint32_t* properties_count,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800784 VkExtensionProperties* properties) {
785 const VkExtensionProperties* extensions = nullptr;
786 uint32_t num_extensions = 0;
787 if (layer_name) {
788 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
789 } else {
Jesse Hallb1471272016-01-17 21:36:58 -0800790 Instance& instance = GetDispatchParent(gpu);
791 size_t gpu_idx = 0;
792 while (instance.physical_devices[gpu_idx] != gpu)
793 gpu_idx++;
794 const DeviceExtensionSet driver_extensions =
795 instance.physical_device_driver_extensions[gpu_idx];
796
797 // We only support VK_KHR_swapchain if the GPU supports
798 // VK_ANDROID_native_buffer
799 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
800 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
801 if (driver_extensions[kANDROID_native_buffer]) {
802 available[num_extensions++] = VkExtensionProperties{
803 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
804 }
805
806 // TODO(jessehall): We need to also enumerate extensions supported by
807 // implicitly-enabled layers. Currently we don't have that list of
808 // layers until instance creation.
809 extensions = available;
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800810 }
811
812 if (!properties || *properties_count > num_extensions)
813 *properties_count = num_extensions;
814 if (properties)
815 std::copy(extensions, extensions + *properties_count, properties);
816 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700817}
818
Jesse Halle1b12782015-11-30 11:27:32 -0800819VKAPI_ATTR
Jesse Hall80523e22016-01-06 16:47:54 -0800820VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice /*pdev*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800821 uint32_t* properties_count,
Jesse Hallaa410942016-01-17 13:07:10 -0800822 VkLayerProperties* properties) {
823 uint32_t layer_count =
824 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
825 if (!properties || *properties_count > layer_count)
826 *properties_count = layer_count;
827 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800828}
829
830VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800831VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800832 const VkDeviceCreateInfo* create_info,
833 const VkAllocationCallbacks* allocator,
834 VkDevice* device_out) {
Jesse Hallb1471272016-01-17 21:36:58 -0800835 Instance& instance = GetDispatchParent(gpu);
Jesse Hall04f4f472015-08-16 19:51:04 -0700836 VkResult result;
837
Jesse Hall9f763492016-01-21 21:54:49 -0800838 // FIXME(jessehall): We don't have good conventions or infrastructure yet to
839 // do better than just using the instance allocator and scope for
840 // everything. See b/26732122.
841 if (true /*!allocator*/)
842 allocator = instance.alloc;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800843
Jesse Hall3fbc8562015-11-29 22:10:52 -0800844 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
845 alignof(Device),
846 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700847 if (!mem)
848 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500849 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700850
Jesse Hall9a16f972015-10-28 15:59:53 -0700851 result = ActivateAllLayers(create_info, &instance, device);
852 if (result != VK_SUCCESS) {
853 DestroyDevice(device);
854 return result;
855 }
856
Jesse Hallb1471272016-01-17 21:36:58 -0800857 size_t gpu_idx = 0;
858 while (instance.physical_devices[gpu_idx] != gpu)
859 gpu_idx++;
860
861 uint32_t num_driver_extensions = 0;
862 const char** driver_extensions = static_cast<const char**>(
863 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
864 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
865 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -0800866 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -0800867 if (id != kDeviceExtensionCount) {
868 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
869 driver_extensions[num_driver_extensions++] = name;
870 continue;
871 }
872 if (id == kKHR_swapchain &&
873 instance.physical_device_driver_extensions
874 [gpu_idx][kANDROID_native_buffer]) {
875 driver_extensions[num_driver_extensions++] =
876 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
877 continue;
878 }
Jesse Hallb1471272016-01-17 21:36:58 -0800879 }
Jesse Hallb1471272016-01-17 21:36:58 -0800880 bool supported = false;
881 for (const auto& layer : device->active_layers) {
882 if (layer.SupportsExtension(name))
883 supported = true;
884 }
885 if (!supported) {
886 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -0800887 "requested device extension '%s' not supported by loader, "
888 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -0800889 name);
890 DestroyDevice(device);
891 return VK_ERROR_EXTENSION_NOT_PRESENT;
892 }
893 }
894
Jesse Halla7ac76d2016-01-08 22:29:42 -0800895 VkDeviceCreateInfo driver_create_info = *create_info;
896 driver_create_info.enabledLayerCount = 0;
897 driver_create_info.ppEnabledLayerNames = nullptr;
898 // TODO(jessehall): As soon as we enumerate device extensions supported by
899 // the driver, we need to filter the requested extension list to those
900 // supported by the driver here. Also, add the VK_ANDROID_native_buffer
901 // extension to the list iff the VK_KHR_swapchain extension was requested,
902 // instead of adding it unconditionally like we do now.
Jesse Hallb1471272016-01-17 21:36:58 -0800903 driver_create_info.enabledExtensionCount = num_driver_extensions;
904 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800905
Jesse Hall04f4f472015-08-16 19:51:04 -0700906 VkDevice drv_device;
Jesse Hallb1471272016-01-17 21:36:58 -0800907 result = instance.drv.dispatch.CreateDevice(gpu, &driver_create_info,
908 allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700909 if (result != VK_SUCCESS) {
910 DestroyDevice(device);
911 return result;
912 }
913
Jesse Hall1f91d392015-12-11 16:28:44 -0800914 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700915 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800916 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
917 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
918 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500919 PFN_vkDestroyDevice destroy_device =
920 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800921 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
922 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800923 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700924 DestroyDevice(device);
925 return VK_ERROR_INITIALIZATION_FAILED;
926 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800927 drv_dispatch->vtbl = &device->dispatch;
928 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
929 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
930 "vkGetDeviceProcAddr"));
Jesse Hall04f4f472015-08-16 19:51:04 -0700931
Michael Lentine03c64b02015-08-26 18:27:26 -0500932 void* base_object = static_cast<void*>(drv_device);
933 void* next_object = base_object;
934 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800935 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetDeviceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500936 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine03c64b02015-08-26 18:27:26 -0500937 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
Jesse Hall26cecff2016-01-21 19:52:25 -0800938 try {
939 elem_list.resize(device->active_layers.size());
940 } catch (std::bad_alloc&) {
941 ALOGE("device creation failed: out of memory");
942 PFN_vkDestroyDevice destroy_device =
943 reinterpret_cast<PFN_vkDestroyDevice>(
944 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
945 "vkDestroyDevice"));
946 destroy_device(drv_device, allocator);
947 DestroyDevice(device);
948 return VK_ERROR_OUT_OF_HOST_MEMORY;
949 }
Michael Lentine03c64b02015-08-26 18:27:26 -0500950
951 for (size_t i = elem_list.size(); i > 0; i--) {
952 size_t idx = i - 1;
953 next_element = &elem_list[idx];
954 next_element->get_proc_addr =
955 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
956 next_element->base_object = base_object;
957 next_element->next_element = next_object;
958 next_object = static_cast<void*>(next_element);
959
Jesse Hall80523e22016-01-06 16:47:54 -0800960 next_get_proc_addr = device->active_layers[idx].GetGetDeviceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500961 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800962 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500963 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800964 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500965 }
966 }
967
Jesse Hall1f91d392015-12-11 16:28:44 -0800968 // This is the magic call that initializes all the layer devices and
969 // allows them to create their device_handle -> device_data mapping.
970 next_get_proc_addr(static_cast<VkDevice>(next_object),
971 "vkGetDeviceProcAddr");
972
973 // We must create all the layer devices *before* retrieving the device
974 // procaddrs, so that the layers know which extensions are enabled and
975 // therefore which functions to return procaddrs for.
976 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
977 next_get_proc_addr(drv_device, "vkCreateDevice"));
Jesse Hallb1471272016-01-17 21:36:58 -0800978 create_device(gpu, create_info, allocator, &drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800979
980 if (!LoadDeviceDispatchTable(static_cast<VkDevice>(base_object),
981 next_get_proc_addr, device->dispatch)) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500982 DestroyDevice(device);
983 return VK_ERROR_INITIALIZATION_FAILED;
984 }
985
Jesse Hall1f91d392015-12-11 16:28:44 -0800986 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700987 return VK_SUCCESS;
988}
989
Jesse Hall1f91d392015-12-11 16:28:44 -0800990void DestroyInstance_Bottom(VkInstance vkinstance,
991 const VkAllocationCallbacks* allocator) {
992 Instance& instance = GetDispatchParent(vkinstance);
993
994 // These checks allow us to call DestroyInstance_Bottom from any error
995 // path in CreateInstance_Bottom, before the driver instance is fully
996 // initialized.
997 if (instance.drv.instance != VK_NULL_HANDLE &&
998 instance.drv.dispatch.DestroyInstance) {
999 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
1000 }
1001 if (instance.message) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001002 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
1003 destroy_debug_report_callback =
1004 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
1005 vkGetInstanceProcAddr(vkinstance,
1006 "vkDestroyDebugReportCallbackEXT"));
1007 destroy_debug_report_callback(vkinstance, instance.message, allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -08001008 }
Jesse Hall80523e22016-01-06 16:47:54 -08001009 instance.active_layers.clear();
Jesse Hall1f91d392015-12-11 16:28:44 -08001010 const VkAllocationCallbacks* alloc = instance.alloc;
1011 instance.~Instance();
1012 alloc->pfnFree(alloc->pUserData, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -07001013}
1014
Jesse Hall1f91d392015-12-11 16:28:44 -08001015PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
1016 const char* name) {
1017 if (strcmp(name, "vkCreateDevice") == 0) {
1018 // TODO(jessehall): Blegh, having this here is disgusting. The current
1019 // layer init process can't call through the instance dispatch table's
1020 // vkCreateDevice, because that goes through the instance layers rather
1021 // than through the device layers. So we need to be able to get the
1022 // vkCreateDevice pointer through the *device* layer chain.
1023 //
1024 // Because we've already created the driver device before calling
1025 // through the layer vkCreateDevice functions, the loader bottom proc
1026 // is a no-op.
Michael Lentine03c64b02015-08-26 18:27:26 -05001027 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
1028 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001029
1030 // VK_ANDROID_native_buffer should be hidden from applications and layers.
1031 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
1032 PFN_vkVoidFunction pfn;
1033 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
1034 strcmp(name, "vkAcquireImageANDROID") == 0 ||
1035 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
1036 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001037 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001038 if ((pfn = GetLoaderBottomProcAddr(name)))
1039 return pfn;
1040 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001041}
1042
Jesse Hall04f4f472015-08-16 19:51:04 -07001043// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -08001044// Loader top functions. These are called directly from the loader entry
1045// points or from the application (via vkGetInstanceProcAddr) without going
1046// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -07001047
Jesse Hall1f91d392015-12-11 16:28:44 -08001048VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -08001049 const char* layer_name,
1050 uint32_t* properties_count,
1051 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001052 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001053 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001054
Jesse Hall80523e22016-01-06 16:47:54 -08001055 const VkExtensionProperties* extensions = nullptr;
1056 uint32_t num_extensions = 0;
1057 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -08001058 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -08001059 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001060 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1061 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
1062 available[num_extensions++] = VkExtensionProperties{
1063 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
1064 available[num_extensions++] =
1065 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1066 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
1067 if (g_driver_instance_extensions[kEXT_debug_report]) {
1068 available[num_extensions++] =
1069 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1070 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1071 }
Jesse Hall80523e22016-01-06 16:47:54 -08001072 // TODO(jessehall): We need to also enumerate extensions supported by
1073 // implicitly-enabled layers. Currently we don't have that list of
1074 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001075 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001076 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001077
Jesse Hall80523e22016-01-06 16:47:54 -08001078 if (!properties || *properties_count > num_extensions)
1079 *properties_count = num_extensions;
1080 if (properties)
1081 std::copy(extensions, extensions + *properties_count, properties);
1082 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001083}
1084
Jesse Hall80523e22016-01-06 16:47:54 -08001085VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1086 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001087 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001088 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001089
Jesse Hall80523e22016-01-06 16:47:54 -08001090 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001091 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001092 if (!properties || *properties_count > layer_count)
1093 *properties_count = layer_count;
1094 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001095}
1096
Jesse Hall1f91d392015-12-11 16:28:44 -08001097VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1098 const VkAllocationCallbacks* allocator,
1099 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001100 VkResult result;
1101
1102 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001103 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001104
Jesse Hall03b6fe12015-11-24 12:44:21 -08001105 if (!allocator)
1106 allocator = &kDefaultAllocCallbacks;
1107
Jesse Hall04f4f472015-08-16 19:51:04 -07001108 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001109 create_info = &local_create_info;
1110
Jesse Hall3fbc8562015-11-29 22:10:52 -08001111 void* instance_mem = allocator->pfnAllocation(
1112 allocator->pUserData, sizeof(Instance), alignof(Instance),
1113 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001114 if (!instance_mem)
1115 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001116 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001117
Jesse Hall9a16f972015-10-28 15:59:53 -07001118 result = ActivateAllLayers(create_info, instance, instance);
1119 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001120 DestroyInstance_Bottom(instance->handle, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001121 return result;
1122 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001123
Jesse Hall1f91d392015-12-11 16:28:44 -08001124 void* base_object = static_cast<void*>(instance->handle);
Michael Lentine03c64b02015-08-26 18:27:26 -05001125 void* next_object = base_object;
1126 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -08001127 PFN_vkGetInstanceProcAddr next_get_proc_addr = GetInstanceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -05001128 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine03c64b02015-08-26 18:27:26 -05001129 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
Jesse Hall26cecff2016-01-21 19:52:25 -08001130 try {
1131 elem_list.resize(instance->active_layers.size());
1132 } catch (std::bad_alloc&) {
1133 ALOGE("instance creation failed: out of memory");
1134 DestroyInstance_Bottom(instance->handle, allocator);
1135 return VK_ERROR_OUT_OF_HOST_MEMORY;
1136 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001137
1138 for (size_t i = elem_list.size(); i > 0; i--) {
1139 size_t idx = i - 1;
1140 next_element = &elem_list[idx];
1141 next_element->get_proc_addr =
1142 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
1143 next_element->base_object = base_object;
1144 next_element->next_element = next_object;
1145 next_object = static_cast<void*>(next_element);
1146
Jesse Hall80523e22016-01-06 16:47:54 -08001147 next_get_proc_addr =
1148 instance->active_layers[idx].GetGetInstanceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -05001149 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -08001150 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -05001151 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -08001152 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -05001153 }
1154 }
1155
Jesse Hall1f91d392015-12-11 16:28:44 -08001156 // This is the magic call that initializes all the layer instances and
1157 // allows them to create their instance_handle -> instance_data mapping.
1158 next_get_proc_addr(static_cast<VkInstance>(next_object),
1159 "vkGetInstanceProcAddr");
1160
1161 if (!LoadInstanceDispatchTable(static_cast<VkInstance>(base_object),
1162 next_get_proc_addr, instance->dispatch)) {
1163 DestroyInstance_Bottom(instance->handle, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001164 return VK_ERROR_INITIALIZATION_FAILED;
1165 }
1166
Michael Lentine950bb4f2015-09-14 13:26:30 -05001167 // Force enable callback extension if required
Jesse Hall21597662015-12-18 13:48:24 -08001168 bool enable_callback = false;
1169 bool enable_logging = false;
1170 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1171 enable_callback =
1172 property_get_bool("debug.vulkan.enable_callback", false);
1173 enable_logging = enable_callback;
1174 if (enable_callback) {
1175 enable_callback = AddExtensionToCreateInfo(
Jesse Hall715b86a2016-01-16 16:34:29 -08001176 local_create_info, "VK_EXT_debug_report", instance->alloc);
Jesse Hall21597662015-12-18 13:48:24 -08001177 }
Michael Lentine950bb4f2015-09-14 13:26:30 -05001178 }
1179
Jesse Hallc55fa942016-01-17 21:44:16 -08001180 VkInstance handle = instance->handle;
Jesse Hall1f91d392015-12-11 16:28:44 -08001181 PFN_vkCreateInstance create_instance =
1182 reinterpret_cast<PFN_vkCreateInstance>(
1183 next_get_proc_addr(instance->handle, "vkCreateInstance"));
Jesse Hallc55fa942016-01-17 21:44:16 -08001184 result = create_instance(create_info, allocator, &handle);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001185 if (enable_callback)
1186 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall993849c2016-01-18 00:59:45 -08001187 if (result >= 0) {
1188 *instance_out = instance->handle;
1189 } else {
Jesse Hall04f4f472015-08-16 19:51:04 -07001190 // For every layer, including the loader top and bottom layers:
1191 // - If a call to the next CreateInstance fails, the layer must clean
1192 // up anything it has successfully done so far, and propagate the
1193 // error upwards.
1194 // - If a layer successfully calls the next layer's CreateInstance, and
1195 // afterwards must fail for some reason, it must call the next layer's
1196 // DestroyInstance before returning.
1197 // - The layer must not call the next layer's DestroyInstance if that
1198 // layer's CreateInstance wasn't called, or returned failure.
1199
Jesse Hall1f91d392015-12-11 16:28:44 -08001200 // On failure, CreateInstance_Bottom frees the instance struct, so it's
Jesse Hall04f4f472015-08-16 19:51:04 -07001201 // already gone at this point. Nothing to do.
1202 }
1203
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001204 if (enable_logging) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001205 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1206 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1207 .flags =
1208 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARN_BIT_EXT,
1209 .pfnCallback = LogDebugMessageCallback,
1210 };
1211 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1212 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1213 GetInstanceProcAddr_Top(instance->handle,
1214 "vkCreateDebugReportCallbackEXT"));
1215 create_debug_report_callback(instance->handle, &callback_create_info,
1216 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001217 }
1218
Jesse Hall04f4f472015-08-16 19:51:04 -07001219 return result;
1220}
1221
Jesse Hall1f91d392015-12-11 16:28:44 -08001222PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1223 const char* name) {
1224 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1225 if (!vkinstance)
1226 return GetLoaderGlobalProcAddr(name);
1227
1228 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1229 PFN_vkVoidFunction pfn;
1230 // Always go through the loader-top function if there is one.
1231 if ((pfn = GetLoaderTopProcAddr(name)))
1232 return pfn;
1233 // Otherwise, look up the handler in the instance dispatch table
1234 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1235 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001236 // Anything not handled already must be a device-dispatched function
1237 // without a loader-top. We must return a function that will dispatch based
1238 // on the dispatchable object parameter -- which is exactly what the
1239 // exported functions do. So just return them here.
1240 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001241}
1242
Jesse Hall1f91d392015-12-11 16:28:44 -08001243void DestroyInstance_Top(VkInstance instance,
1244 const VkAllocationCallbacks* allocator) {
1245 if (!instance)
1246 return;
1247 GetDispatchTable(instance).DestroyInstance(instance, allocator);
1248}
1249
1250PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1251 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001252 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001253 return nullptr;
1254 if ((pfn = GetLoaderTopProcAddr(name)))
1255 return pfn;
1256 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001257}
1258
Jesse Hall1f91d392015-12-11 16:28:44 -08001259void GetDeviceQueue_Top(VkDevice vkdevice,
1260 uint32_t family,
1261 uint32_t index,
1262 VkQueue* queue_out) {
1263 const auto& table = GetDispatchTable(vkdevice);
1264 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1265 hwvulkan_dispatch_t* queue_dispatch =
1266 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1267 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1268 queue_dispatch->vtbl != &table)
1269 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1270 queue_dispatch->magic);
1271 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001272}
1273
Jesse Hall1f91d392015-12-11 16:28:44 -08001274VkResult AllocateCommandBuffers_Top(
1275 VkDevice vkdevice,
1276 const VkCommandBufferAllocateInfo* alloc_info,
1277 VkCommandBuffer* cmdbufs) {
1278 const auto& table = GetDispatchTable(vkdevice);
1279 VkResult result =
1280 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001281 if (result != VK_SUCCESS)
1282 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001283 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001284 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001285 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001286 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001287 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001288 cmdbuf_dispatch->magic);
1289 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001290 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001291 return VK_SUCCESS;
1292}
1293
Jesse Hall1f91d392015-12-11 16:28:44 -08001294void DestroyDevice_Top(VkDevice vkdevice,
1295 const VkAllocationCallbacks* /*allocator*/) {
1296 if (!vkdevice)
1297 return;
1298 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001299 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1300 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001301}
1302
Jesse Hall1f91d392015-12-11 16:28:44 -08001303// -----------------------------------------------------------------------------
1304
1305const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1306 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001307}
1308
Jesse Hall1f91d392015-12-11 16:28:44 -08001309const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1310 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001311}
1312
Jesse Hall715b86a2016-01-16 16:34:29 -08001313VkInstance GetDriverInstance(VkInstance instance) {
1314 return GetDispatchParent(instance).drv.instance;
1315}
1316
1317const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1318 return GetDispatchParent(instance).drv.dispatch;
1319}
1320
Jesse Hall1f91d392015-12-11 16:28:44 -08001321const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1322 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001323}
1324
Jesse Hall1f91d392015-12-11 16:28:44 -08001325const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1326 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001327}
1328
Jesse Hall715b86a2016-01-16 16:34:29 -08001329DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1330 return GetDispatchParent(instance).debug_report_callbacks;
1331}
1332
Jesse Hall04f4f472015-08-16 19:51:04 -07001333} // namespace vulkan