blob: 65319688d9052a634be51ea41dc4195f9b6a4a0b [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>
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -070039#include <vulkan/vk_layer_interface.h>
Jesse Hall04f4f472015-08-16 19:51:04 -070040
Jesse Hall26cecff2016-01-21 19:52:25 -080041// #define ENABLE_ALLOC_CALLSTACKS 1
42#if ENABLE_ALLOC_CALLSTACKS
43#include <utils/CallStack.h>
44#define ALOGD_CALLSTACK(...) \
45 do { \
46 ALOGD(__VA_ARGS__); \
47 android::CallStack callstack; \
48 callstack.update(); \
49 callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \
50 } while (false)
51#else
52#define ALOGD_CALLSTACK(...) \
53 do { \
54 } while (false)
55#endif
56
Jesse Hall04f4f472015-08-16 19:51:04 -070057using namespace vulkan;
58
59static const uint32_t kMaxPhysicalDevices = 4;
60
Michael Lentine03c64b02015-08-26 18:27:26 -050061namespace {
62
Jesse Hall1f91d392015-12-11 16:28:44 -080063// ----------------------------------------------------------------------------
Michael Lentine03c64b02015-08-26 18:27:26 -050064
Jesse Hall3fbc8562015-11-29 22:10:52 -080065// Standard-library allocator that delegates to VkAllocationCallbacks.
Jesse Hall03b6fe12015-11-24 12:44:21 -080066//
67// TODO(jessehall): This class currently always uses
Jesse Hall3fbc8562015-11-29 22:10:52 -080068// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template
Jesse Hall03b6fe12015-11-24 12:44:21 -080069// parameter or a constructor parameter. The former would help catch bugs
70// where we use the wrong scope, e.g. adding a command-scope string to an
71// instance-scope vector. But that might also be pretty annoying to deal with.
Michael Lentine03c64b02015-08-26 18:27:26 -050072template <class T>
73class CallbackAllocator {
74 public:
75 typedef T value_type;
76
Jesse Hall3fbc8562015-11-29 22:10:52 -080077 CallbackAllocator(const VkAllocationCallbacks* alloc_input)
Michael Lentine03c64b02015-08-26 18:27:26 -050078 : alloc(alloc_input) {}
79
80 template <class T2>
81 CallbackAllocator(const CallbackAllocator<T2>& other)
82 : alloc(other.alloc) {}
83
84 T* allocate(std::size_t n) {
Jesse Hall3fbc8562015-11-29 22:10:52 -080085 void* mem =
86 alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T),
87 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall26cecff2016-01-21 19:52:25 -080088 if (!mem)
89 throw std::bad_alloc();
Michael Lentine03c64b02015-08-26 18:27:26 -050090 return static_cast<T*>(mem);
91 }
92
Jesse Hall26cecff2016-01-21 19:52:25 -080093 void deallocate(T* array, std::size_t /*n*/) noexcept {
Michael Lentine03c64b02015-08-26 18:27:26 -050094 alloc->pfnFree(alloc->pUserData, array);
95 }
96
Jesse Hall3fbc8562015-11-29 22:10:52 -080097 const VkAllocationCallbacks* alloc;
Michael Lentine03c64b02015-08-26 18:27:26 -050098};
99// These are needed in order to move Strings
100template <class T>
101bool operator==(const CallbackAllocator<T>& alloc1,
102 const CallbackAllocator<T>& alloc2) {
103 return alloc1.alloc == alloc2.alloc;
104}
105template <class T>
106bool operator!=(const CallbackAllocator<T>& alloc1,
107 const CallbackAllocator<T>& alloc2) {
108 return !(alloc1 == alloc2);
109}
110
Michael Lentine03c64b02015-08-26 18:27:26 -0500111template <class T>
Jesse Hall1f91d392015-12-11 16:28:44 -0800112using Vector = std::vector<T, CallbackAllocator<T>>;
Michael Lentine03c64b02015-08-26 18:27:26 -0500113
Jesse Hall1f91d392015-12-11 16:28:44 -0800114typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>>
115 String;
Michael Lentine03c64b02015-08-26 18:27:26 -0500116
Jesse Hall1f91d392015-12-11 16:28:44 -0800117// ----------------------------------------------------------------------------
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500118
Jesse Halle1b12782015-11-30 11:27:32 -0800119VKAPI_ATTR void* DefaultAllocate(void*,
120 size_t size,
121 size_t alignment,
122 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800123 void* ptr = nullptr;
124 // Vulkan requires 'alignment' to be a power of two, but posix_memalign
125 // additionally requires that it be at least sizeof(void*).
Jesse Hall26cecff2016-01-21 19:52:25 -0800126 int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
127 ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment,
128 ret, ptr);
129 return ret == 0 ? ptr : nullptr;
Jesse Hall03b6fe12015-11-24 12:44:21 -0800130}
131
Jesse Halle1b12782015-11-30 11:27:32 -0800132VKAPI_ATTR void* DefaultReallocate(void*,
133 void* ptr,
134 size_t size,
135 size_t alignment,
136 VkSystemAllocationScope) {
Jesse Hall03b6fe12015-11-24 12:44:21 -0800137 if (size == 0) {
138 free(ptr);
139 return nullptr;
140 }
141
142 // TODO(jessehall): Right now we never shrink allocations; if the new
143 // request is smaller than the existing chunk, we just continue using it.
144 // Right now the loader never reallocs, so this doesn't matter. If that
145 // changes, or if this code is copied into some other project, this should
146 // probably have a heuristic to allocate-copy-free when doing so will save
147 // "enough" space.
148 size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
149 if (size <= old_size)
150 return ptr;
151
152 void* new_ptr = nullptr;
153 if (posix_memalign(&new_ptr, alignment, size) != 0)
154 return nullptr;
155 if (ptr) {
156 memcpy(new_ptr, ptr, std::min(old_size, size));
157 free(ptr);
158 }
159 return new_ptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700160}
161
Jesse Hall26cecff2016-01-21 19:52:25 -0800162VKAPI_ATTR void DefaultFree(void*, void* ptr) {
163 ALOGD_CALLSTACK("Free: %p", ptr);
164 free(ptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700165}
166
Jesse Hall3fbc8562015-11-29 22:10:52 -0800167const VkAllocationCallbacks kDefaultAllocCallbacks = {
Jesse Hall04f4f472015-08-16 19:51:04 -0700168 .pUserData = nullptr,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800169 .pfnAllocation = DefaultAllocate,
170 .pfnReallocation = DefaultReallocate,
Jesse Hall04f4f472015-08-16 19:51:04 -0700171 .pfnFree = DefaultFree,
172};
173
Jesse Hall1f91d392015-12-11 16:28:44 -0800174// ----------------------------------------------------------------------------
Jesse Hall80523e22016-01-06 16:47:54 -0800175// Global Data and Initialization
Jesse Hall1f91d392015-12-11 16:28:44 -0800176
Jesse Hall80523e22016-01-06 16:47:54 -0800177hwvulkan_device_t* g_hwdevice = nullptr;
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800178InstanceExtensionSet g_driver_instance_extensions;
179
Jesse Hall80523e22016-01-06 16:47:54 -0800180void LoadVulkanHAL() {
181 static const hwvulkan_module_t* module;
182 int result =
183 hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
184 if (result != 0) {
185 ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result);
186 return;
187 }
188 result = module->common.methods->open(
189 &module->common, HWVULKAN_DEVICE_0,
190 reinterpret_cast<hw_device_t**>(&g_hwdevice));
191 if (result != 0) {
192 ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result),
193 result);
194 module = nullptr;
195 return;
196 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800197
198 VkResult vkresult;
199 uint32_t count;
200 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
201 nullptr, &count, nullptr)) != VK_SUCCESS) {
202 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
203 vkresult);
204 g_hwdevice->common.close(&g_hwdevice->common);
205 g_hwdevice = nullptr;
206 module = nullptr;
207 return;
208 }
209 VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>(
210 alloca(count * sizeof(VkExtensionProperties)));
211 if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties(
212 nullptr, &count, extensions)) != VK_SUCCESS) {
213 ALOGE("driver EnumerateInstanceExtensionProperties failed: %d",
214 vkresult);
215 g_hwdevice->common.close(&g_hwdevice->common);
216 g_hwdevice = nullptr;
217 module = nullptr;
218 return;
219 }
220 ALOGV_IF(count > 0, "Driver-supported instance extensions:");
221 for (uint32_t i = 0; i < count; i++) {
222 ALOGV(" %s (v%u)", extensions[i].extensionName,
223 extensions[i].specVersion);
224 InstanceExtension id =
225 InstanceExtensionFromName(extensions[i].extensionName);
226 if (id != kInstanceExtensionCount)
227 g_driver_instance_extensions.set(id);
228 }
229 // Ignore driver attempts to support loader extensions
230 g_driver_instance_extensions.reset(kKHR_surface);
231 g_driver_instance_extensions.reset(kKHR_android_surface);
Jesse Hall80523e22016-01-06 16:47:54 -0800232}
233
Jesse Hall04f4f472015-08-16 19:51:04 -0700234bool EnsureInitialized() {
235 static std::once_flag once_flag;
Jesse Hall04f4f472015-08-16 19:51:04 -0700236 std::call_once(once_flag, []() {
Jesse Hall80523e22016-01-06 16:47:54 -0800237 LoadVulkanHAL();
238 DiscoverLayers();
Jesse Hall04f4f472015-08-16 19:51:04 -0700239 });
Jesse Hall80523e22016-01-06 16:47:54 -0800240 return g_hwdevice != nullptr;
Jesse Hall04f4f472015-08-16 19:51:04 -0700241}
242
Jesse Hall1f91d392015-12-11 16:28:44 -0800243// -----------------------------------------------------------------------------
244
245struct Instance {
246 Instance(const VkAllocationCallbacks* alloc_callbacks)
247 : dispatch_ptr(&dispatch),
248 handle(reinterpret_cast<VkInstance>(&dispatch_ptr)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800249 alloc(alloc_callbacks),
250 num_physical_devices(0),
Jesse Hall80523e22016-01-06 16:47:54 -0800251 active_layers(CallbackAllocator<LayerRef>(alloc)),
Jesse Hall1f91d392015-12-11 16:28:44 -0800252 message(VK_NULL_HANDLE) {
253 memset(&dispatch, 0, sizeof(dispatch));
254 memset(physical_devices, 0, sizeof(physical_devices));
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600255 enabled_extensions.reset();
Jesse Hall1f91d392015-12-11 16:28:44 -0800256 drv.instance = VK_NULL_HANDLE;
257 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
258 drv.num_physical_devices = 0;
259 }
260
Jesse Hall80523e22016-01-06 16:47:54 -0800261 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800262
263 const InstanceDispatchTable* dispatch_ptr;
264 const VkInstance handle;
265 InstanceDispatchTable dispatch;
266
Jesse Hall1f91d392015-12-11 16:28:44 -0800267 const VkAllocationCallbacks* alloc;
268 uint32_t num_physical_devices;
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -0600269 VkPhysicalDevice physical_devices_top[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800270 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;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600276 InstanceExtensionSet enabled_extensions;
Jesse Hall1f91d392015-12-11 16:28:44 -0800277
278 struct {
279 VkInstance instance;
280 DriverDispatchTable dispatch;
281 uint32_t num_physical_devices;
282 } drv; // may eventually be an array
283};
284
285struct Device {
286 Device(Instance* instance_)
287 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800288 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800289 memset(&dispatch, 0, sizeof(dispatch));
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600290 enabled_extensions.reset();
Jesse Hall1f91d392015-12-11 16:28:44 -0800291 }
292 DeviceDispatchTable dispatch;
293 Instance* instance;
294 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800295 Vector<LayerRef> active_layers;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600296 DeviceExtensionSet enabled_extensions;
Jesse Hall1f91d392015-12-11 16:28:44 -0800297};
298
299template <typename THandle>
300struct HandleTraits {};
301template <>
302struct HandleTraits<VkInstance> {
303 typedef Instance LoaderObjectType;
304};
305template <>
306struct HandleTraits<VkPhysicalDevice> {
307 typedef Instance LoaderObjectType;
308};
309template <>
310struct HandleTraits<VkDevice> {
311 typedef Device LoaderObjectType;
312};
313template <>
314struct HandleTraits<VkQueue> {
315 typedef Device LoaderObjectType;
316};
317template <>
318struct HandleTraits<VkCommandBuffer> {
319 typedef Device LoaderObjectType;
320};
321
322template <typename THandle>
323typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
324 THandle handle) {
325 // TODO(jessehall): Make Instance and Device POD types (by removing the
326 // non-default constructors), so that offsetof is actually legal to use.
327 // The specific case we're using here is safe in gcc/clang (and probably
328 // most other C++ compilers), but isn't guaranteed by C++.
329 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
330#pragma clang diagnostic push
331#pragma clang diagnostic ignored "-Winvalid-offsetof"
332 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
333#pragma clang diagnostic pop
334
335 const auto& dispatch = GetDispatchTable(handle);
336 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
337 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
338 return *reinterpret_cast<ObjectType*>(object_addr);
339}
340
341// -----------------------------------------------------------------------------
342
Jesse Hall04f4f472015-08-16 19:51:04 -0700343void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800344 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700345 device->~Device();
346 alloc->pfnFree(alloc->pUserData, device);
347}
348
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500349template <class TObject>
Jesse Hallaa410942016-01-17 13:07:10 -0800350LayerRef GetLayerRef(const char* name);
351template <>
352LayerRef GetLayerRef<Instance>(const char* name) {
353 return GetInstanceLayerRef(name);
354}
355template <>
356LayerRef GetLayerRef<Device>(const char* name) {
357 return GetDeviceLayerRef(name);
358}
359
360template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800361bool ActivateLayer(TObject* object, const char* name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800362 LayerRef layer(GetLayerRef<TObject>(name));
Jesse Hall80523e22016-01-06 16:47:54 -0800363 if (!layer)
364 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500365 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall26cecff2016-01-21 19:52:25 -0800366 layer) == object->active_layers.end()) {
367 try {
368 object->active_layers.push_back(std::move(layer));
369 } catch (std::bad_alloc&) {
370 // TODO(jessehall): We should fail with VK_ERROR_OUT_OF_MEMORY
371 // if we can't enable a requested layer. Callers currently ignore
372 // ActivateLayer's return value.
373 ALOGW("failed to activate layer '%s': out of memory", name);
374 return false;
375 }
376 }
Jesse Hall80523e22016-01-06 16:47:54 -0800377 ALOGV("activated layer '%s'", name);
378 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500379}
380
Michael Lentine9da191b2015-10-13 11:08:45 -0500381struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500382 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500383 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500384};
385
Michael Lentine9da191b2015-10-13 11:08:45 -0500386void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500387 const char* value,
388 void* data) {
Jesse Hall26cecff2016-01-21 19:52:25 -0800389 try {
390 const char prefix[] = "debug.vulkan.layer.";
391 const size_t prefixlen = sizeof(prefix) - 1;
392 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
393 return;
394 const char* number_str = name + prefixlen;
395 long layer_number = strtol(number_str, nullptr, 10);
396 if (layer_number <= 0 || layer_number == LONG_MAX) {
397 ALOGW("Cannot use a layer at number %ld from string %s",
398 layer_number, number_str);
399 return;
400 }
401 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
402 Vector<String>* layer_names = instance_names_pair->layer_names;
403 Instance* instance = instance_names_pair->instance;
404 size_t layer_size = static_cast<size_t>(layer_number);
405 if (layer_size > layer_names->size()) {
406 layer_names->resize(
407 layer_size, String(CallbackAllocator<char>(instance->alloc)));
408 }
409 (*layer_names)[layer_size - 1] = value;
410 } catch (std::bad_alloc&) {
411 ALOGW("failed to handle property '%s'='%s': out of memory", name,
412 value);
Michael Lentine9da191b2015-10-13 11:08:45 -0500413 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500414 }
415}
416
417template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800418VkResult ActivateAllLayers(TInfo create_info,
419 Instance* instance,
420 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500421 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
422 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
423 "Cannot activate layers for unknown object %p", object);
424 CallbackAllocator<char> string_allocator(instance->alloc);
425 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800426 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500427 char layer_prop[PROPERTY_VALUE_MAX];
428 property_get("debug.vulkan.layers", layer_prop, "");
Jesse Hall26cecff2016-01-21 19:52:25 -0800429 char* strtok_state;
430 char* layer_name = nullptr;
431 while ((layer_name = strtok_r(layer_name ? nullptr : layer_prop, ":",
432 &strtok_state))) {
433 ActivateLayer(object, layer_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500434 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500435 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
436 InstanceNamesPair instance_names_pair = {.instance = instance,
437 .layer_names = &layer_names};
438 property_list(SetLayerNamesFromProperty,
439 static_cast<void*>(&instance_names_pair));
440 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800441 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500442 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500443 }
444 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800445 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800446 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700447 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800448 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
449 ? "instance"
450 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800451 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700452 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500453 }
454 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700455 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500456}
457
Michael Lentine57036832016-03-04 11:03:35 -0600458template <class TCreateInfo, class TObject>
459bool AddLayersToCreateInfo(TCreateInfo& local_create_info,
460 const TObject& object,
461 const VkAllocationCallbacks* alloc,
462 bool& allocatedMemory) {
463 // This should never happen and means there is a likely a bug in layer
464 // tracking
465 if (object->active_layers.size() < local_create_info.enabledLayerCount) {
466 ALOGE("Total number of layers is less than those enabled by the app!");
467 return false;
468 }
469 // Check if the total number of layers enabled is greater than those
470 // enabled by the application. If it is then we have system enabled
471 // layers which need to be added to the list of layers passed in through
472 // create.
473 if (object->active_layers.size() > local_create_info.enabledLayerCount) {
474 void* mem = alloc->pfnAllocation(
475 alloc->pUserData, object->active_layers.size() * sizeof(char*),
476 alignof(char*), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
477 if (mem) {
478 local_create_info.enabledLayerCount = 0;
479 const char** names = static_cast<const char**>(mem);
480 for (const auto& layer : object->active_layers) {
481 const char* name = layer.GetName();
482 names[local_create_info.enabledLayerCount++] = name;
483 }
484 local_create_info.ppEnabledLayerNames = names;
485 } else {
486 ALOGE("System layers cannot be enabled: memory allocation failed");
487 return false;
488 }
489 allocatedMemory = true;
490 } else {
491 allocatedMemory = false;
492 }
493 return true;
494}
495
496template <class T>
497void FreeAllocatedLayerCreateInfo(T& local_create_info,
498 const VkAllocationCallbacks* alloc) {
499 alloc->pfnFree(alloc->pUserData,
500 const_cast<char**>(local_create_info.ppEnabledLayerNames));
501}
502
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500503template <class TCreateInfo>
504bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
505 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800506 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800507 uint32_t extension_count = local_create_info.enabledExtensionCount;
508 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800509 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800510 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800511 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
Michael Lentine57036832016-03-04 11:03:35 -0600512 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500513 if (mem) {
514 const char** enabled_extensions = static_cast<const char**>(mem);
515 for (uint32_t i = 0; i < extension_count; ++i) {
516 enabled_extensions[i] =
517 local_create_info.ppEnabledExtensionNames[i];
518 }
519 enabled_extensions[extension_count] = extension_name;
520 local_create_info.ppEnabledExtensionNames = enabled_extensions;
521 } else {
Michael Lentine57036832016-03-04 11:03:35 -0600522 ALOGE("%s extension cannot be enabled: memory allocation failed",
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500523 extension_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500524 return false;
525 }
526 return true;
527}
528
529template <class T>
Michael Lentine57036832016-03-04 11:03:35 -0600530void FreeAllocatedExtensionCreateInfo(T& local_create_info,
531 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500532 alloc->pfnFree(
533 alloc->pUserData,
534 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
535}
536
Jesse Halle1b12782015-11-30 11:27:32 -0800537VKAPI_ATTR
Jesse Hall715b86a2016-01-16 16:34:29 -0800538VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
539 VkDebugReportObjectTypeEXT /*objectType*/,
540 uint64_t /*object*/,
Michael Lentineeb970862015-10-15 12:42:22 -0500541 size_t /*location*/,
542 int32_t message_code,
543 const char* layer_prefix,
544 const char* message,
545 void* /*user_data*/) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800546 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500547 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
Jesse Halle2948d82016-02-25 04:19:32 -0800548 } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500549 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
550 }
Michael Lentineeb970862015-10-15 12:42:22 -0500551 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500552}
553
Jesse Hall06193802015-12-03 16:12:51 -0800554VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500555 return VK_SUCCESS;
556}
557
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700558/*
559 * This function will return the pNext pointer of any
560 * CreateInfo extensions that are not loader extensions.
561 * This is used to skip past the loader extensions prepended
562 * to the list during CreateInstance and CreateDevice.
563 */
564void* StripCreateExtensions(const void* pNext) {
565 VkLayerInstanceCreateInfo* create_info =
566 const_cast<VkLayerInstanceCreateInfo*>(
567 static_cast<const VkLayerInstanceCreateInfo*>(pNext));
568
569 while (
570 create_info &&
571 (create_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
572 create_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)) {
573 create_info = const_cast<VkLayerInstanceCreateInfo*>(
574 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
575 }
576
577 return create_info;
578}
579
Jesse Hallfee71432016-03-05 22:27:02 -0800580// Clean up and deallocate an Instance; called from both the failure paths in
581// CreateInstance_Top as well as from DestroyInstance_Top. This function does
582// not call down the dispatch chain; that should be done before calling this
583// function, iff the lower vkCreateInstance call has been made and returned
584// successfully.
585void DestroyInstance(Instance* instance,
586 const VkAllocationCallbacks* allocator) {
587 if (instance->message) {
588 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
589 destroy_debug_report_callback =
590 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
591 GetInstanceProcAddr_Top(instance->handle,
592 "vkDestroyDebugReportCallbackEXT"));
593 destroy_debug_report_callback(instance->handle, instance->message,
594 allocator);
595 }
596 instance->~Instance();
597 allocator->pfnFree(allocator->pUserData, instance);
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -0700598}
599
Jesse Hall1f91d392015-12-11 16:28:44 -0800600} // anonymous namespace
601
602namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500603
Jesse Hall04f4f472015-08-16 19:51:04 -0700604// -----------------------------------------------------------------------------
605// "Bottom" functions. These are called at the end of the instance dispatch
606// chain.
607
Jesse Hall1f91d392015-12-11 16:28:44 -0800608VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
609 const VkAllocationCallbacks* allocator,
610 VkInstance* vkinstance) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700611 VkResult result;
612
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700613 VkLayerInstanceCreateInfo* chain_info =
614 const_cast<VkLayerInstanceCreateInfo*>(
615 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
616 while (
617 chain_info &&
618 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
619 chain_info->function == VK_LAYER_FUNCTION_INSTANCE)) {
620 chain_info = const_cast<VkLayerInstanceCreateInfo*>(
621 static_cast<const VkLayerInstanceCreateInfo*>(chain_info->pNext));
622 }
623 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
624
625 Instance& instance = GetDispatchParent(
626 static_cast<VkInstance>(chain_info->u.instanceInfo.instance_info));
627
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800628 // Check that all enabled extensions are supported
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800629 uint32_t num_driver_extensions = 0;
630 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
631 const char* name = create_info->ppEnabledExtensionNames[i];
632 InstanceExtension id = InstanceExtensionFromName(name);
633 if (id != kInstanceExtensionCount) {
634 if (g_driver_instance_extensions[id]) {
635 num_driver_extensions++;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600636 instance.enabled_extensions.set(id);
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800637 continue;
638 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700639 if (id == kKHR_surface || id == kKHR_android_surface) {
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600640 instance.enabled_extensions.set(id);
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800641 continue;
642 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700643 // The loader natively supports debug report.
644 if (id == kEXT_debug_report) {
645 continue;
646 }
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800647 }
648 bool supported = false;
649 for (const auto& layer : instance.active_layers) {
650 if (layer.SupportsExtension(name))
651 supported = true;
652 }
653 if (!supported) {
654 ALOGE(
655 "requested instance extension '%s' not supported by "
656 "loader, driver, or any active layers",
657 name);
658 DestroyInstance_Bottom(instance.handle, allocator);
659 return VK_ERROR_EXTENSION_NOT_PRESENT;
660 }
661 }
662
Jesse Halla7ac76d2016-01-08 22:29:42 -0800663 VkInstanceCreateInfo driver_create_info = *create_info;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700664 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
Jesse Halla7ac76d2016-01-08 22:29:42 -0800665 driver_create_info.enabledLayerCount = 0;
666 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800667 driver_create_info.enabledExtensionCount = 0;
668 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800669 if (num_driver_extensions > 0) {
670 const char** names = static_cast<const char**>(
671 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800672 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800673 const char* name = create_info->ppEnabledExtensionNames[i];
674 InstanceExtension id = InstanceExtensionFromName(name);
675 if (id != kInstanceExtensionCount) {
676 if (g_driver_instance_extensions[id]) {
677 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800678 continue;
679 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800680 }
681 }
682 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800683 ALOG_ASSERT(
684 driver_create_info.enabledExtensionCount == num_driver_extensions,
685 "counted enabled driver instance extensions twice and got "
686 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800687 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800688
689 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800690 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700691 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800692 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700693 return result;
694 }
695
Jesse Hall1f91d392015-12-11 16:28:44 -0800696 hwvulkan_dispatch_t* drv_dispatch =
697 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700698 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700699 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800700 drv_dispatch->magic);
701 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700702 return VK_ERROR_INITIALIZATION_FAILED;
703 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700704 // Skip setting drv_dispatch->vtbl, since we never call through it;
705 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700706
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600707 if (!LoadDriverDispatchTable(
708 instance.drv.instance, g_hwdevice->GetInstanceProcAddr,
709 instance.enabled_extensions, instance.drv.dispatch)) {
Courtney Goeltzenleuchteraa6c8722016-01-29 08:57:16 -0700710 DestroyInstance_Bottom(instance.handle, allocator);
711 return VK_ERROR_INITIALIZATION_FAILED;
712 }
713
Jesse Hall04f4f472015-08-16 19:51:04 -0700714 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800715 result = instance.drv.dispatch.EnumeratePhysicalDevices(
716 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700717 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800718 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700719 return VK_ERROR_INITIALIZATION_FAILED;
720 }
721 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800722 result = instance.drv.dispatch.EnumeratePhysicalDevices(
723 instance.drv.instance, &num_physical_devices,
724 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700725 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800726 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700727 return VK_ERROR_INITIALIZATION_FAILED;
728 }
Jesse Hallb1471272016-01-17 21:36:58 -0800729
730 Vector<VkExtensionProperties> extensions(
731 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700732 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800733 hwvulkan_dispatch_t* pdev_dispatch =
734 reinterpret_cast<hwvulkan_dispatch_t*>(
735 instance.physical_devices[i]);
736 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700737 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800738 pdev_dispatch->magic);
739 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700740 return VK_ERROR_INITIALIZATION_FAILED;
741 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800742 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800743
744 uint32_t count;
745 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
746 instance.physical_devices[i], nullptr, &count, nullptr)) !=
747 VK_SUCCESS) {
748 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
749 result);
750 continue;
751 }
Jesse Hall26cecff2016-01-21 19:52:25 -0800752 try {
753 extensions.resize(count);
754 } catch (std::bad_alloc&) {
755 ALOGE("instance creation failed: out of memory");
756 DestroyInstance_Bottom(instance.handle, allocator);
757 return VK_ERROR_OUT_OF_HOST_MEMORY;
758 }
Jesse Hallb1471272016-01-17 21:36:58 -0800759 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
760 instance.physical_devices[i], nullptr, &count,
761 extensions.data())) != VK_SUCCESS) {
762 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
763 result);
764 continue;
765 }
766 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
767 for (const auto& extension : extensions) {
768 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
769 DeviceExtension id =
770 DeviceExtensionFromName(extension.extensionName);
771 if (id == kDeviceExtensionCount) {
772 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
773 extension.extensionName);
774 } else {
775 instance.physical_device_driver_extensions[i].set(id);
776 }
777 }
778 // Ignore driver attempts to support loader extensions
779 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700780 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800781 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800782 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800783
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700784 *vkinstance = instance.handle;
785
Jesse Hall04f4f472015-08-16 19:51:04 -0700786 return VK_SUCCESS;
787}
788
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600789VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance,
790 const VkAndroidSurfaceCreateInfoKHR*,
791 const VkAllocationCallbacks*,
792 VkSurfaceKHR*) {
793 ALOGE(
794 "VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not "
795 "executed.");
796
797 return VK_SUCCESS;
798}
799
800void DestroySurfaceKHR_Disabled(VkInstance,
801 VkSurfaceKHR,
802 const VkAllocationCallbacks*) {
803 ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
804}
805
806VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice,
807 uint32_t,
808 VkSurfaceKHR,
809 VkBool32*) {
810 ALOGE(
811 "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not "
812 "executed.");
813
814 return VK_SUCCESS;
815}
816
817VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled(
818 VkPhysicalDevice,
819 VkSurfaceKHR,
820 VkSurfaceCapabilitiesKHR*) {
821 ALOGE(
822 "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceapabilitiesKHR "
823 "not executed.");
824
825 return VK_SUCCESS;
826}
827
828VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice,
829 VkSurfaceKHR,
830 uint32_t*,
831 VkSurfaceFormatKHR*) {
832 ALOGE(
833 "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not "
834 "executed.");
835
836 return VK_SUCCESS;
837}
838
839VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice,
840 VkSurfaceKHR,
841 uint32_t*,
842 VkPresentModeKHR*) {
843 ALOGE(
844 "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR "
845 "not executed.");
846
847 return VK_SUCCESS;
848}
849
850PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance vkinstance,
851 const char* name) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800852 PFN_vkVoidFunction pfn;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -0600853
854 if (vkinstance) {
855 Instance& instance = GetDispatchParent(vkinstance);
856 if (!instance.enabled_extensions[kKHR_android_surface]) {
857 // KHR_android_surface is not enabled, use error stubs instead
858 if (strcmp(name, "vkCreateAndroidSurfaceKHR") == 0) {
859 return reinterpret_cast<PFN_vkVoidFunction>(
860 CreateAndroidSurfaceKHR_Disabled);
861 }
862 }
863 if (!instance.enabled_extensions[kKHR_surface]) {
864 // KHR_surface is not enabled, use error stubs instead
865 if (strcmp(name, "vkDestroySurfaceKHR") == 0) {
866 return reinterpret_cast<PFN_vkVoidFunction>(
867 DestroySurfaceKHR_Disabled);
868 }
869 if (strcmp(name, "vkGetPhysicalDeviceSurfaceSupportKHR") == 0) {
870 return reinterpret_cast<PFN_vkVoidFunction>(
871 GetPhysicalDeviceSurfaceSupportKHR_Disabled);
872 }
873 if (strcmp(name, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") ==
874 0) {
875 return reinterpret_cast<PFN_vkVoidFunction>(
876 GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled);
877 }
878 if (strcmp(name, "vkGetPhysicalDeviceSurfaceFormatsKHR") == 0) {
879 return reinterpret_cast<PFN_vkVoidFunction>(
880 GetPhysicalDeviceSurfaceFormatsKHR_Disabled);
881 }
882 if (strcmp(name, "vkGetPhysicalDeviceSurfacePresentModesKHR") ==
883 0) {
884 return reinterpret_cast<PFN_vkVoidFunction>(
885 GetPhysicalDeviceSurfacePresentModesKHR_Disabled);
886 }
887 }
888 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800889 if ((pfn = GetLoaderBottomProcAddr(name)))
890 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800891 return nullptr;
892}
893
894VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
895 uint32_t* pdev_count,
896 VkPhysicalDevice* pdevs) {
897 Instance& instance = GetDispatchParent(vkinstance);
898 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700899 if (pdevs) {
900 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800901 std::copy(instance.physical_devices, instance.physical_devices + count,
902 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700903 }
904 *pdev_count = count;
905 return VK_SUCCESS;
906}
907
Jesse Hall1f91d392015-12-11 16:28:44 -0800908void GetPhysicalDeviceProperties_Bottom(
909 VkPhysicalDevice pdev,
910 VkPhysicalDeviceProperties* properties) {
911 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
912 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700913}
914
Jesse Hall1f91d392015-12-11 16:28:44 -0800915void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
916 VkPhysicalDeviceFeatures* features) {
917 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
918 features);
919}
920
921void GetPhysicalDeviceMemoryProperties_Bottom(
922 VkPhysicalDevice pdev,
923 VkPhysicalDeviceMemoryProperties* properties) {
924 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
925 pdev, properties);
926}
927
928void GetPhysicalDeviceQueueFamilyProperties_Bottom(
929 VkPhysicalDevice pdev,
930 uint32_t* pCount,
931 VkQueueFamilyProperties* properties) {
932 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
933 pdev, pCount, properties);
934}
935
936void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
937 VkFormat format,
938 VkFormatProperties* properties) {
939 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700940 pdev, format, properties);
941}
942
Jesse Hall1f91d392015-12-11 16:28:44 -0800943VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700944 VkPhysicalDevice pdev,
945 VkFormat format,
946 VkImageType type,
947 VkImageTiling tiling,
948 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700949 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700950 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800951 return GetDispatchParent(pdev)
952 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800953 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700954}
955
Jesse Hall1f91d392015-12-11 16:28:44 -0800956void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700957 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800958 VkFormat format,
959 VkImageType type,
960 VkSampleCountFlagBits samples,
961 VkImageUsageFlags usage,
962 VkImageTiling tiling,
963 uint32_t* properties_count,
964 VkSparseImageFormatProperties* properties) {
965 GetDispatchParent(pdev)
966 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
967 pdev, format, type, samples, usage, tiling, properties_count,
968 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700969}
970
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700971// This is a no-op, the Top function returns the aggregate layer property
972// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800973VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800974VkResult EnumerateDeviceExtensionProperties_Bottom(
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700975 VkPhysicalDevice /*pdev*/,
976 const char* /*layer_name*/,
977 uint32_t* /*properties_count*/,
978 VkExtensionProperties* /*properties*/) {
979 return VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700980}
981
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700982// This is a no-op, the Top function returns the aggregate layer property
983// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800984VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700985VkResult EnumerateDeviceLayerProperties_Bottom(
986 VkPhysicalDevice /*pdev*/,
987 uint32_t* /*properties_count*/,
988 VkLayerProperties* /*properties*/) {
989 return VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800990}
991
992VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800993VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800994 const VkDeviceCreateInfo* create_info,
995 const VkAllocationCallbacks* allocator,
996 VkDevice* device_out) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700997 VkLayerDeviceCreateInfo* chain_info = const_cast<VkLayerDeviceCreateInfo*>(
998 static_cast<const VkLayerDeviceCreateInfo*>(create_info->pNext));
999 while (chain_info &&
1000 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO &&
1001 chain_info->function == VK_LAYER_FUNCTION_DEVICE)) {
1002 chain_info = const_cast<VkLayerDeviceCreateInfo*>(
1003 static_cast<const VkLayerDeviceCreateInfo*>(chain_info->pNext));
Jesse Hall9a16f972015-10-28 15:59:53 -07001004 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001005 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
Jesse Hall9a16f972015-10-28 15:59:53 -07001006
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001007 Instance& instance = GetDispatchParent(gpu);
Jesse Hallb1471272016-01-17 21:36:58 -08001008 size_t gpu_idx = 0;
1009 while (instance.physical_devices[gpu_idx] != gpu)
1010 gpu_idx++;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001011 Device* device = static_cast<Device*>(chain_info->u.deviceInfo.device_info);
1012 PFN_vkGetInstanceProcAddr get_instance_proc_addr =
1013 chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
1014
1015 VkDeviceCreateInfo driver_create_info = *create_info;
1016 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
1017 driver_create_info.enabledLayerCount = 0;
1018 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Hallb1471272016-01-17 21:36:58 -08001019
1020 uint32_t num_driver_extensions = 0;
1021 const char** driver_extensions = static_cast<const char**>(
1022 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
1023 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
1024 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -08001025 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -08001026 if (id != kDeviceExtensionCount) {
1027 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
1028 driver_extensions[num_driver_extensions++] = name;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -06001029 device->enabled_extensions.set(id);
Jesse Hallae3b70d2016-01-17 22:05:29 -08001030 continue;
1031 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001032 // Add the VK_ANDROID_native_buffer extension to the list iff
1033 // the VK_KHR_swapchain extension was requested
Jesse Hallae3b70d2016-01-17 22:05:29 -08001034 if (id == kKHR_swapchain &&
1035 instance.physical_device_driver_extensions
1036 [gpu_idx][kANDROID_native_buffer]) {
1037 driver_extensions[num_driver_extensions++] =
1038 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -06001039 device->enabled_extensions.set(id);
Jesse Hallae3b70d2016-01-17 22:05:29 -08001040 continue;
1041 }
Jesse Hallb1471272016-01-17 21:36:58 -08001042 }
Jesse Hallb1471272016-01-17 21:36:58 -08001043 bool supported = false;
1044 for (const auto& layer : device->active_layers) {
1045 if (layer.SupportsExtension(name))
1046 supported = true;
1047 }
1048 if (!supported) {
1049 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -08001050 "requested device extension '%s' not supported by loader, "
1051 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -08001052 name);
Jesse Hallb1471272016-01-17 21:36:58 -08001053 return VK_ERROR_EXTENSION_NOT_PRESENT;
1054 }
1055 }
1056
Jesse Hallb1471272016-01-17 21:36:58 -08001057 driver_create_info.enabledExtensionCount = num_driver_extensions;
1058 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Hall04f4f472015-08-16 19:51:04 -07001059 VkDevice drv_device;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001060 VkResult result = instance.drv.dispatch.CreateDevice(
1061 gpu, &driver_create_info, allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001062 if (result != VK_SUCCESS) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001063 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001064 }
1065
Jesse Hall1f91d392015-12-11 16:28:44 -08001066 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -07001067 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -08001068 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
1069 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
1070 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -05001071 PFN_vkDestroyDevice destroy_device =
1072 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -08001073 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
1074 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -08001075 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001076 return VK_ERROR_INITIALIZATION_FAILED;
1077 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001078
1079 // Set dispatch table for newly created Device
1080 // CreateDevice_Top will fill in the details
Jesse Hall1f91d392015-12-11 16:28:44 -08001081 drv_dispatch->vtbl = &device->dispatch;
1082 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
1083 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
1084 "vkGetDeviceProcAddr"));
Jesse Hall1f91d392015-12-11 16:28:44 -08001085 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -07001086 return VK_SUCCESS;
1087}
1088
Jesse Hall1f91d392015-12-11 16:28:44 -08001089void DestroyInstance_Bottom(VkInstance vkinstance,
1090 const VkAllocationCallbacks* allocator) {
1091 Instance& instance = GetDispatchParent(vkinstance);
1092
1093 // These checks allow us to call DestroyInstance_Bottom from any error
1094 // path in CreateInstance_Bottom, before the driver instance is fully
1095 // initialized.
1096 if (instance.drv.instance != VK_NULL_HANDLE &&
1097 instance.drv.dispatch.DestroyInstance) {
1098 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001099 instance.drv.instance = VK_NULL_HANDLE;
Jesse Hall1f91d392015-12-11 16:28:44 -08001100 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001101}
1102
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -06001103VkResult CreateSwapchainKHR_Disabled(VkDevice,
1104 const VkSwapchainCreateInfoKHR*,
1105 const VkAllocationCallbacks*,
1106 VkSwapchainKHR*) {
1107 ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
1108
1109 return VK_SUCCESS;
1110}
1111
1112void DestroySwapchainKHR_Disabled(VkDevice,
1113 VkSwapchainKHR,
1114 const VkAllocationCallbacks*) {
1115 ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
1116}
1117
1118VkResult GetSwapchainImagesKHR_Disabled(VkDevice,
1119 VkSwapchainKHR,
1120 uint32_t*,
1121 VkImage*) {
1122 ALOGE(
1123 "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
1124
1125 return VK_SUCCESS;
1126}
1127
1128VkResult AcquireNextImageKHR_Disabled(VkDevice,
1129 VkSwapchainKHR,
1130 uint64_t,
1131 VkSemaphore,
1132 VkFence,
1133 uint32_t*) {
1134 ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
1135
1136 return VK_SUCCESS;
1137}
1138
1139VkResult QueuePresentKHR_Disabled(VkQueue, const VkPresentInfoKHR*) {
1140 ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
1141
1142 return VK_SUCCESS;
1143}
1144
Jesse Hall1f91d392015-12-11 16:28:44 -08001145PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
1146 const char* name) {
1147 if (strcmp(name, "vkCreateDevice") == 0) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001148 return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom);
Michael Lentine03c64b02015-08-26 18:27:26 -05001149 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001150
Courtney Goeltzenleuchtera76e8ff2016-03-22 08:09:58 -06001151 Device& device = GetDispatchParent(vkdevice);
1152 if (!device.enabled_extensions[kKHR_swapchain]) {
1153 if (strcmp(name, "vkCreateSwapchainKHR") == 0) {
1154 return reinterpret_cast<PFN_vkVoidFunction>(
1155 CreateSwapchainKHR_Disabled);
1156 }
1157 if (strcmp(name, "vkDestroySwapchainKHR") == 0) {
1158 return reinterpret_cast<PFN_vkVoidFunction>(
1159 DestroySwapchainKHR_Disabled);
1160 }
1161 if (strcmp(name, "vkGetSwapchainImagesKHR") == 0) {
1162 return reinterpret_cast<PFN_vkVoidFunction>(
1163 GetSwapchainImagesKHR_Disabled);
1164 }
1165 if (strcmp(name, "vkAcquireNextSwapchainImageKHR") == 0) {
1166 return reinterpret_cast<PFN_vkVoidFunction>(
1167 AcquireNextImageKHR_Disabled);
1168 }
1169 if (strcmp(name, "vkQueuePresentKHR") == 0) {
1170 return reinterpret_cast<PFN_vkVoidFunction>(
1171 QueuePresentKHR_Disabled);
1172 }
1173 }
1174
Jesse Hall1f91d392015-12-11 16:28:44 -08001175 // VK_ANDROID_native_buffer should be hidden from applications and layers.
1176 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
1177 PFN_vkVoidFunction pfn;
1178 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
1179 strcmp(name, "vkAcquireImageANDROID") == 0 ||
1180 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
1181 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001182 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001183 if ((pfn = GetLoaderBottomProcAddr(name)))
1184 return pfn;
1185 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001186}
1187
Jesse Hall04f4f472015-08-16 19:51:04 -07001188// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -08001189// Loader top functions. These are called directly from the loader entry
1190// points or from the application (via vkGetInstanceProcAddr) without going
1191// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -07001192
Jesse Hall1f91d392015-12-11 16:28:44 -08001193VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -08001194 const char* layer_name,
1195 uint32_t* properties_count,
1196 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001197 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001198 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001199
Jesse Hall80523e22016-01-06 16:47:54 -08001200 const VkExtensionProperties* extensions = nullptr;
1201 uint32_t num_extensions = 0;
1202 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -08001203 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -08001204 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001205 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1206 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
1207 available[num_extensions++] = VkExtensionProperties{
1208 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
1209 available[num_extensions++] =
1210 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1211 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
1212 if (g_driver_instance_extensions[kEXT_debug_report]) {
1213 available[num_extensions++] =
1214 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1215 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1216 }
Jesse Hall80523e22016-01-06 16:47:54 -08001217 // TODO(jessehall): We need to also enumerate extensions supported by
1218 // implicitly-enabled layers. Currently we don't have that list of
1219 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001220 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001221 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001222
Jesse Hall80523e22016-01-06 16:47:54 -08001223 if (!properties || *properties_count > num_extensions)
1224 *properties_count = num_extensions;
1225 if (properties)
1226 std::copy(extensions, extensions + *properties_count, properties);
1227 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001228}
1229
Jesse Hall80523e22016-01-06 16:47:54 -08001230VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1231 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001232 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001233 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001234
Jesse Hall80523e22016-01-06 16:47:54 -08001235 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001236 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001237 if (!properties || *properties_count > layer_count)
1238 *properties_count = layer_count;
1239 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001240}
1241
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -07001242VKAPI_ATTR
1243VkResult EnumerateDeviceExtensionProperties_Top(
1244 VkPhysicalDevice gpu,
1245 const char* layer_name,
1246 uint32_t* properties_count,
1247 VkExtensionProperties* properties) {
1248 const VkExtensionProperties* extensions = nullptr;
1249 uint32_t num_extensions = 0;
1250
1251 ALOGV("EnumerateDeviceExtensionProperties_Top:");
1252 if (layer_name) {
1253 ALOGV(" layer %s", layer_name);
1254 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
1255 } else {
1256 ALOGV(" no layer");
1257 Instance& instance = GetDispatchParent(gpu);
1258 size_t gpu_idx = 0;
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -06001259 while (instance.physical_devices_top[gpu_idx] != gpu)
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -07001260 gpu_idx++;
1261 const DeviceExtensionSet driver_extensions =
1262 instance.physical_device_driver_extensions[gpu_idx];
1263
1264 // We only support VK_KHR_swapchain if the GPU supports
1265 // VK_ANDROID_native_buffer
1266 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1267 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
1268 if (driver_extensions[kANDROID_native_buffer]) {
1269 available[num_extensions++] = VkExtensionProperties{
1270 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
1271 }
1272
1273 // TODO(jessehall): We need to also enumerate extensions supported by
1274 // implicitly-enabled layers. Currently we don't have that list of
1275 // layers until instance creation.
1276 extensions = available;
1277 }
1278
1279 ALOGV(" num: %d, extensions: %p", num_extensions, extensions);
1280 if (!properties || *properties_count > num_extensions)
1281 *properties_count = num_extensions;
1282 if (properties)
1283 std::copy(extensions, extensions + *properties_count, properties);
1284 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
1285}
1286
Jesse Hall1f91d392015-12-11 16:28:44 -08001287VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1288 const VkAllocationCallbacks* allocator,
1289 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001290 VkResult result;
1291
1292 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001293 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001294
Jesse Hall03b6fe12015-11-24 12:44:21 -08001295 if (!allocator)
1296 allocator = &kDefaultAllocCallbacks;
1297
Jesse Hall04f4f472015-08-16 19:51:04 -07001298 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001299 create_info = &local_create_info;
1300
Jesse Hall3fbc8562015-11-29 22:10:52 -08001301 void* instance_mem = allocator->pfnAllocation(
1302 allocator->pUserData, sizeof(Instance), alignof(Instance),
1303 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001304 if (!instance_mem)
1305 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001306 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001307
Jesse Hall9a16f972015-10-28 15:59:53 -07001308 result = ActivateAllLayers(create_info, instance, instance);
1309 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001310 DestroyInstance(instance, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001311 return result;
1312 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001313
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001314 uint32_t activated_layers = 0;
1315 VkLayerInstanceCreateInfo chain_info;
1316 VkLayerInstanceLink* layer_instance_link_info = nullptr;
1317 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1318 VkInstance local_instance = nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001319
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001320 if (instance->active_layers.size() > 0) {
1321 chain_info.u.pLayerInfo = nullptr;
1322 chain_info.pNext = create_info->pNext;
1323 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1324 chain_info.function = VK_LAYER_FUNCTION_LINK;
1325 local_create_info.pNext = &chain_info;
Michael Lentine03c64b02015-08-26 18:27:26 -05001326
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001327 layer_instance_link_info = static_cast<VkLayerInstanceLink*>(alloca(
1328 sizeof(VkLayerInstanceLink) * instance->active_layers.size()));
1329 if (!layer_instance_link_info) {
1330 ALOGE("Failed to alloc Instance objects for layers");
Jesse Hallfee71432016-03-05 22:27:02 -08001331 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001332 return VK_ERROR_OUT_OF_HOST_MEMORY;
1333 }
1334
1335 /* Create instance chain of enabled layers */
1336 for (auto rit = instance->active_layers.rbegin();
1337 rit != instance->active_layers.rend(); ++rit) {
1338 LayerRef& layer = *rit;
1339 layer_instance_link_info[activated_layers].pNext =
1340 chain_info.u.pLayerInfo;
1341 layer_instance_link_info[activated_layers]
1342 .pfnNextGetInstanceProcAddr = next_gipa;
1343 chain_info.u.pLayerInfo =
1344 &layer_instance_link_info[activated_layers];
1345 next_gipa = layer.GetGetInstanceProcAddr();
1346
1347 ALOGV("Insert instance layer %s (v%u)", layer.GetName(),
1348 layer.GetSpecVersion());
1349
1350 activated_layers++;
Michael Lentine03c64b02015-08-26 18:27:26 -05001351 }
1352 }
1353
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001354 PFN_vkCreateInstance create_instance =
1355 reinterpret_cast<PFN_vkCreateInstance>(
1356 next_gipa(VK_NULL_HANDLE, "vkCreateInstance"));
1357 if (!create_instance) {
Jesse Hallfee71432016-03-05 22:27:02 -08001358 DestroyInstance(instance, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001359 return VK_ERROR_INITIALIZATION_FAILED;
1360 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001361 VkLayerInstanceCreateInfo instance_create_info;
1362
1363 instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1364 instance_create_info.function = VK_LAYER_FUNCTION_INSTANCE;
1365
1366 instance_create_info.u.instanceInfo.instance_info = instance;
1367 instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1368
1369 instance_create_info.pNext = local_create_info.pNext;
1370 local_create_info.pNext = &instance_create_info;
1371
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001372 // Force enable callback extension if required
1373 bool enable_callback = false;
1374 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1375 enable_callback =
1376 property_get_bool("debug.vulkan.enable_callback", false);
1377 if (enable_callback) {
Michael Lentine57036832016-03-04 11:03:35 -06001378 if (!AddExtensionToCreateInfo(local_create_info,
1379 "VK_EXT_debug_report", allocator)) {
1380 DestroyInstance(instance, allocator);
1381 return VK_ERROR_INITIALIZATION_FAILED;
1382 }
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001383 }
1384 }
Michael Lentine57036832016-03-04 11:03:35 -06001385 bool allocatedLayerMem;
1386 if (!AddLayersToCreateInfo(local_create_info, instance, allocator,
1387 allocatedLayerMem)) {
1388 if (enable_callback) {
1389 FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
1390 }
1391 DestroyInstance(instance, allocator);
1392 return VK_ERROR_INITIALIZATION_FAILED;
1393 }
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001394
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001395 result = create_instance(&local_create_info, allocator, &local_instance);
Michael Lentine57036832016-03-04 11:03:35 -06001396
1397 if (allocatedLayerMem) {
1398 FreeAllocatedLayerCreateInfo(local_create_info, allocator);
1399 }
1400 if (enable_callback) {
1401 FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
1402 }
1403
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001404 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001405 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001406 return result;
1407 }
1408
1409 const InstanceDispatchTable& instance_dispatch =
1410 GetDispatchTable(local_instance);
1411 if (!LoadInstanceDispatchTable(
1412 local_instance, next_gipa,
1413 const_cast<InstanceDispatchTable&>(instance_dispatch))) {
1414 ALOGV("Failed to initialize instance dispatch table");
1415 PFN_vkDestroyInstance destroy_instance =
1416 reinterpret_cast<PFN_vkDestroyInstance>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001417 next_gipa(local_instance, "vkDestroyInstance"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001418 if (!destroy_instance) {
1419 ALOGD("Loader unable to find DestroyInstance");
1420 return VK_ERROR_INITIALIZATION_FAILED;
1421 }
1422 destroy_instance(local_instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001423 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001424 return VK_ERROR_INITIALIZATION_FAILED;
1425 }
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -06001426
1427 // Capture the physical devices from the top of the
1428 // chain in case it has been wrapped by a layer.
1429 uint32_t num_physical_devices = 0;
1430 result = instance_dispatch.EnumeratePhysicalDevices(
1431 local_instance, &num_physical_devices, nullptr);
1432 if (result != VK_SUCCESS) {
1433 DestroyInstance(instance, allocator);
1434 return VK_ERROR_INITIALIZATION_FAILED;
1435 }
1436 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
1437 result = instance_dispatch.EnumeratePhysicalDevices(
1438 local_instance, &num_physical_devices,
1439 instance->physical_devices_top);
1440 if (result != VK_SUCCESS) {
1441 DestroyInstance(instance, allocator);
1442 return VK_ERROR_INITIALIZATION_FAILED;
1443 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001444 *instance_out = local_instance;
Michael Lentine03c64b02015-08-26 18:27:26 -05001445
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001446 if (enable_callback) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001447 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1448 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1449 .flags =
Jesse Halle2948d82016-02-25 04:19:32 -08001450 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
Jesse Hall715b86a2016-01-16 16:34:29 -08001451 .pfnCallback = LogDebugMessageCallback,
1452 };
1453 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1454 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1455 GetInstanceProcAddr_Top(instance->handle,
1456 "vkCreateDebugReportCallbackEXT"));
1457 create_debug_report_callback(instance->handle, &callback_create_info,
1458 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001459 }
1460
Jesse Hall04f4f472015-08-16 19:51:04 -07001461 return result;
1462}
1463
Jesse Hall1f91d392015-12-11 16:28:44 -08001464PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1465 const char* name) {
1466 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1467 if (!vkinstance)
1468 return GetLoaderGlobalProcAddr(name);
1469
1470 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1471 PFN_vkVoidFunction pfn;
1472 // Always go through the loader-top function if there is one.
1473 if ((pfn = GetLoaderTopProcAddr(name)))
1474 return pfn;
1475 // Otherwise, look up the handler in the instance dispatch table
1476 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1477 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001478 // Anything not handled already must be a device-dispatched function
1479 // without a loader-top. We must return a function that will dispatch based
1480 // on the dispatchable object parameter -- which is exactly what the
1481 // exported functions do. So just return them here.
1482 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001483}
1484
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001485void DestroyInstance_Top(VkInstance vkinstance,
Jesse Hall1f91d392015-12-11 16:28:44 -08001486 const VkAllocationCallbacks* allocator) {
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001487 if (!vkinstance)
Jesse Hall1f91d392015-12-11 16:28:44 -08001488 return;
Jesse Hallfee71432016-03-05 22:27:02 -08001489 if (!allocator)
1490 allocator = &kDefaultAllocCallbacks;
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001491 GetDispatchTable(vkinstance).DestroyInstance(vkinstance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001492 DestroyInstance(&(GetDispatchParent(vkinstance)), allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -08001493}
1494
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001495VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -07001496VkResult EnumerateDeviceLayerProperties_Top(VkPhysicalDevice /*pdev*/,
1497 uint32_t* properties_count,
1498 VkLayerProperties* properties) {
1499 uint32_t layer_count =
1500 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
1501 if (!properties || *properties_count > layer_count)
1502 *properties_count = layer_count;
1503 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
1504}
1505
1506VKAPI_ATTR
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001507VkResult CreateDevice_Top(VkPhysicalDevice gpu,
1508 const VkDeviceCreateInfo* create_info,
1509 const VkAllocationCallbacks* allocator,
1510 VkDevice* device_out) {
1511 Instance& instance = GetDispatchParent(gpu);
1512 VkResult result;
1513
1514 // FIXME(jessehall): We don't have good conventions or infrastructure yet to
1515 // do better than just using the instance allocator and scope for
1516 // everything. See b/26732122.
1517 if (true /*!allocator*/)
1518 allocator = instance.alloc;
1519
1520 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
1521 alignof(Device),
1522 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1523 if (!mem)
1524 return VK_ERROR_OUT_OF_HOST_MEMORY;
1525 Device* device = new (mem) Device(&instance);
1526
1527 result = ActivateAllLayers(create_info, &instance, device);
1528 if (result != VK_SUCCESS) {
1529 DestroyDevice(device);
1530 return result;
1531 }
1532
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001533 uint32_t activated_layers = 0;
1534 VkLayerDeviceCreateInfo chain_info;
1535 VkLayerDeviceLink* layer_device_link_info = nullptr;
1536 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1537 PFN_vkGetDeviceProcAddr next_gdpa = GetDeviceProcAddr_Bottom;
1538 VkDeviceCreateInfo local_create_info = *create_info;
1539 VkDevice local_device = nullptr;
1540
1541 if (device->active_layers.size() > 0) {
1542 chain_info.u.pLayerInfo = nullptr;
1543 chain_info.pNext = local_create_info.pNext;
1544 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1545 chain_info.function = VK_LAYER_FUNCTION_LINK;
1546 local_create_info.pNext = &chain_info;
1547
1548 layer_device_link_info = static_cast<VkLayerDeviceLink*>(
1549 alloca(sizeof(VkLayerDeviceLink) * device->active_layers.size()));
1550 if (!layer_device_link_info) {
1551 ALOGE("Failed to alloc Device objects for layers");
1552 DestroyDevice(device);
1553 return VK_ERROR_OUT_OF_HOST_MEMORY;
1554 }
1555
1556 /* Create device chain of enabled layers */
1557 for (auto rit = device->active_layers.rbegin();
1558 rit != device->active_layers.rend(); ++rit) {
1559 LayerRef& layer = *rit;
1560 layer_device_link_info[activated_layers].pNext =
1561 chain_info.u.pLayerInfo;
1562 layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr =
1563 next_gdpa;
1564 layer_device_link_info[activated_layers]
1565 .pfnNextGetInstanceProcAddr = next_gipa;
1566 chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
1567
1568 next_gipa = layer.GetGetInstanceProcAddr();
1569 next_gdpa = layer.GetGetDeviceProcAddr();
1570
1571 ALOGV("Insert device layer %s (v%u)", layer.GetName(),
1572 layer.GetSpecVersion());
1573
1574 activated_layers++;
1575 }
1576 }
1577
1578 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001579 next_gipa(instance.handle, "vkCreateDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001580 if (!create_device) {
1581 ALOGE("Unable to find vkCreateDevice for driver");
1582 DestroyDevice(device);
1583 return VK_ERROR_INITIALIZATION_FAILED;
1584 }
1585
1586 VkLayerDeviceCreateInfo device_create_info;
1587
1588 device_create_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1589 device_create_info.function = VK_LAYER_FUNCTION_DEVICE;
1590
1591 device_create_info.u.deviceInfo.device_info = device;
1592 device_create_info.u.deviceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1593
1594 device_create_info.pNext = local_create_info.pNext;
1595 local_create_info.pNext = &device_create_info;
1596
Michael Lentine57036832016-03-04 11:03:35 -06001597 bool allocatedLayerMem;
1598 if (!AddLayersToCreateInfo(local_create_info, device, allocator,
1599 allocatedLayerMem)) {
1600 DestroyDevice(device);
1601 return VK_ERROR_INITIALIZATION_FAILED;
1602 }
1603
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001604 result = create_device(gpu, &local_create_info, allocator, &local_device);
1605
Michael Lentine57036832016-03-04 11:03:35 -06001606 if (allocatedLayerMem) {
1607 FreeAllocatedLayerCreateInfo(local_create_info, allocator);
1608 }
1609
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001610 if (result != VK_SUCCESS) {
1611 DestroyDevice(device);
1612 return result;
1613 }
1614
1615 // Set dispatch table for newly created Device
1616 hwvulkan_dispatch_t* vulkan_dispatch =
1617 reinterpret_cast<hwvulkan_dispatch_t*>(local_device);
1618 vulkan_dispatch->vtbl = &device->dispatch;
1619
1620 const DeviceDispatchTable& device_dispatch = GetDispatchTable(local_device);
1621 if (!LoadDeviceDispatchTable(
1622 local_device, next_gdpa,
1623 const_cast<DeviceDispatchTable&>(device_dispatch))) {
1624 ALOGV("Failed to initialize device dispatch table");
1625 PFN_vkDestroyDevice destroy_device =
1626 reinterpret_cast<PFN_vkDestroyDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001627 next_gipa(instance.handle, "vkDestroyDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001628 ALOG_ASSERT(destroy_device != nullptr,
1629 "Loader unable to find DestroyDevice");
1630 destroy_device(local_device, allocator);
1631 return VK_ERROR_INITIALIZATION_FAILED;
1632 }
1633 *device_out = local_device;
1634
1635 return VK_SUCCESS;
1636}
1637
Jesse Hall1f91d392015-12-11 16:28:44 -08001638PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1639 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001640 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001641 return nullptr;
1642 if ((pfn = GetLoaderTopProcAddr(name)))
1643 return pfn;
1644 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001645}
1646
Jesse Hall1f91d392015-12-11 16:28:44 -08001647void GetDeviceQueue_Top(VkDevice vkdevice,
1648 uint32_t family,
1649 uint32_t index,
1650 VkQueue* queue_out) {
1651 const auto& table = GetDispatchTable(vkdevice);
1652 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1653 hwvulkan_dispatch_t* queue_dispatch =
1654 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1655 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1656 queue_dispatch->vtbl != &table)
1657 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1658 queue_dispatch->magic);
1659 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001660}
1661
Jesse Hall1f91d392015-12-11 16:28:44 -08001662VkResult AllocateCommandBuffers_Top(
1663 VkDevice vkdevice,
1664 const VkCommandBufferAllocateInfo* alloc_info,
1665 VkCommandBuffer* cmdbufs) {
1666 const auto& table = GetDispatchTable(vkdevice);
1667 VkResult result =
1668 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001669 if (result != VK_SUCCESS)
1670 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001671 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001672 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001673 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001674 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001675 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001676 cmdbuf_dispatch->magic);
1677 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001678 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001679 return VK_SUCCESS;
1680}
1681
Jesse Hall1f91d392015-12-11 16:28:44 -08001682void DestroyDevice_Top(VkDevice vkdevice,
1683 const VkAllocationCallbacks* /*allocator*/) {
1684 if (!vkdevice)
1685 return;
1686 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001687 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1688 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001689}
1690
Jesse Hall1f91d392015-12-11 16:28:44 -08001691// -----------------------------------------------------------------------------
1692
1693const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1694 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001695}
1696
Jesse Hall1f91d392015-12-11 16:28:44 -08001697const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1698 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001699}
1700
Jesse Hall715b86a2016-01-16 16:34:29 -08001701VkInstance GetDriverInstance(VkInstance instance) {
1702 return GetDispatchParent(instance).drv.instance;
1703}
1704
1705const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1706 return GetDispatchParent(instance).drv.dispatch;
1707}
1708
Jesse Hall1f91d392015-12-11 16:28:44 -08001709const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1710 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001711}
1712
Jesse Hall1f91d392015-12-11 16:28:44 -08001713const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1714 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001715}
1716
Jesse Hall715b86a2016-01-16 16:34:29 -08001717DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1718 return GetDispatchParent(instance).debug_report_callbacks;
1719}
1720
Jesse Hall04f4f472015-08-16 19:51:04 -07001721} // namespace vulkan