blob: 04705b7ae48ceec639ad1981e004f22135528f3f [file] [log] [blame]
Jesse Halld02edcb2015-09-08 07:44:48 -07001/*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jesse Hall504db7f2016-01-14 15:53:57 -080017// #define LOG_NDEBUG 0
Michael Lentine9dbe67f2015-09-16 15:53:50 -050018
Jesse Hall04f4f472015-08-16 19:51:04 -070019// module header
20#include "loader.h"
21// standard C headers
Michael Lentine03c64b02015-08-26 18:27:26 -050022#include <dirent.h>
23#include <dlfcn.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070024#include <inttypes.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070025#include <pthread.h>
Jesse Hall03b6fe12015-11-24 12:44:21 -080026#include <stdlib.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070027#include <string.h>
Jesse Hall21597662015-12-18 13:48:24 -080028#include <sys/prctl.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070029// standard C++ headers
30#include <algorithm>
31#include <mutex>
Michael Lentine03c64b02015-08-26 18:27:26 -050032#include <sstream>
33#include <string>
34#include <unordered_map>
35#include <vector>
Jesse Hall04f4f472015-08-16 19:51:04 -070036// platform/library headers
Michael Lentine03c64b02015-08-26 18:27:26 -050037#include <cutils/properties.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070038#include <hardware/hwvulkan.h>
39#include <log/log.h>
Michael Lentine1c69b9e2015-09-14 13:26:59 -050040#include <vulkan/vulkan_loader_data.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070041
42using namespace vulkan;
43
44static const uint32_t kMaxPhysicalDevices = 4;
45
Michael Lentine03c64b02015-08-26 18:27:26 -050046namespace {
47
48// These definitions are taken from the LunarG Vulkan Loader. They are used to
49// enforce compatability between the Loader and Layers.
50typedef void* (*PFN_vkGetProcAddr)(void* obj, const char* pName);
51
52typedef struct VkLayerLinkedListElem_ {
53 PFN_vkGetProcAddr get_proc_addr;
54 void* next_element;
55 void* base_object;
56} VkLayerLinkedListElem;
57
Jesse Hall1f91d392015-12-11 16:28:44 -080058// ----------------------------------------------------------------------------
Michael Lentine03c64b02015-08-26 18:27:26 -050059
Jesse Hall3fbc8562015-11-29 22:10:52 -080060// Standard-library allocator that delegates to VkAllocationCallbacks.
Jesse Hall03b6fe12015-11-24 12:44:21 -080061//
62// TODO(jessehall): This class currently always uses
Jesse Hall3fbc8562015-11-29 22:10:52 -080063// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template
Jesse Hall03b6fe12015-11-24 12:44:21 -080064// parameter or a constructor parameter. The former would help catch bugs
65// where we use the wrong scope, e.g. adding a command-scope string to an
66// instance-scope vector. But that might also be pretty annoying to deal with.
Michael Lentine03c64b02015-08-26 18:27:26 -050067template <class T>
68class CallbackAllocator {
69 public:
70 typedef T value_type;
71
Jesse Hall3fbc8562015-11-29 22:10:52 -080072 CallbackAllocator(const VkAllocationCallbacks* alloc_input)
Michael Lentine03c64b02015-08-26 18:27:26 -050073 : alloc(alloc_input) {}
74
75 template <class T2>
76 CallbackAllocator(const CallbackAllocator<T2>& other)
77 : alloc(other.alloc) {}
78
79 T* allocate(std::size_t n) {
Jesse Hall3fbc8562015-11-29 22:10:52 -080080 void* mem =
81 alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T),
82 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine03c64b02015-08-26 18:27:26 -050083 return static_cast<T*>(mem);
84 }
85
86 void deallocate(T* array, std::size_t /*n*/) {
87 alloc->pfnFree(alloc->pUserData, array);
88 }
89
Jesse Hall3fbc8562015-11-29 22:10:52 -080090 const VkAllocationCallbacks* alloc;
Michael Lentine03c64b02015-08-26 18:27:26 -050091};
92// These are needed in order to move Strings
93template <class T>
94bool operator==(const CallbackAllocator<T>& alloc1,
95 const CallbackAllocator<T>& alloc2) {
96 return alloc1.alloc == alloc2.alloc;
97}
98template <class T>
99bool operator!=(const CallbackAllocator<T>& alloc1,
100 const CallbackAllocator<T>& alloc2) {
101 return !(alloc1 == alloc2);
102}
103
104template <class Key,
105 class T,
106 class Hash = std::hash<Key>,
Jesse Hall1f91d392015-12-11 16:28:44 -0800107 class Pred = std::equal_to<Key>>
Michael Lentine03c64b02015-08-26 18:27:26 -0500108using UnorderedMap =
109 std::unordered_map<Key,
110 T,
111 Hash,
112 Pred,
Jesse Hall1f91d392015-12-11 16:28:44 -0800113 CallbackAllocator<std::pair<const Key, T>>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500114
115template <class T>
Jesse Hall1f91d392015-12-11 16:28:44 -0800116using Vector = std::vector<T, CallbackAllocator<T>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500117
Jesse Hall1f91d392015-12-11 16:28:44 -0800118typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>>
119 String;
Michael Lentine03c64b02015-08-26 18:27:26 -0500120
Jesse Hall1f91d392015-12-11 16:28:44 -0800121// ----------------------------------------------------------------------------
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500122
Jesse Halle1b12782015-11-30 11:27:32 -0800123VKAPI_ATTR void* DefaultAllocate(void*,
124 size_t size,
125 size_t alignment,
126 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800127 void* ptr = nullptr;
128 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
129 // additionally requires that it be at least sizeof(void*).
130 return posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0
131 ? ptr
132 : nullptr;
133}
134
Jesse Halle1b12782015-11-30 11:27:32 -0800135VKAPI_ATTR void* DefaultReallocate(void*,
136 void* ptr,
137 size_t size,
138 size_t alignment,
139 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800140 if (size == 0) {
141 free(ptr);
142 return nullptr;
143 }
144
145 // TODO(jessehall): Right now we never shrink allocations; if the new
146 // request is smaller than the existing chunk, we just continue using it.
147 // Right now the loader never reallocs, so this doesn't matter. If that
148 // changes, or if this code is copied into some other project, this should
149 // probably have a heuristic to allocate-copy-free when doing so will save
150 // "enough" space.
151 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
152 if (size <= old_size)
153 return ptr;
154
155 void* new_ptr = nullptr;
156 if (posix_memalign(&new_ptr, alignment, size) != 0)
157 return nullptr;
158 if (ptr) {
159 memcpy(new_ptr, ptr, std::min(old_size, size));
160 free(ptr);
161 }
162 return new_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700163}
164
Jesse Halle1b12782015-11-30 11:27:32 -0800165VKAPI_ATTR void DefaultFree(void*, void* pMem) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700166 free(pMem);
167}
168
Jesse Hall3fbc8562015-11-29 22:10:52 -0800169const VkAllocationCallbacks kDefaultAllocCallbacks = {
Jesse Hall04f4f472015-08-16 19:51:04 -0700170 .pUserData = nullptr,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800171 .pfnAllocation = DefaultAllocate,
172 .pfnReallocation = DefaultReallocate,
Jesse Hall04f4f472015-08-16 19:51:04 -0700173 .pfnFree = DefaultFree,
174};
175
Jesse Hall1f91d392015-12-11 16:28:44 -0800176// ----------------------------------------------------------------------------
Jesse Hall80523e22016-01-06 16:47:54 -0800177// Global Data and Initialization
Jesse Hall1f91d392015-12-11 16:28:44 -0800178
Jesse Hall80523e22016-01-06 16:47:54 -0800179hwvulkan_device_t* g_hwdevice = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800180InstanceExtensionSet g_driver_instance_extensions;
181
Jesse Hall80523e22016-01-06 16:47:54 -0800182void LoadVulkanHAL() {
183 static const hwvulkan_module_t* module;
184 int result =
185 hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
186 if (result != 0) {
187 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
188 return;
189 }
190 result = module->common.methods->open(
191 &module->common, HWVULKAN_DEVICE_0,
192 reinterpret_cast<hw_device_t**>(&g_hwdevice));
193 if (result != 0) {
194 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
195 result);
196 module = nullptr;
197 return;
198 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800199
200 VkResult vkresult;
201 uint32_t count;
202 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
203 nullptr, &count, nullptr)) != VK_SUCCESS) {
204 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
205 vkresult);
206 g_hwdevice->common.close(&g_hwdevice->common);
207 g_hwdevice = nullptr;
208 module = nullptr;
209 return;
210 }
211 VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>(
212 alloca(count * sizeof(VkExtensionProperties)));
213 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
214 nullptr, &count, extensions)) != VK_SUCCESS) {
215 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
216 vkresult);
217 g_hwdevice->common.close(&g_hwdevice->common);
218 g_hwdevice = nullptr;
219 module = nullptr;
220 return;
221 }
222 ALOGV_IF(count > 0, "Driver-supported instance extensions:");
223 for (uint32_t i = 0; i < count; i++) {
224 ALOGV(" %s (v%u)", extensions[i].extensionName,
225 extensions[i].specVersion);
226 InstanceExtension id =
227 InstanceExtensionFromName(extensions[i].extensionName);
228 if (id != kInstanceExtensionCount)
229 g_driver_instance_extensions.set(id);
230 }
231 // Ignore driver attempts to support loader extensions
232 g_driver_instance_extensions.reset(kKHR_surface);
233 g_driver_instance_extensions.reset(kKHR_android_surface);
Jesse Hall80523e22016-01-06 16:47:54 -0800234}
235
Jesse Hall04f4f472015-08-16 19:51:04 -0700236bool EnsureInitialized() {
237 static std::once_flag once_flag;
Jesse Hall04f4f472015-08-16 19:51:04 -0700238 std::call_once(once_flag, []() {
Jesse Hall80523e22016-01-06 16:47:54 -0800239 LoadVulkanHAL();
240 DiscoverLayers();
Jesse Hall04f4f472015-08-16 19:51:04 -0700241 });
Jesse Hall80523e22016-01-06 16:47:54 -0800242 return g_hwdevice != nullptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700243}
244
Jesse Hall1f91d392015-12-11 16:28:44 -0800245// -----------------------------------------------------------------------------
246
247struct Instance {
248 Instance(const VkAllocationCallbacks* alloc_callbacks)
249 : dispatch_ptr(&dispatch),
250 handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800251 alloc(alloc_callbacks),
252 num_physical_devices(0),
Jesse Hall80523e22016-01-06 16:47:54 -0800253 active_layers(CallbackAllocator<LayerRef>(alloc)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800254 message(VK_NULL_HANDLE) {
255 memset(&dispatch, 0, sizeof(dispatch));
256 memset(physical_devices, 0, sizeof(physical_devices));
Jesse Hall1f91d392015-12-11 16:28:44 -0800257 drv.instance = VK_NULL_HANDLE;
258 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
259 drv.num_physical_devices = 0;
260 }
261
Jesse Hall80523e22016-01-06 16:47:54 -0800262 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800263
264 const InstanceDispatchTable* dispatch_ptr;
265 const VkInstance handle;
266 InstanceDispatchTable dispatch;
267
Jesse Hall1f91d392015-12-11 16:28:44 -0800268 const VkAllocationCallbacks* alloc;
269 uint32_t num_physical_devices;
270 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
Jesse Hallb1471272016-01-17 21:36:58 -0800271 DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800272
Jesse Hall80523e22016-01-06 16:47:54 -0800273 Vector<LayerRef> active_layers;
Jesse Hall715b86a2016-01-16 16:34:29 -0800274 VkDebugReportCallbackEXT message;
275 DebugReportCallbackList debug_report_callbacks;
Jesse Hall1f91d392015-12-11 16:28:44 -0800276
277 struct {
278 VkInstance instance;
279 DriverDispatchTable dispatch;
280 uint32_t num_physical_devices;
281 } drv; // may eventually be an array
282};
283
284struct Device {
285 Device(Instance* instance_)
286 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800287 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800288 memset(&dispatch, 0, sizeof(dispatch));
289 }
290 DeviceDispatchTable dispatch;
291 Instance* instance;
292 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800293 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800294};
295
296template <typename THandle>
297struct HandleTraits {};
298template <>
299struct HandleTraits<VkInstance> {
300 typedef Instance LoaderObjectType;
301};
302template <>
303struct HandleTraits<VkPhysicalDevice> {
304 typedef Instance LoaderObjectType;
305};
306template <>
307struct HandleTraits<VkDevice> {
308 typedef Device LoaderObjectType;
309};
310template <>
311struct HandleTraits<VkQueue> {
312 typedef Device LoaderObjectType;
313};
314template <>
315struct HandleTraits<VkCommandBuffer> {
316 typedef Device LoaderObjectType;
317};
318
319template <typename THandle>
320typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
321 THandle handle) {
322 // TODO(jessehall): Make Instance and Device POD types (by removing the
323 // non-default constructors), so that offsetof is actually legal to use.
324 // The specific case we're using here is safe in gcc/clang (and probably
325 // most other C++ compilers), but isn't guaranteed by C++.
326 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
327#pragma clang diagnostic push
328#pragma clang diagnostic ignored "-Winvalid-offsetof"
329 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
330#pragma clang diagnostic pop
331
332 const auto& dispatch = GetDispatchTable(handle);
333 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
334 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
335 return *reinterpret_cast<ObjectType*>(object_addr);
336}
337
338// -----------------------------------------------------------------------------
339
Jesse Hall04f4f472015-08-16 19:51:04 -0700340void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800341 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700342 device->~Device();
343 alloc->pfnFree(alloc->pUserData, device);
344}
345
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500346template <class TObject>
Jesse Hallaa410942016-01-17 13:07:10 -0800347LayerRef GetLayerRef(const char* name);
348template <>
349LayerRef GetLayerRef<Instance>(const char* name) {
350 return GetInstanceLayerRef(name);
351}
352template <>
353LayerRef GetLayerRef<Device>(const char* name) {
354 return GetDeviceLayerRef(name);
355}
356
357template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800358bool ActivateLayer(TObject* object, const char* name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800359 LayerRef layer(GetLayerRef<TObject>(name));
Jesse Hall80523e22016-01-06 16:47:54 -0800360 if (!layer)
361 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500362 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall80523e22016-01-06 16:47:54 -0800363 layer) == object->active_layers.end())
364 object->active_layers.push_back(std::move(layer));
365 ALOGV("activated layer '%s'", name);
366 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500367}
368
Michael Lentine9da191b2015-10-13 11:08:45 -0500369struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500370 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500371 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500372};
373
Michael Lentine9da191b2015-10-13 11:08:45 -0500374void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500375 const char* value,
376 void* data) {
377 const char prefix[] = "debug.vulkan.layer.";
378 const size_t prefixlen = sizeof(prefix) - 1;
379 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
380 return;
Michael Lentine9da191b2015-10-13 11:08:45 -0500381 const char* number_str = name + prefixlen;
382 long layer_number = strtol(number_str, nullptr, 10);
383 if (layer_number <= 0 || layer_number == LONG_MAX) {
384 ALOGW("Cannot use a layer at number %ld from string %s", layer_number,
385 number_str);
386 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500387 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500388 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
389 Vector<String>* layer_names = instance_names_pair->layer_names;
390 Instance* instance = instance_names_pair->instance;
391 size_t layer_size = static_cast<size_t>(layer_number);
392 if (layer_size > layer_names->size()) {
393 layer_names->resize(layer_size,
394 String(CallbackAllocator<char>(instance->alloc)));
395 }
396 (*layer_names)[layer_size - 1] = value;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500397}
398
399template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800400VkResult ActivateAllLayers(TInfo create_info,
401 Instance* instance,
402 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500403 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
404 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
405 "Cannot activate layers for unknown object %p", object);
406 CallbackAllocator<char> string_allocator(instance->alloc);
407 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800408 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500409 char layer_prop[PROPERTY_VALUE_MAX];
410 property_get("debug.vulkan.layers", layer_prop, "");
411 String layer_name(string_allocator);
412 String layer_prop_str(layer_prop, string_allocator);
413 size_t end, start = 0;
414 while ((end = layer_prop_str.find(':', start)) != std::string::npos) {
415 layer_name = layer_prop_str.substr(start, end - start);
Jesse Hall80523e22016-01-06 16:47:54 -0800416 ActivateLayer(object, layer_name.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500417 start = end + 1;
418 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500419 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
420 InstanceNamesPair instance_names_pair = {.instance = instance,
421 .layer_names = &layer_names};
422 property_list(SetLayerNamesFromProperty,
423 static_cast<void*>(&instance_names_pair));
424 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800425 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500426 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500427 }
428 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800429 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800430 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700431 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800432 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
433 ? "instance"
434 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800435 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700436 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500437 }
438 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700439 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500440}
441
442template <class TCreateInfo>
443bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
444 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800445 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800446 for (uint32_t i = 0; i < local_create_info.enabledExtensionCount; ++i) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500447 if (!strcmp(extension_name,
448 local_create_info.ppEnabledExtensionNames[i])) {
449 return false;
450 }
451 }
Jesse Hall3dd678a2016-01-08 21:52:01 -0800452 uint32_t extension_count = local_create_info.enabledExtensionCount;
453 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800454 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800455 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800456 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
457 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500458 if (mem) {
459 const char** enabled_extensions = static_cast<const char**>(mem);
460 for (uint32_t i = 0; i < extension_count; ++i) {
461 enabled_extensions[i] =
462 local_create_info.ppEnabledExtensionNames[i];
463 }
464 enabled_extensions[extension_count] = extension_name;
465 local_create_info.ppEnabledExtensionNames = enabled_extensions;
466 } else {
467 ALOGW("%s extension cannot be enabled: memory allocation failed",
468 extension_name);
Jesse Hall3dd678a2016-01-08 21:52:01 -0800469 local_create_info.enabledExtensionCount--;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500470 return false;
471 }
472 return true;
473}
474
475template <class T>
476void FreeAllocatedCreateInfo(T& local_create_info,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800477 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500478 alloc->pfnFree(
479 alloc->pUserData,
480 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
481}
482
Jesse Halle1b12782015-11-30 11:27:32 -0800483VKAPI_ATTR
Jesse Hall715b86a2016-01-16 16:34:29 -0800484VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
485 VkDebugReportObjectTypeEXT /*objectType*/,
486 uint64_t /*object*/,
Michael Lentineeb970862015-10-15 12:42:22 -0500487 size_t /*location*/,
488 int32_t message_code,
489 const char* layer_prefix,
490 const char* message,
491 void* /*user_data*/) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800492 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500493 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
Jesse Hall715b86a2016-01-16 16:34:29 -0800494 } else if (flags & VK_DEBUG_REPORT_WARN_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500495 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
496 }
Michael Lentineeb970862015-10-15 12:42:22 -0500497 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500498}
499
Jesse Hall06193802015-12-03 16:12:51 -0800500VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500501 return VK_SUCCESS;
502}
503
Jesse Hall1f91d392015-12-11 16:28:44 -0800504} // anonymous namespace
505
506namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500507
Jesse Hall04f4f472015-08-16 19:51:04 -0700508// -----------------------------------------------------------------------------
509// "Bottom" functions. These are called at the end of the instance dispatch
510// chain.
511
Jesse Hall1f91d392015-12-11 16:28:44 -0800512VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
513 const VkAllocationCallbacks* allocator,
514 VkInstance* vkinstance) {
515 Instance& instance = GetDispatchParent(*vkinstance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700516 VkResult result;
517
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800518 // Check that all enabled extensions are supported
519 InstanceExtensionSet enabled_extensions;
520 uint32_t num_driver_extensions = 0;
521 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
522 const char* name = create_info->ppEnabledExtensionNames[i];
523 InstanceExtension id = InstanceExtensionFromName(name);
524 if (id != kInstanceExtensionCount) {
525 if (g_driver_instance_extensions[id]) {
526 num_driver_extensions++;
527 enabled_extensions.set(id);
528 continue;
529 }
530 if (id == kKHR_surface || id == kKHR_android_surface ||
531 id == kEXT_debug_report) {
532 enabled_extensions.set(id);
533 continue;
534 }
535 }
536 bool supported = false;
537 for (const auto& layer : instance.active_layers) {
538 if (layer.SupportsExtension(name))
539 supported = true;
540 }
541 if (!supported) {
542 ALOGE(
543 "requested instance extension '%s' not supported by "
544 "loader, driver, or any active layers",
545 name);
546 DestroyInstance_Bottom(instance.handle, allocator);
547 return VK_ERROR_EXTENSION_NOT_PRESENT;
548 }
549 }
550
Jesse Halla7ac76d2016-01-08 22:29:42 -0800551 VkInstanceCreateInfo driver_create_info = *create_info;
552 driver_create_info.enabledLayerCount = 0;
553 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800554 driver_create_info.enabledExtensionCount = 0;
555 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800556 if (num_driver_extensions > 0) {
557 const char** names = static_cast<const char**>(
558 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800559 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800560 const char* name = create_info->ppEnabledExtensionNames[i];
561 InstanceExtension id = InstanceExtensionFromName(name);
562 if (id != kInstanceExtensionCount) {
563 if (g_driver_instance_extensions[id]) {
564 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800565 continue;
566 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800567 }
568 }
569 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800570 ALOG_ASSERT(
571 driver_create_info.enabledExtensionCount == num_driver_extensions,
572 "counted enabled driver instance extensions twice and got "
573 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800574 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800575
576 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800577 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700578 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800579 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700580 return result;
581 }
582
Jesse Hall1f91d392015-12-11 16:28:44 -0800583 if (!LoadDriverDispatchTable(instance.drv.instance,
584 g_hwdevice->GetInstanceProcAddr,
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800585 enabled_extensions, instance.drv.dispatch)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800586 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700587 return VK_ERROR_INITIALIZATION_FAILED;
588 }
589
Jesse Hall1f91d392015-12-11 16:28:44 -0800590 hwvulkan_dispatch_t* drv_dispatch =
591 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
592 if (drv_dispatch->magic == HWVULKAN_DISPATCH_MAGIC) {
593 // Skip setting drv_dispatch->vtbl, since we never call through it;
594 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700595 } else {
596 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800597 drv_dispatch->magic);
598 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700599 return VK_ERROR_INITIALIZATION_FAILED;
600 }
601
602 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800603 result = instance.drv.dispatch.EnumeratePhysicalDevices(
604 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700605 if (result != VK_SUCCESS) {
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 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800610 result = instance.drv.dispatch.EnumeratePhysicalDevices(
611 instance.drv.instance, &num_physical_devices,
612 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700613 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800614 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700615 return VK_ERROR_INITIALIZATION_FAILED;
616 }
Jesse Hallb1471272016-01-17 21:36:58 -0800617
618 Vector<VkExtensionProperties> extensions(
619 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700620 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800621 hwvulkan_dispatch_t* pdev_dispatch =
622 reinterpret_cast<hwvulkan_dispatch_t*>(
623 instance.physical_devices[i]);
624 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700625 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800626 pdev_dispatch->magic);
627 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700628 return VK_ERROR_INITIALIZATION_FAILED;
629 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800630 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800631
632 uint32_t count;
633 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
634 instance.physical_devices[i], nullptr, &count, nullptr)) !=
635 VK_SUCCESS) {
636 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
637 result);
638 continue;
639 }
640 extensions.resize(count);
641 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
642 instance.physical_devices[i], nullptr, &count,
643 extensions.data())) != VK_SUCCESS) {
644 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
645 result);
646 continue;
647 }
648 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
649 for (const auto& extension : extensions) {
650 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
651 DeviceExtension id =
652 DeviceExtensionFromName(extension.extensionName);
653 if (id == kDeviceExtensionCount) {
654 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
655 extension.extensionName);
656 } else {
657 instance.physical_device_driver_extensions[i].set(id);
658 }
659 }
660 // Ignore driver attempts to support loader extensions
661 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700662 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800663 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800664 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800665
Jesse Hall04f4f472015-08-16 19:51:04 -0700666 return VK_SUCCESS;
667}
668
Jesse Hall1f91d392015-12-11 16:28:44 -0800669PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
670 PFN_vkVoidFunction pfn;
671 if ((pfn = GetLoaderBottomProcAddr(name)))
672 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800673 return nullptr;
674}
675
676VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
677 uint32_t* pdev_count,
678 VkPhysicalDevice* pdevs) {
679 Instance& instance = GetDispatchParent(vkinstance);
680 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700681 if (pdevs) {
682 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800683 std::copy(instance.physical_devices, instance.physical_devices + count,
684 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700685 }
686 *pdev_count = count;
687 return VK_SUCCESS;
688}
689
Jesse Hall1f91d392015-12-11 16:28:44 -0800690void GetPhysicalDeviceProperties_Bottom(
691 VkPhysicalDevice pdev,
692 VkPhysicalDeviceProperties* properties) {
693 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
694 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700695}
696
Jesse Hall1f91d392015-12-11 16:28:44 -0800697void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
698 VkPhysicalDeviceFeatures* features) {
699 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
700 features);
701}
702
703void GetPhysicalDeviceMemoryProperties_Bottom(
704 VkPhysicalDevice pdev,
705 VkPhysicalDeviceMemoryProperties* properties) {
706 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
707 pdev, properties);
708}
709
710void GetPhysicalDeviceQueueFamilyProperties_Bottom(
711 VkPhysicalDevice pdev,
712 uint32_t* pCount,
713 VkQueueFamilyProperties* properties) {
714 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
715 pdev, pCount, properties);
716}
717
718void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
719 VkFormat format,
720 VkFormatProperties* properties) {
721 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700722 pdev, format, properties);
723}
724
Jesse Hall1f91d392015-12-11 16:28:44 -0800725VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700726 VkPhysicalDevice pdev,
727 VkFormat format,
728 VkImageType type,
729 VkImageTiling tiling,
730 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700731 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700732 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800733 return GetDispatchParent(pdev)
734 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800735 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700736}
737
Jesse Hall1f91d392015-12-11 16:28:44 -0800738void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700739 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800740 VkFormat format,
741 VkImageType type,
742 VkSampleCountFlagBits samples,
743 VkImageUsageFlags usage,
744 VkImageTiling tiling,
745 uint32_t* properties_count,
746 VkSparseImageFormatProperties* properties) {
747 GetDispatchParent(pdev)
748 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
749 pdev, format, type, samples, usage, tiling, properties_count,
750 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700751}
752
Jesse Halle1b12782015-11-30 11:27:32 -0800753VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800754VkResult EnumerateDeviceExtensionProperties_Bottom(
Jesse Hallb1471272016-01-17 21:36:58 -0800755 VkPhysicalDevice gpu,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800756 const char* layer_name,
Jesse Hall1f91d392015-12-11 16:28:44 -0800757 uint32_t* properties_count,
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800758 VkExtensionProperties* properties) {
759 const VkExtensionProperties* extensions = nullptr;
760 uint32_t num_extensions = 0;
761 if (layer_name) {
762 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
763 } else {
Jesse Hallb1471272016-01-17 21:36:58 -0800764 Instance& instance = GetDispatchParent(gpu);
765 size_t gpu_idx = 0;
766 while (instance.physical_devices[gpu_idx] != gpu)
767 gpu_idx++;
768 const DeviceExtensionSet driver_extensions =
769 instance.physical_device_driver_extensions[gpu_idx];
770
771 // We only support VK_KHR_swapchain if the GPU supports
772 // VK_ANDROID_native_buffer
773 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
774 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
775 if (driver_extensions[kANDROID_native_buffer]) {
776 available[num_extensions++] = VkExtensionProperties{
777 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
778 }
779
780 // TODO(jessehall): We need to also enumerate extensions supported by
781 // implicitly-enabled layers. Currently we don't have that list of
782 // layers until instance creation.
783 extensions = available;
Jesse Hall57f7f8c2016-01-17 17:21:36 -0800784 }
785
786 if (!properties || *properties_count > num_extensions)
787 *properties_count = num_extensions;
788 if (properties)
789 std::copy(extensions, extensions + *properties_count, properties);
790 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700791}
792
Jesse Halle1b12782015-11-30 11:27:32 -0800793VKAPI_ATTR
Jesse Hall80523e22016-01-06 16:47:54 -0800794VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice /*pdev*/,
Jesse Hall1f91d392015-12-11 16:28:44 -0800795 uint32_t* properties_count,
Jesse Hallaa410942016-01-17 13:07:10 -0800796 VkLayerProperties* properties) {
797 uint32_t layer_count =
798 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
799 if (!properties || *properties_count > layer_count)
800 *properties_count = layer_count;
801 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800802}
803
804VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800805VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800806 const VkDeviceCreateInfo* create_info,
807 const VkAllocationCallbacks* allocator,
808 VkDevice* device_out) {
Jesse Hallb1471272016-01-17 21:36:58 -0800809 Instance& instance = GetDispatchParent(gpu);
Jesse Hall04f4f472015-08-16 19:51:04 -0700810 VkResult result;
811
Jesse Hall03b6fe12015-11-24 12:44:21 -0800812 if (!allocator) {
813 if (instance.alloc)
814 allocator = instance.alloc;
815 else
816 allocator = &kDefaultAllocCallbacks;
817 }
818
Jesse Hall3fbc8562015-11-29 22:10:52 -0800819 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
820 alignof(Device),
821 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
Jesse Hall04f4f472015-08-16 19:51:04 -0700822 if (!mem)
823 return VK_ERROR_OUT_OF_HOST_MEMORY;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500824 Device* device = new (mem) Device(&instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700825
Jesse Hall9a16f972015-10-28 15:59:53 -0700826 result = ActivateAllLayers(create_info, &instance, device);
827 if (result != VK_SUCCESS) {
828 DestroyDevice(device);
829 return result;
830 }
831
Jesse Hallb1471272016-01-17 21:36:58 -0800832 size_t gpu_idx = 0;
833 while (instance.physical_devices[gpu_idx] != gpu)
834 gpu_idx++;
835
836 uint32_t num_driver_extensions = 0;
837 const char** driver_extensions = static_cast<const char**>(
838 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
839 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
840 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -0800841 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -0800842 if (id != kDeviceExtensionCount) {
843 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
844 driver_extensions[num_driver_extensions++] = name;
845 continue;
846 }
847 if (id == kKHR_swapchain &&
848 instance.physical_device_driver_extensions
849 [gpu_idx][kANDROID_native_buffer]) {
850 driver_extensions[num_driver_extensions++] =
851 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
852 continue;
853 }
Jesse Hallb1471272016-01-17 21:36:58 -0800854 }
Jesse Hallb1471272016-01-17 21:36:58 -0800855 bool supported = false;
856 for (const auto& layer : device->active_layers) {
857 if (layer.SupportsExtension(name))
858 supported = true;
859 }
860 if (!supported) {
861 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -0800862 "requested device extension '%s' not supported by loader, "
863 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -0800864 name);
865 DestroyDevice(device);
866 return VK_ERROR_EXTENSION_NOT_PRESENT;
867 }
868 }
869
Jesse Halla7ac76d2016-01-08 22:29:42 -0800870 VkDeviceCreateInfo driver_create_info = *create_info;
871 driver_create_info.enabledLayerCount = 0;
872 driver_create_info.ppEnabledLayerNames = nullptr;
873 // TODO(jessehall): As soon as we enumerate device extensions supported by
874 // the driver, we need to filter the requested extension list to those
875 // supported by the driver here. Also, add the VK_ANDROID_native_buffer
876 // extension to the list iff the VK_KHR_swapchain extension was requested,
877 // instead of adding it unconditionally like we do now.
Jesse Hallb1471272016-01-17 21:36:58 -0800878 driver_create_info.enabledExtensionCount = num_driver_extensions;
879 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800880
Jesse Hall04f4f472015-08-16 19:51:04 -0700881 VkDevice drv_device;
Jesse Hallb1471272016-01-17 21:36:58 -0800882 result = instance.drv.dispatch.CreateDevice(gpu, &driver_create_info,
883 allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700884 if (result != VK_SUCCESS) {
885 DestroyDevice(device);
886 return result;
887 }
888
Jesse Hall1f91d392015-12-11 16:28:44 -0800889 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700890 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800891 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
892 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
893 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500894 PFN_vkDestroyDevice destroy_device =
895 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800896 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
897 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800898 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700899 DestroyDevice(device);
900 return VK_ERROR_INITIALIZATION_FAILED;
901 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800902 drv_dispatch->vtbl = &device->dispatch;
903 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
904 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
905 "vkGetDeviceProcAddr"));
Jesse Hall04f4f472015-08-16 19:51:04 -0700906
Michael Lentine03c64b02015-08-26 18:27:26 -0500907 void* base_object = static_cast<void*>(drv_device);
908 void* next_object = base_object;
909 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -0800910 PFN_vkGetDeviceProcAddr next_get_proc_addr = GetDeviceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -0500911 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500912 device->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -0500913 CallbackAllocator<VkLayerLinkedListElem>(instance.alloc));
914
915 for (size_t i = elem_list.size(); i > 0; i--) {
916 size_t idx = i - 1;
917 next_element = &elem_list[idx];
918 next_element->get_proc_addr =
919 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
920 next_element->base_object = base_object;
921 next_element->next_element = next_object;
922 next_object = static_cast<void*>(next_element);
923
Jesse Hall80523e22016-01-06 16:47:54 -0800924 next_get_proc_addr = device->active_layers[idx].GetGetDeviceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -0500925 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -0800926 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -0500927 next_get_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -0800928 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -0500929 }
930 }
931
Jesse Hall1f91d392015-12-11 16:28:44 -0800932 // This is the magic call that initializes all the layer devices and
933 // allows them to create their device_handle -> device_data mapping.
934 next_get_proc_addr(static_cast<VkDevice>(next_object),
935 "vkGetDeviceProcAddr");
936
937 // We must create all the layer devices *before* retrieving the device
938 // procaddrs, so that the layers know which extensions are enabled and
939 // therefore which functions to return procaddrs for.
940 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
941 next_get_proc_addr(drv_device, "vkCreateDevice"));
Jesse Hallb1471272016-01-17 21:36:58 -0800942 create_device(gpu, create_info, allocator, &drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800943
944 if (!LoadDeviceDispatchTable(static_cast<VkDevice>(base_object),
945 next_get_proc_addr, device->dispatch)) {
Michael Lentine03c64b02015-08-26 18:27:26 -0500946 DestroyDevice(device);
947 return VK_ERROR_INITIALIZATION_FAILED;
948 }
949
Jesse Hall1f91d392015-12-11 16:28:44 -0800950 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700951 return VK_SUCCESS;
952}
953
Jesse Hall1f91d392015-12-11 16:28:44 -0800954void DestroyInstance_Bottom(VkInstance vkinstance,
955 const VkAllocationCallbacks* allocator) {
956 Instance& instance = GetDispatchParent(vkinstance);
957
958 // These checks allow us to call DestroyInstance_Bottom from any error
959 // path in CreateInstance_Bottom, before the driver instance is fully
960 // initialized.
961 if (instance.drv.instance != VK_NULL_HANDLE &&
962 instance.drv.dispatch.DestroyInstance) {
963 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
964 }
965 if (instance.message) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800966 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
967 destroy_debug_report_callback =
968 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
969 vkGetInstanceProcAddr(vkinstance,
970 "vkDestroyDebugReportCallbackEXT"));
971 destroy_debug_report_callback(vkinstance, instance.message, allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -0800972 }
Jesse Hall80523e22016-01-06 16:47:54 -0800973 instance.active_layers.clear();
Jesse Hall1f91d392015-12-11 16:28:44 -0800974 const VkAllocationCallbacks* alloc = instance.alloc;
975 instance.~Instance();
976 alloc->pfnFree(alloc->pUserData, &instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700977}
978
Jesse Hall1f91d392015-12-11 16:28:44 -0800979PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
980 const char* name) {
981 if (strcmp(name, "vkCreateDevice") == 0) {
982 // TODO(jessehall): Blegh, having this here is disgusting. The current
983 // layer init process can't call through the instance dispatch table's
984 // vkCreateDevice, because that goes through the instance layers rather
985 // than through the device layers. So we need to be able to get the
986 // vkCreateDevice pointer through the *device* layer chain.
987 //
988 // Because we've already created the driver device before calling
989 // through the layer vkCreateDevice functions, the loader bottom proc
990 // is a no-op.
Michael Lentine03c64b02015-08-26 18:27:26 -0500991 return reinterpret_cast<PFN_vkVoidFunction>(Noop);
992 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800993
994 // VK_ANDROID_native_buffer should be hidden from applications and layers.
995 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
996 PFN_vkVoidFunction pfn;
997 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
998 strcmp(name, "vkAcquireImageANDROID") == 0 ||
999 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
1000 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001001 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001002 if ((pfn = GetLoaderBottomProcAddr(name)))
1003 return pfn;
1004 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001005}
1006
Jesse Hall04f4f472015-08-16 19:51:04 -07001007// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -08001008// Loader top functions. These are called directly from the loader entry
1009// points or from the application (via vkGetInstanceProcAddr) without going
1010// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -07001011
Jesse Hall1f91d392015-12-11 16:28:44 -08001012VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -08001013 const char* layer_name,
1014 uint32_t* properties_count,
1015 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001016 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001017 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001018
Jesse Hall80523e22016-01-06 16:47:54 -08001019 const VkExtensionProperties* extensions = nullptr;
1020 uint32_t num_extensions = 0;
1021 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -08001022 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -08001023 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001024 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1025 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
1026 available[num_extensions++] = VkExtensionProperties{
1027 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
1028 available[num_extensions++] =
1029 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1030 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
1031 if (g_driver_instance_extensions[kEXT_debug_report]) {
1032 available[num_extensions++] =
1033 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1034 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1035 }
Jesse Hall80523e22016-01-06 16:47:54 -08001036 // TODO(jessehall): We need to also enumerate extensions supported by
1037 // implicitly-enabled layers. Currently we don't have that list of
1038 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001039 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001040 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001041
Jesse Hall80523e22016-01-06 16:47:54 -08001042 if (!properties || *properties_count > num_extensions)
1043 *properties_count = num_extensions;
1044 if (properties)
1045 std::copy(extensions, extensions + *properties_count, properties);
1046 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001047}
1048
Jesse Hall80523e22016-01-06 16:47:54 -08001049VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1050 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001051 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001052 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001053
Jesse Hall80523e22016-01-06 16:47:54 -08001054 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001055 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001056 if (!properties || *properties_count > layer_count)
1057 *properties_count = layer_count;
1058 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001059}
1060
Jesse Hall1f91d392015-12-11 16:28:44 -08001061VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1062 const VkAllocationCallbacks* allocator,
1063 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001064 VkResult result;
1065
1066 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001067 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001068
Jesse Hall03b6fe12015-11-24 12:44:21 -08001069 if (!allocator)
1070 allocator = &kDefaultAllocCallbacks;
1071
Jesse Hall04f4f472015-08-16 19:51:04 -07001072 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001073 create_info = &local_create_info;
1074
Jesse Hall3fbc8562015-11-29 22:10:52 -08001075 void* instance_mem = allocator->pfnAllocation(
1076 allocator->pUserData, sizeof(Instance), alignof(Instance),
1077 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001078 if (!instance_mem)
1079 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001080 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001081
Jesse Hall9a16f972015-10-28 15:59:53 -07001082 result = ActivateAllLayers(create_info, instance, instance);
1083 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001084 DestroyInstance_Bottom(instance->handle, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001085 return result;
1086 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001087
Jesse Hall1f91d392015-12-11 16:28:44 -08001088 void* base_object = static_cast<void*>(instance->handle);
Michael Lentine03c64b02015-08-26 18:27:26 -05001089 void* next_object = base_object;
1090 VkLayerLinkedListElem* next_element;
Jesse Hall1f91d392015-12-11 16:28:44 -08001091 PFN_vkGetInstanceProcAddr next_get_proc_addr = GetInstanceProcAddr_Bottom;
Michael Lentine03c64b02015-08-26 18:27:26 -05001092 Vector<VkLayerLinkedListElem> elem_list(
Michael Lentine1f0f5392015-09-11 14:54:34 -07001093 instance->active_layers.size(),
Michael Lentine03c64b02015-08-26 18:27:26 -05001094 CallbackAllocator<VkLayerLinkedListElem>(instance->alloc));
1095
1096 for (size_t i = elem_list.size(); i > 0; i--) {
1097 size_t idx = i - 1;
1098 next_element = &elem_list[idx];
1099 next_element->get_proc_addr =
1100 reinterpret_cast<PFN_vkGetProcAddr>(next_get_proc_addr);
1101 next_element->base_object = base_object;
1102 next_element->next_element = next_object;
1103 next_object = static_cast<void*>(next_element);
1104
Jesse Hall80523e22016-01-06 16:47:54 -08001105 next_get_proc_addr =
1106 instance->active_layers[idx].GetGetInstanceProcAddr();
Michael Lentine03c64b02015-08-26 18:27:26 -05001107 if (!next_get_proc_addr) {
Jesse Hall80523e22016-01-06 16:47:54 -08001108 next_object = next_element->next_element;
Michael Lentine03c64b02015-08-26 18:27:26 -05001109 next_get_proc_addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
Jesse Hall80523e22016-01-06 16:47:54 -08001110 next_element->get_proc_addr);
Michael Lentine03c64b02015-08-26 18:27:26 -05001111 }
1112 }
1113
Jesse Hall1f91d392015-12-11 16:28:44 -08001114 // This is the magic call that initializes all the layer instances and
1115 // allows them to create their instance_handle -> instance_data mapping.
1116 next_get_proc_addr(static_cast<VkInstance>(next_object),
1117 "vkGetInstanceProcAddr");
1118
1119 if (!LoadInstanceDispatchTable(static_cast<VkInstance>(base_object),
1120 next_get_proc_addr, instance->dispatch)) {
1121 DestroyInstance_Bottom(instance->handle, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001122 return VK_ERROR_INITIALIZATION_FAILED;
1123 }
1124
Michael Lentine950bb4f2015-09-14 13:26:30 -05001125 // Force enable callback extension if required
Jesse Hall21597662015-12-18 13:48:24 -08001126 bool enable_callback = false;
1127 bool enable_logging = false;
1128 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1129 enable_callback =
1130 property_get_bool("debug.vulkan.enable_callback", false);
1131 enable_logging = enable_callback;
1132 if (enable_callback) {
1133 enable_callback = AddExtensionToCreateInfo(
Jesse Hall715b86a2016-01-16 16:34:29 -08001134 local_create_info, "VK_EXT_debug_report", instance->alloc);
Jesse Hall21597662015-12-18 13:48:24 -08001135 }
Michael Lentine950bb4f2015-09-14 13:26:30 -05001136 }
1137
Jesse Hallc55fa942016-01-17 21:44:16 -08001138 VkInstance handle = instance->handle;
Jesse Hall1f91d392015-12-11 16:28:44 -08001139 PFN_vkCreateInstance create_instance =
1140 reinterpret_cast<PFN_vkCreateInstance>(
1141 next_get_proc_addr(instance->handle, "vkCreateInstance"));
Jesse Hallc55fa942016-01-17 21:44:16 -08001142 result = create_instance(create_info, allocator, &handle);
Michael Lentine9dbe67f2015-09-16 15:53:50 -05001143 if (enable_callback)
1144 FreeAllocatedCreateInfo(local_create_info, instance->alloc);
Jesse Hall993849c2016-01-18 00:59:45 -08001145 if (result >= 0) {
1146 *instance_out = instance->handle;
1147 } else {
Jesse Hall04f4f472015-08-16 19:51:04 -07001148 // For every layer, including the loader top and bottom layers:
1149 // - If a call to the next CreateInstance fails, the layer must clean
1150 // up anything it has successfully done so far, and propagate the
1151 // error upwards.
1152 // - If a layer successfully calls the next layer's CreateInstance, and
1153 // afterwards must fail for some reason, it must call the next layer's
1154 // DestroyInstance before returning.
1155 // - The layer must not call the next layer's DestroyInstance if that
1156 // layer's CreateInstance wasn't called, or returned failure.
1157
Jesse Hall1f91d392015-12-11 16:28:44 -08001158 // On failure, CreateInstance_Bottom frees the instance struct, so it's
Jesse Hall04f4f472015-08-16 19:51:04 -07001159 // already gone at this point. Nothing to do.
1160 }
1161
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001162 if (enable_logging) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001163 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1164 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1165 .flags =
1166 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARN_BIT_EXT,
1167 .pfnCallback = LogDebugMessageCallback,
1168 };
1169 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1170 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1171 GetInstanceProcAddr_Top(instance->handle,
1172 "vkCreateDebugReportCallbackEXT"));
1173 create_debug_report_callback(instance->handle, &callback_create_info,
1174 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001175 }
1176
Jesse Hall04f4f472015-08-16 19:51:04 -07001177 return result;
1178}
1179
Jesse Hall1f91d392015-12-11 16:28:44 -08001180PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1181 const char* name) {
1182 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1183 if (!vkinstance)
1184 return GetLoaderGlobalProcAddr(name);
1185
1186 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1187 PFN_vkVoidFunction pfn;
1188 // Always go through the loader-top function if there is one.
1189 if ((pfn = GetLoaderTopProcAddr(name)))
1190 return pfn;
1191 // Otherwise, look up the handler in the instance dispatch table
1192 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1193 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001194 // Anything not handled already must be a device-dispatched function
1195 // without a loader-top. We must return a function that will dispatch based
1196 // on the dispatchable object parameter -- which is exactly what the
1197 // exported functions do. So just return them here.
1198 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001199}
1200
Jesse Hall1f91d392015-12-11 16:28:44 -08001201void DestroyInstance_Top(VkInstance instance,
1202 const VkAllocationCallbacks* allocator) {
1203 if (!instance)
1204 return;
1205 GetDispatchTable(instance).DestroyInstance(instance, allocator);
1206}
1207
1208PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1209 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001210 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001211 return nullptr;
1212 if ((pfn = GetLoaderTopProcAddr(name)))
1213 return pfn;
1214 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001215}
1216
Jesse Hall1f91d392015-12-11 16:28:44 -08001217void GetDeviceQueue_Top(VkDevice vkdevice,
1218 uint32_t family,
1219 uint32_t index,
1220 VkQueue* queue_out) {
1221 const auto& table = GetDispatchTable(vkdevice);
1222 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1223 hwvulkan_dispatch_t* queue_dispatch =
1224 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1225 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1226 queue_dispatch->vtbl != &table)
1227 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1228 queue_dispatch->magic);
1229 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001230}
1231
Jesse Hall1f91d392015-12-11 16:28:44 -08001232VkResult AllocateCommandBuffers_Top(
1233 VkDevice vkdevice,
1234 const VkCommandBufferAllocateInfo* alloc_info,
1235 VkCommandBuffer* cmdbufs) {
1236 const auto& table = GetDispatchTable(vkdevice);
1237 VkResult result =
1238 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001239 if (result != VK_SUCCESS)
1240 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001241 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001242 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001243 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001244 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001245 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001246 cmdbuf_dispatch->magic);
1247 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001248 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001249 return VK_SUCCESS;
1250}
1251
Jesse Hall1f91d392015-12-11 16:28:44 -08001252void DestroyDevice_Top(VkDevice vkdevice,
1253 const VkAllocationCallbacks* /*allocator*/) {
1254 if (!vkdevice)
1255 return;
1256 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001257 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1258 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001259}
1260
Jesse Hall1f91d392015-12-11 16:28:44 -08001261// -----------------------------------------------------------------------------
1262
1263const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1264 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001265}
1266
Jesse Hall1f91d392015-12-11 16:28:44 -08001267const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1268 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001269}
1270
Jesse Hall715b86a2016-01-16 16:34:29 -08001271VkInstance GetDriverInstance(VkInstance instance) {
1272 return GetDispatchParent(instance).drv.instance;
1273}
1274
1275const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1276 return GetDispatchParent(instance).drv.dispatch;
1277}
1278
Jesse Hall1f91d392015-12-11 16:28:44 -08001279const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1280 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001281}
1282
Jesse Hall1f91d392015-12-11 16:28:44 -08001283const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1284 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001285}
1286
Jesse Hall715b86a2016-01-16 16:34:29 -08001287DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1288 return GetDispatchParent(instance).debug_report_callbacks;
1289}
1290
Jesse Hall04f4f472015-08-16 19:51:04 -07001291} // namespace vulkan