blob: 07044a3d21d944eeb2a5edb6e1797f079e9c11c0 [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));
Jesse Hall1f91d392015-12-11 16:28:44 -0800255 drv.instance = VK_NULL_HANDLE;
256 memset(&drv.dispatch, 0, sizeof(drv.dispatch));
257 drv.num_physical_devices = 0;
258 }
259
Jesse Hall80523e22016-01-06 16:47:54 -0800260 ~Instance() {}
Jesse Hall1f91d392015-12-11 16:28:44 -0800261
262 const InstanceDispatchTable* dispatch_ptr;
263 const VkInstance handle;
264 InstanceDispatchTable dispatch;
265
Jesse Hall1f91d392015-12-11 16:28:44 -0800266 const VkAllocationCallbacks* alloc;
267 uint32_t num_physical_devices;
268 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
Jesse Hallb1471272016-01-17 21:36:58 -0800269 DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800270
Jesse Hall80523e22016-01-06 16:47:54 -0800271 Vector<LayerRef> active_layers;
Jesse Hall715b86a2016-01-16 16:34:29 -0800272 VkDebugReportCallbackEXT message;
273 DebugReportCallbackList debug_report_callbacks;
Jesse Hall1f91d392015-12-11 16:28:44 -0800274
275 struct {
276 VkInstance instance;
277 DriverDispatchTable dispatch;
278 uint32_t num_physical_devices;
279 } drv; // may eventually be an array
280};
281
282struct Device {
283 Device(Instance* instance_)
284 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800285 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800286 memset(&dispatch, 0, sizeof(dispatch));
287 }
288 DeviceDispatchTable dispatch;
289 Instance* instance;
290 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800291 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800292};
293
294template <typename THandle>
295struct HandleTraits {};
296template <>
297struct HandleTraits<VkInstance> {
298 typedef Instance LoaderObjectType;
299};
300template <>
301struct HandleTraits<VkPhysicalDevice> {
302 typedef Instance LoaderObjectType;
303};
304template <>
305struct HandleTraits<VkDevice> {
306 typedef Device LoaderObjectType;
307};
308template <>
309struct HandleTraits<VkQueue> {
310 typedef Device LoaderObjectType;
311};
312template <>
313struct HandleTraits<VkCommandBuffer> {
314 typedef Device LoaderObjectType;
315};
316
317template <typename THandle>
318typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
319 THandle handle) {
320 // TODO(jessehall): Make Instance and Device POD types (by removing the
321 // non-default constructors), so that offsetof is actually legal to use.
322 // The specific case we're using here is safe in gcc/clang (and probably
323 // most other C++ compilers), but isn't guaranteed by C++.
324 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
325#pragma clang diagnostic push
326#pragma clang diagnostic ignored "-Winvalid-offsetof"
327 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
328#pragma clang diagnostic pop
329
330 const auto& dispatch = GetDispatchTable(handle);
331 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
332 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
333 return *reinterpret_cast<ObjectType*>(object_addr);
334}
335
336// -----------------------------------------------------------------------------
337
Jesse Hall04f4f472015-08-16 19:51:04 -0700338void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800339 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700340 device->~Device();
341 alloc->pfnFree(alloc->pUserData, device);
342}
343
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500344template <class TObject>
Jesse Hallaa410942016-01-17 13:07:10 -0800345LayerRef GetLayerRef(const char* name);
346template <>
347LayerRef GetLayerRef<Instance>(const char* name) {
348 return GetInstanceLayerRef(name);
349}
350template <>
351LayerRef GetLayerRef<Device>(const char* name) {
352 return GetDeviceLayerRef(name);
353}
354
355template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800356bool ActivateLayer(TObject* object, const char* name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800357 LayerRef layer(GetLayerRef<TObject>(name));
Jesse Hall80523e22016-01-06 16:47:54 -0800358 if (!layer)
359 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500360 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall26cecff2016-01-21 19:52:25 -0800361 layer) == object->active_layers.end()) {
362 try {
363 object->active_layers.push_back(std::move(layer));
364 } catch (std::bad_alloc&) {
365 // TODO(jessehall): We should fail with VK_ERROR_OUT_OF_MEMORY
366 // if we can't enable a requested layer. Callers currently ignore
367 // ActivateLayer's return value.
368 ALOGW("failed to activate layer '%s': out of memory", name);
369 return false;
370 }
371 }
Jesse Hall80523e22016-01-06 16:47:54 -0800372 ALOGV("activated layer '%s'", name);
373 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500374}
375
Michael Lentine9da191b2015-10-13 11:08:45 -0500376struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500377 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500378 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500379};
380
Michael Lentine9da191b2015-10-13 11:08:45 -0500381void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500382 const char* value,
383 void* data) {
Jesse Hall26cecff2016-01-21 19:52:25 -0800384 try {
385 const char prefix[] = "debug.vulkan.layer.";
386 const size_t prefixlen = sizeof(prefix) - 1;
387 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
388 return;
389 const char* number_str = name + prefixlen;
390 long layer_number = strtol(number_str, nullptr, 10);
391 if (layer_number <= 0 || layer_number == LONG_MAX) {
392 ALOGW("Cannot use a layer at number %ld from string %s",
393 layer_number, number_str);
394 return;
395 }
396 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
397 Vector<String>* layer_names = instance_names_pair->layer_names;
398 Instance* instance = instance_names_pair->instance;
399 size_t layer_size = static_cast<size_t>(layer_number);
400 if (layer_size > layer_names->size()) {
401 layer_names->resize(
402 layer_size, String(CallbackAllocator<char>(instance->alloc)));
403 }
404 (*layer_names)[layer_size - 1] = value;
405 } catch (std::bad_alloc&) {
406 ALOGW("failed to handle property '%s'='%s': out of memory", name,
407 value);
Michael Lentine9da191b2015-10-13 11:08:45 -0500408 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500409 }
410}
411
412template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800413VkResult ActivateAllLayers(TInfo create_info,
414 Instance* instance,
415 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500416 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
417 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
418 "Cannot activate layers for unknown object %p", object);
419 CallbackAllocator<char> string_allocator(instance->alloc);
420 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800421 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500422 char layer_prop[PROPERTY_VALUE_MAX];
423 property_get("debug.vulkan.layers", layer_prop, "");
Jesse Hall26cecff2016-01-21 19:52:25 -0800424 char* strtok_state;
425 char* layer_name = nullptr;
426 while ((layer_name = strtok_r(layer_name ? nullptr : layer_prop, ":",
427 &strtok_state))) {
428 ActivateLayer(object, layer_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500429 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500430 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
431 InstanceNamesPair instance_names_pair = {.instance = instance,
432 .layer_names = &layer_names};
433 property_list(SetLayerNamesFromProperty,
434 static_cast<void*>(&instance_names_pair));
435 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800436 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500437 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500438 }
439 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800440 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800441 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700442 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800443 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
444 ? "instance"
445 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800446 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700447 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500448 }
449 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700450 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500451}
452
453template <class TCreateInfo>
454bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
455 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800456 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800457 uint32_t extension_count = local_create_info.enabledExtensionCount;
458 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800459 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800460 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800461 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
462 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500463 if (mem) {
464 const char** enabled_extensions = static_cast<const char**>(mem);
465 for (uint32_t i = 0; i < extension_count; ++i) {
466 enabled_extensions[i] =
467 local_create_info.ppEnabledExtensionNames[i];
468 }
469 enabled_extensions[extension_count] = extension_name;
470 local_create_info.ppEnabledExtensionNames = enabled_extensions;
471 } else {
472 ALOGW("%s extension cannot be enabled: memory allocation failed",
473 extension_name);
Jesse Hall3dd678a2016-01-08 21:52:01 -0800474 local_create_info.enabledExtensionCount--;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500475 return false;
476 }
477 return true;
478}
479
480template <class T>
481void FreeAllocatedCreateInfo(T& local_create_info,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800482 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500483 alloc->pfnFree(
484 alloc->pUserData,
485 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
486}
487
Jesse Halle1b12782015-11-30 11:27:32 -0800488VKAPI_ATTR
Jesse Hall715b86a2016-01-16 16:34:29 -0800489VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
490 VkDebugReportObjectTypeEXT /*objectType*/,
491 uint64_t /*object*/,
Michael Lentineeb970862015-10-15 12:42:22 -0500492 size_t /*location*/,
493 int32_t message_code,
494 const char* layer_prefix,
495 const char* message,
496 void* /*user_data*/) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800497 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500498 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
Jesse Halle2948d82016-02-25 04:19:32 -0800499 } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500500 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
501 }
Michael Lentineeb970862015-10-15 12:42:22 -0500502 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500503}
504
Jesse Hall06193802015-12-03 16:12:51 -0800505VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500506 return VK_SUCCESS;
507}
508
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700509/*
510 * This function will return the pNext pointer of any
511 * CreateInfo extensions that are not loader extensions.
512 * This is used to skip past the loader extensions prepended
513 * to the list during CreateInstance and CreateDevice.
514 */
515void* StripCreateExtensions(const void* pNext) {
516 VkLayerInstanceCreateInfo* create_info =
517 const_cast<VkLayerInstanceCreateInfo*>(
518 static_cast<const VkLayerInstanceCreateInfo*>(pNext));
519
520 while (
521 create_info &&
522 (create_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
523 create_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)) {
524 create_info = const_cast<VkLayerInstanceCreateInfo*>(
525 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
526 }
527
528 return create_info;
529}
530
Jesse Hallfee71432016-03-05 22:27:02 -0800531// Clean up and deallocate an Instance; called from both the failure paths in
532// CreateInstance_Top as well as from DestroyInstance_Top. This function does
533// not call down the dispatch chain; that should be done before calling this
534// function, iff the lower vkCreateInstance call has been made and returned
535// successfully.
536void DestroyInstance(Instance* instance,
537 const VkAllocationCallbacks* allocator) {
538 if (instance->message) {
539 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
540 destroy_debug_report_callback =
541 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
542 GetInstanceProcAddr_Top(instance->handle,
543 "vkDestroyDebugReportCallbackEXT"));
544 destroy_debug_report_callback(instance->handle, instance->message,
545 allocator);
546 }
547 instance->~Instance();
548 allocator->pfnFree(allocator->pUserData, instance);
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -0700549}
550
Jesse Hall1f91d392015-12-11 16:28:44 -0800551} // anonymous namespace
552
553namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500554
Jesse Hall04f4f472015-08-16 19:51:04 -0700555// -----------------------------------------------------------------------------
556// "Bottom" functions. These are called at the end of the instance dispatch
557// chain.
558
Jesse Hall1f91d392015-12-11 16:28:44 -0800559VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
560 const VkAllocationCallbacks* allocator,
561 VkInstance* vkinstance) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700562 VkResult result;
563
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700564 VkLayerInstanceCreateInfo* chain_info =
565 const_cast<VkLayerInstanceCreateInfo*>(
566 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
567 while (
568 chain_info &&
569 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
570 chain_info->function == VK_LAYER_FUNCTION_INSTANCE)) {
571 chain_info = const_cast<VkLayerInstanceCreateInfo*>(
572 static_cast<const VkLayerInstanceCreateInfo*>(chain_info->pNext));
573 }
574 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
575
576 Instance& instance = GetDispatchParent(
577 static_cast<VkInstance>(chain_info->u.instanceInfo.instance_info));
578
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800579 // Check that all enabled extensions are supported
580 InstanceExtensionSet enabled_extensions;
581 uint32_t num_driver_extensions = 0;
582 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
583 const char* name = create_info->ppEnabledExtensionNames[i];
584 InstanceExtension id = InstanceExtensionFromName(name);
585 if (id != kInstanceExtensionCount) {
586 if (g_driver_instance_extensions[id]) {
587 num_driver_extensions++;
588 enabled_extensions.set(id);
589 continue;
590 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700591 if (id == kKHR_surface || id == kKHR_android_surface) {
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800592 enabled_extensions.set(id);
593 continue;
594 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700595 // The loader natively supports debug report.
596 if (id == kEXT_debug_report) {
597 continue;
598 }
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800599 }
600 bool supported = false;
601 for (const auto& layer : instance.active_layers) {
602 if (layer.SupportsExtension(name))
603 supported = true;
604 }
605 if (!supported) {
606 ALOGE(
607 "requested instance extension '%s' not supported by "
608 "loader, driver, or any active layers",
609 name);
610 DestroyInstance_Bottom(instance.handle, allocator);
611 return VK_ERROR_EXTENSION_NOT_PRESENT;
612 }
613 }
614
Jesse Halla7ac76d2016-01-08 22:29:42 -0800615 VkInstanceCreateInfo driver_create_info = *create_info;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700616 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
Jesse Halla7ac76d2016-01-08 22:29:42 -0800617 driver_create_info.enabledLayerCount = 0;
618 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800619 driver_create_info.enabledExtensionCount = 0;
620 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800621 if (num_driver_extensions > 0) {
622 const char** names = static_cast<const char**>(
623 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800624 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800625 const char* name = create_info->ppEnabledExtensionNames[i];
626 InstanceExtension id = InstanceExtensionFromName(name);
627 if (id != kInstanceExtensionCount) {
628 if (g_driver_instance_extensions[id]) {
629 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800630 continue;
631 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800632 }
633 }
634 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800635 ALOG_ASSERT(
636 driver_create_info.enabledExtensionCount == num_driver_extensions,
637 "counted enabled driver instance extensions twice and got "
638 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800639 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800640
641 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800642 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700643 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800644 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700645 return result;
646 }
647
Jesse Hall1f91d392015-12-11 16:28:44 -0800648 hwvulkan_dispatch_t* drv_dispatch =
649 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700650 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700651 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800652 drv_dispatch->magic);
653 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700654 return VK_ERROR_INITIALIZATION_FAILED;
655 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700656 // Skip setting drv_dispatch->vtbl, since we never call through it;
657 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700658
Courtney Goeltzenleuchteraa6c8722016-01-29 08:57:16 -0700659 if (!LoadDriverDispatchTable(instance.drv.instance,
660 g_hwdevice->GetInstanceProcAddr,
661 enabled_extensions, instance.drv.dispatch)) {
662 DestroyInstance_Bottom(instance.handle, allocator);
663 return VK_ERROR_INITIALIZATION_FAILED;
664 }
665
Jesse Hall04f4f472015-08-16 19:51:04 -0700666 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800667 result = instance.drv.dispatch.EnumeratePhysicalDevices(
668 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700669 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800670 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700671 return VK_ERROR_INITIALIZATION_FAILED;
672 }
673 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800674 result = instance.drv.dispatch.EnumeratePhysicalDevices(
675 instance.drv.instance, &num_physical_devices,
676 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700677 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800678 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700679 return VK_ERROR_INITIALIZATION_FAILED;
680 }
Jesse Hallb1471272016-01-17 21:36:58 -0800681
682 Vector<VkExtensionProperties> extensions(
683 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700684 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800685 hwvulkan_dispatch_t* pdev_dispatch =
686 reinterpret_cast<hwvulkan_dispatch_t*>(
687 instance.physical_devices[i]);
688 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700689 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800690 pdev_dispatch->magic);
691 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700692 return VK_ERROR_INITIALIZATION_FAILED;
693 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800694 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800695
696 uint32_t count;
697 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
698 instance.physical_devices[i], nullptr, &count, nullptr)) !=
699 VK_SUCCESS) {
700 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
701 result);
702 continue;
703 }
Jesse Hall26cecff2016-01-21 19:52:25 -0800704 try {
705 extensions.resize(count);
706 } catch (std::bad_alloc&) {
707 ALOGE("instance creation failed: out of memory");
708 DestroyInstance_Bottom(instance.handle, allocator);
709 return VK_ERROR_OUT_OF_HOST_MEMORY;
710 }
Jesse Hallb1471272016-01-17 21:36:58 -0800711 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
712 instance.physical_devices[i], nullptr, &count,
713 extensions.data())) != VK_SUCCESS) {
714 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
715 result);
716 continue;
717 }
718 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
719 for (const auto& extension : extensions) {
720 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
721 DeviceExtension id =
722 DeviceExtensionFromName(extension.extensionName);
723 if (id == kDeviceExtensionCount) {
724 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
725 extension.extensionName);
726 } else {
727 instance.physical_device_driver_extensions[i].set(id);
728 }
729 }
730 // Ignore driver attempts to support loader extensions
731 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700732 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800733 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800734 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800735
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700736 *vkinstance = instance.handle;
737
Jesse Hall04f4f472015-08-16 19:51:04 -0700738 return VK_SUCCESS;
739}
740
Jesse Hall1f91d392015-12-11 16:28:44 -0800741PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
742 PFN_vkVoidFunction pfn;
743 if ((pfn = GetLoaderBottomProcAddr(name)))
744 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800745 return nullptr;
746}
747
748VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
749 uint32_t* pdev_count,
750 VkPhysicalDevice* pdevs) {
751 Instance& instance = GetDispatchParent(vkinstance);
752 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700753 if (pdevs) {
754 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800755 std::copy(instance.physical_devices, instance.physical_devices + count,
756 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700757 }
758 *pdev_count = count;
759 return VK_SUCCESS;
760}
761
Jesse Hall1f91d392015-12-11 16:28:44 -0800762void GetPhysicalDeviceProperties_Bottom(
763 VkPhysicalDevice pdev,
764 VkPhysicalDeviceProperties* properties) {
765 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
766 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700767}
768
Jesse Hall1f91d392015-12-11 16:28:44 -0800769void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
770 VkPhysicalDeviceFeatures* features) {
771 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
772 features);
773}
774
775void GetPhysicalDeviceMemoryProperties_Bottom(
776 VkPhysicalDevice pdev,
777 VkPhysicalDeviceMemoryProperties* properties) {
778 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
779 pdev, properties);
780}
781
782void GetPhysicalDeviceQueueFamilyProperties_Bottom(
783 VkPhysicalDevice pdev,
784 uint32_t* pCount,
785 VkQueueFamilyProperties* properties) {
786 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
787 pdev, pCount, properties);
788}
789
790void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
791 VkFormat format,
792 VkFormatProperties* properties) {
793 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700794 pdev, format, properties);
795}
796
Jesse Hall1f91d392015-12-11 16:28:44 -0800797VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700798 VkPhysicalDevice pdev,
799 VkFormat format,
800 VkImageType type,
801 VkImageTiling tiling,
802 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700803 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700804 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800805 return GetDispatchParent(pdev)
806 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800807 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700808}
809
Jesse Hall1f91d392015-12-11 16:28:44 -0800810void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700811 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800812 VkFormat format,
813 VkImageType type,
814 VkSampleCountFlagBits samples,
815 VkImageUsageFlags usage,
816 VkImageTiling tiling,
817 uint32_t* properties_count,
818 VkSparseImageFormatProperties* properties) {
819 GetDispatchParent(pdev)
820 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
821 pdev, format, type, samples, usage, tiling, properties_count,
822 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700823}
824
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700825// This is a no-op, the Top function returns the aggregate layer property
826// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800827VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800828VkResult EnumerateDeviceExtensionProperties_Bottom(
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700829 VkPhysicalDevice /*pdev*/,
830 const char* /*layer_name*/,
831 uint32_t* /*properties_count*/,
832 VkExtensionProperties* /*properties*/) {
833 return VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700834}
835
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700836// This is a no-op, the Top function returns the aggregate layer property
837// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800838VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700839VkResult EnumerateDeviceLayerProperties_Bottom(
840 VkPhysicalDevice /*pdev*/,
841 uint32_t* /*properties_count*/,
842 VkLayerProperties* /*properties*/) {
843 return VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800844}
845
846VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800847VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800848 const VkDeviceCreateInfo* create_info,
849 const VkAllocationCallbacks* allocator,
850 VkDevice* device_out) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700851 VkLayerDeviceCreateInfo* chain_info = const_cast<VkLayerDeviceCreateInfo*>(
852 static_cast<const VkLayerDeviceCreateInfo*>(create_info->pNext));
853 while (chain_info &&
854 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO &&
855 chain_info->function == VK_LAYER_FUNCTION_DEVICE)) {
856 chain_info = const_cast<VkLayerDeviceCreateInfo*>(
857 static_cast<const VkLayerDeviceCreateInfo*>(chain_info->pNext));
Jesse Hall9a16f972015-10-28 15:59:53 -0700858 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700859 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
Jesse Hall9a16f972015-10-28 15:59:53 -0700860
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700861 Instance& instance = GetDispatchParent(gpu);
Jesse Hallb1471272016-01-17 21:36:58 -0800862 size_t gpu_idx = 0;
863 while (instance.physical_devices[gpu_idx] != gpu)
864 gpu_idx++;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700865 Device* device = static_cast<Device*>(chain_info->u.deviceInfo.device_info);
866 PFN_vkGetInstanceProcAddr get_instance_proc_addr =
867 chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
868
869 VkDeviceCreateInfo driver_create_info = *create_info;
870 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
871 driver_create_info.enabledLayerCount = 0;
872 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800873
874 uint32_t num_driver_extensions = 0;
875 const char** driver_extensions = static_cast<const char**>(
876 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
877 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
878 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -0800879 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -0800880 if (id != kDeviceExtensionCount) {
881 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
882 driver_extensions[num_driver_extensions++] = name;
883 continue;
884 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700885 // Add the VK_ANDROID_native_buffer extension to the list iff
886 // the VK_KHR_swapchain extension was requested
Jesse Hallae3b70d2016-01-17 22:05:29 -0800887 if (id == kKHR_swapchain &&
888 instance.physical_device_driver_extensions
889 [gpu_idx][kANDROID_native_buffer]) {
890 driver_extensions[num_driver_extensions++] =
891 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
892 continue;
893 }
Jesse Hallb1471272016-01-17 21:36:58 -0800894 }
Jesse Hallb1471272016-01-17 21:36:58 -0800895 bool supported = false;
896 for (const auto& layer : device->active_layers) {
897 if (layer.SupportsExtension(name))
898 supported = true;
899 }
900 if (!supported) {
901 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -0800902 "requested device extension '%s' not supported by loader, "
903 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -0800904 name);
Jesse Hallb1471272016-01-17 21:36:58 -0800905 return VK_ERROR_EXTENSION_NOT_PRESENT;
906 }
907 }
908
Jesse Hallb1471272016-01-17 21:36:58 -0800909 driver_create_info.enabledExtensionCount = num_driver_extensions;
910 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Hall04f4f472015-08-16 19:51:04 -0700911 VkDevice drv_device;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700912 VkResult result = instance.drv.dispatch.CreateDevice(
913 gpu, &driver_create_info, allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700914 if (result != VK_SUCCESS) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700915 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700916 }
917
Jesse Hall1f91d392015-12-11 16:28:44 -0800918 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700919 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800920 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
921 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
922 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500923 PFN_vkDestroyDevice destroy_device =
924 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800925 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
926 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800927 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700928 return VK_ERROR_INITIALIZATION_FAILED;
929 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700930
931 // Set dispatch table for newly created Device
932 // CreateDevice_Top will fill in the details
Jesse Hall1f91d392015-12-11 16:28:44 -0800933 drv_dispatch->vtbl = &device->dispatch;
934 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
935 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
936 "vkGetDeviceProcAddr"));
Jesse Hall1f91d392015-12-11 16:28:44 -0800937 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700938 return VK_SUCCESS;
939}
940
Jesse Hall1f91d392015-12-11 16:28:44 -0800941void DestroyInstance_Bottom(VkInstance vkinstance,
942 const VkAllocationCallbacks* allocator) {
943 Instance& instance = GetDispatchParent(vkinstance);
944
945 // These checks allow us to call DestroyInstance_Bottom from any error
946 // path in CreateInstance_Bottom, before the driver instance is fully
947 // initialized.
948 if (instance.drv.instance != VK_NULL_HANDLE &&
949 instance.drv.dispatch.DestroyInstance) {
950 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -0800951 instance.drv.instance = VK_NULL_HANDLE;
Jesse Hall1f91d392015-12-11 16:28:44 -0800952 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700953}
954
Jesse Hall1f91d392015-12-11 16:28:44 -0800955PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
956 const char* name) {
957 if (strcmp(name, "vkCreateDevice") == 0) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700958 return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom);
Michael Lentine03c64b02015-08-26 18:27:26 -0500959 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800960
961 // VK_ANDROID_native_buffer should be hidden from applications and layers.
962 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
963 PFN_vkVoidFunction pfn;
964 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
965 strcmp(name, "vkAcquireImageANDROID") == 0 ||
966 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
967 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -0500968 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800969 if ((pfn = GetLoaderBottomProcAddr(name)))
970 return pfn;
971 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -0700972}
973
Jesse Hall04f4f472015-08-16 19:51:04 -0700974// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -0800975// Loader top functions. These are called directly from the loader entry
976// points or from the application (via vkGetInstanceProcAddr) without going
977// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -0700978
Jesse Hall1f91d392015-12-11 16:28:44 -0800979VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -0800980 const char* layer_name,
981 uint32_t* properties_count,
982 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700983 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700984 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700985
Jesse Hall80523e22016-01-06 16:47:54 -0800986 const VkExtensionProperties* extensions = nullptr;
987 uint32_t num_extensions = 0;
988 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800989 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -0800990 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800991 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
992 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
993 available[num_extensions++] = VkExtensionProperties{
994 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
995 available[num_extensions++] =
996 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
997 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
998 if (g_driver_instance_extensions[kEXT_debug_report]) {
999 available[num_extensions++] =
1000 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1001 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1002 }
Jesse Hall80523e22016-01-06 16:47:54 -08001003 // TODO(jessehall): We need to also enumerate extensions supported by
1004 // implicitly-enabled layers. Currently we don't have that list of
1005 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001006 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001007 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001008
Jesse Hall80523e22016-01-06 16:47:54 -08001009 if (!properties || *properties_count > num_extensions)
1010 *properties_count = num_extensions;
1011 if (properties)
1012 std::copy(extensions, extensions + *properties_count, properties);
1013 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001014}
1015
Jesse Hall80523e22016-01-06 16:47:54 -08001016VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1017 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001018 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001019 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001020
Jesse Hall80523e22016-01-06 16:47:54 -08001021 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001022 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001023 if (!properties || *properties_count > layer_count)
1024 *properties_count = layer_count;
1025 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001026}
1027
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -07001028VKAPI_ATTR
1029VkResult EnumerateDeviceExtensionProperties_Top(
1030 VkPhysicalDevice gpu,
1031 const char* layer_name,
1032 uint32_t* properties_count,
1033 VkExtensionProperties* properties) {
1034 const VkExtensionProperties* extensions = nullptr;
1035 uint32_t num_extensions = 0;
1036
1037 ALOGV("EnumerateDeviceExtensionProperties_Top:");
1038 if (layer_name) {
1039 ALOGV(" layer %s", layer_name);
1040 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
1041 } else {
1042 ALOGV(" no layer");
1043 Instance& instance = GetDispatchParent(gpu);
1044 size_t gpu_idx = 0;
1045 while (instance.physical_devices[gpu_idx] != gpu)
1046 gpu_idx++;
1047 const DeviceExtensionSet driver_extensions =
1048 instance.physical_device_driver_extensions[gpu_idx];
1049
1050 // We only support VK_KHR_swapchain if the GPU supports
1051 // VK_ANDROID_native_buffer
1052 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1053 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
1054 if (driver_extensions[kANDROID_native_buffer]) {
1055 available[num_extensions++] = VkExtensionProperties{
1056 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
1057 }
1058
1059 // TODO(jessehall): We need to also enumerate extensions supported by
1060 // implicitly-enabled layers. Currently we don't have that list of
1061 // layers until instance creation.
1062 extensions = available;
1063 }
1064
1065 ALOGV(" num: %d, extensions: %p", num_extensions, extensions);
1066 if (!properties || *properties_count > num_extensions)
1067 *properties_count = num_extensions;
1068 if (properties)
1069 std::copy(extensions, extensions + *properties_count, properties);
1070 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
1071}
1072
Jesse Hall1f91d392015-12-11 16:28:44 -08001073VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1074 const VkAllocationCallbacks* allocator,
1075 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001076 VkResult result;
1077
1078 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001079 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001080
Jesse Hall03b6fe12015-11-24 12:44:21 -08001081 if (!allocator)
1082 allocator = &kDefaultAllocCallbacks;
1083
Jesse Hall04f4f472015-08-16 19:51:04 -07001084 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001085 create_info = &local_create_info;
1086
Jesse Hall3fbc8562015-11-29 22:10:52 -08001087 void* instance_mem = allocator->pfnAllocation(
1088 allocator->pUserData, sizeof(Instance), alignof(Instance),
1089 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001090 if (!instance_mem)
1091 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001092 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001093
Jesse Hall9a16f972015-10-28 15:59:53 -07001094 result = ActivateAllLayers(create_info, instance, instance);
1095 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001096 DestroyInstance(instance, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001097 return result;
1098 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001099
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001100 uint32_t activated_layers = 0;
1101 VkLayerInstanceCreateInfo chain_info;
1102 VkLayerInstanceLink* layer_instance_link_info = nullptr;
1103 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1104 VkInstance local_instance = nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001105
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001106 if (instance->active_layers.size() > 0) {
1107 chain_info.u.pLayerInfo = nullptr;
1108 chain_info.pNext = create_info->pNext;
1109 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1110 chain_info.function = VK_LAYER_FUNCTION_LINK;
1111 local_create_info.pNext = &chain_info;
Michael Lentine03c64b02015-08-26 18:27:26 -05001112
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001113 layer_instance_link_info = static_cast<VkLayerInstanceLink*>(alloca(
1114 sizeof(VkLayerInstanceLink) * instance->active_layers.size()));
1115 if (!layer_instance_link_info) {
1116 ALOGE("Failed to alloc Instance objects for layers");
Jesse Hallfee71432016-03-05 22:27:02 -08001117 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001118 return VK_ERROR_OUT_OF_HOST_MEMORY;
1119 }
1120
1121 /* Create instance chain of enabled layers */
1122 for (auto rit = instance->active_layers.rbegin();
1123 rit != instance->active_layers.rend(); ++rit) {
1124 LayerRef& layer = *rit;
1125 layer_instance_link_info[activated_layers].pNext =
1126 chain_info.u.pLayerInfo;
1127 layer_instance_link_info[activated_layers]
1128 .pfnNextGetInstanceProcAddr = next_gipa;
1129 chain_info.u.pLayerInfo =
1130 &layer_instance_link_info[activated_layers];
1131 next_gipa = layer.GetGetInstanceProcAddr();
1132
1133 ALOGV("Insert instance layer %s (v%u)", layer.GetName(),
1134 layer.GetSpecVersion());
1135
1136 activated_layers++;
Michael Lentine03c64b02015-08-26 18:27:26 -05001137 }
1138 }
1139
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001140 PFN_vkCreateInstance create_instance =
1141 reinterpret_cast<PFN_vkCreateInstance>(
1142 next_gipa(VK_NULL_HANDLE, "vkCreateInstance"));
1143 if (!create_instance) {
Jesse Hallfee71432016-03-05 22:27:02 -08001144 DestroyInstance(instance, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001145 return VK_ERROR_INITIALIZATION_FAILED;
1146 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001147 VkLayerInstanceCreateInfo instance_create_info;
1148
1149 instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1150 instance_create_info.function = VK_LAYER_FUNCTION_INSTANCE;
1151
1152 instance_create_info.u.instanceInfo.instance_info = instance;
1153 instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1154
1155 instance_create_info.pNext = local_create_info.pNext;
1156 local_create_info.pNext = &instance_create_info;
1157
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001158 // Force enable callback extension if required
1159 bool enable_callback = false;
1160 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1161 enable_callback =
1162 property_get_bool("debug.vulkan.enable_callback", false);
1163 if (enable_callback) {
1164 enable_callback = AddExtensionToCreateInfo(
1165 local_create_info, "VK_EXT_debug_report", instance->alloc);
1166 }
1167 }
1168
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001169 result = create_instance(&local_create_info, allocator, &local_instance);
Jesse Hallfee71432016-03-05 22:27:02 -08001170 if (enable_callback)
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001171 FreeAllocatedCreateInfo(local_create_info, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001172 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001173 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001174 return result;
1175 }
1176
1177 const InstanceDispatchTable& instance_dispatch =
1178 GetDispatchTable(local_instance);
1179 if (!LoadInstanceDispatchTable(
1180 local_instance, next_gipa,
1181 const_cast<InstanceDispatchTable&>(instance_dispatch))) {
1182 ALOGV("Failed to initialize instance dispatch table");
1183 PFN_vkDestroyInstance destroy_instance =
1184 reinterpret_cast<PFN_vkDestroyInstance>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001185 next_gipa(local_instance, "vkDestroyInstance"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001186 if (!destroy_instance) {
1187 ALOGD("Loader unable to find DestroyInstance");
1188 return VK_ERROR_INITIALIZATION_FAILED;
1189 }
1190 destroy_instance(local_instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001191 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001192 return VK_ERROR_INITIALIZATION_FAILED;
1193 }
1194 *instance_out = local_instance;
Michael Lentine03c64b02015-08-26 18:27:26 -05001195
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001196 if (enable_callback) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001197 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1198 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1199 .flags =
Jesse Halle2948d82016-02-25 04:19:32 -08001200 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
Jesse Hall715b86a2016-01-16 16:34:29 -08001201 .pfnCallback = LogDebugMessageCallback,
1202 };
1203 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1204 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1205 GetInstanceProcAddr_Top(instance->handle,
1206 "vkCreateDebugReportCallbackEXT"));
1207 create_debug_report_callback(instance->handle, &callback_create_info,
1208 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001209 }
1210
Jesse Hall04f4f472015-08-16 19:51:04 -07001211 return result;
1212}
1213
Jesse Hall1f91d392015-12-11 16:28:44 -08001214PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1215 const char* name) {
1216 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1217 if (!vkinstance)
1218 return GetLoaderGlobalProcAddr(name);
1219
1220 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1221 PFN_vkVoidFunction pfn;
1222 // Always go through the loader-top function if there is one.
1223 if ((pfn = GetLoaderTopProcAddr(name)))
1224 return pfn;
1225 // Otherwise, look up the handler in the instance dispatch table
1226 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1227 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001228 // Anything not handled already must be a device-dispatched function
1229 // without a loader-top. We must return a function that will dispatch based
1230 // on the dispatchable object parameter -- which is exactly what the
1231 // exported functions do. So just return them here.
1232 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001233}
1234
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001235void DestroyInstance_Top(VkInstance vkinstance,
Jesse Hall1f91d392015-12-11 16:28:44 -08001236 const VkAllocationCallbacks* allocator) {
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001237 if (!vkinstance)
Jesse Hall1f91d392015-12-11 16:28:44 -08001238 return;
Jesse Hallfee71432016-03-05 22:27:02 -08001239 if (!allocator)
1240 allocator = &kDefaultAllocCallbacks;
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001241 GetDispatchTable(vkinstance).DestroyInstance(vkinstance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001242 DestroyInstance(&(GetDispatchParent(vkinstance)), allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -08001243}
1244
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001245VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -07001246VkResult EnumerateDeviceLayerProperties_Top(VkPhysicalDevice /*pdev*/,
1247 uint32_t* properties_count,
1248 VkLayerProperties* properties) {
1249 uint32_t layer_count =
1250 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
1251 if (!properties || *properties_count > layer_count)
1252 *properties_count = layer_count;
1253 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
1254}
1255
1256VKAPI_ATTR
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001257VkResult CreateDevice_Top(VkPhysicalDevice gpu,
1258 const VkDeviceCreateInfo* create_info,
1259 const VkAllocationCallbacks* allocator,
1260 VkDevice* device_out) {
1261 Instance& instance = GetDispatchParent(gpu);
1262 VkResult result;
1263
1264 // FIXME(jessehall): We don't have good conventions or infrastructure yet to
1265 // do better than just using the instance allocator and scope for
1266 // everything. See b/26732122.
1267 if (true /*!allocator*/)
1268 allocator = instance.alloc;
1269
1270 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
1271 alignof(Device),
1272 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1273 if (!mem)
1274 return VK_ERROR_OUT_OF_HOST_MEMORY;
1275 Device* device = new (mem) Device(&instance);
1276
1277 result = ActivateAllLayers(create_info, &instance, device);
1278 if (result != VK_SUCCESS) {
1279 DestroyDevice(device);
1280 return result;
1281 }
1282
1283 size_t gpu_idx = 0;
1284 while (instance.physical_devices[gpu_idx] != gpu)
1285 gpu_idx++;
1286
1287 uint32_t activated_layers = 0;
1288 VkLayerDeviceCreateInfo chain_info;
1289 VkLayerDeviceLink* layer_device_link_info = nullptr;
1290 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1291 PFN_vkGetDeviceProcAddr next_gdpa = GetDeviceProcAddr_Bottom;
1292 VkDeviceCreateInfo local_create_info = *create_info;
1293 VkDevice local_device = nullptr;
1294
1295 if (device->active_layers.size() > 0) {
1296 chain_info.u.pLayerInfo = nullptr;
1297 chain_info.pNext = local_create_info.pNext;
1298 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1299 chain_info.function = VK_LAYER_FUNCTION_LINK;
1300 local_create_info.pNext = &chain_info;
1301
1302 layer_device_link_info = static_cast<VkLayerDeviceLink*>(
1303 alloca(sizeof(VkLayerDeviceLink) * device->active_layers.size()));
1304 if (!layer_device_link_info) {
1305 ALOGE("Failed to alloc Device objects for layers");
1306 DestroyDevice(device);
1307 return VK_ERROR_OUT_OF_HOST_MEMORY;
1308 }
1309
1310 /* Create device chain of enabled layers */
1311 for (auto rit = device->active_layers.rbegin();
1312 rit != device->active_layers.rend(); ++rit) {
1313 LayerRef& layer = *rit;
1314 layer_device_link_info[activated_layers].pNext =
1315 chain_info.u.pLayerInfo;
1316 layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr =
1317 next_gdpa;
1318 layer_device_link_info[activated_layers]
1319 .pfnNextGetInstanceProcAddr = next_gipa;
1320 chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
1321
1322 next_gipa = layer.GetGetInstanceProcAddr();
1323 next_gdpa = layer.GetGetDeviceProcAddr();
1324
1325 ALOGV("Insert device layer %s (v%u)", layer.GetName(),
1326 layer.GetSpecVersion());
1327
1328 activated_layers++;
1329 }
1330 }
1331
1332 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001333 next_gipa(instance.handle, "vkCreateDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001334 if (!create_device) {
1335 ALOGE("Unable to find vkCreateDevice for driver");
1336 DestroyDevice(device);
1337 return VK_ERROR_INITIALIZATION_FAILED;
1338 }
1339
1340 VkLayerDeviceCreateInfo device_create_info;
1341
1342 device_create_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1343 device_create_info.function = VK_LAYER_FUNCTION_DEVICE;
1344
1345 device_create_info.u.deviceInfo.device_info = device;
1346 device_create_info.u.deviceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1347
1348 device_create_info.pNext = local_create_info.pNext;
1349 local_create_info.pNext = &device_create_info;
1350
1351 result = create_device(gpu, &local_create_info, allocator, &local_device);
1352
1353 if (result != VK_SUCCESS) {
1354 DestroyDevice(device);
1355 return result;
1356 }
1357
1358 // Set dispatch table for newly created Device
1359 hwvulkan_dispatch_t* vulkan_dispatch =
1360 reinterpret_cast<hwvulkan_dispatch_t*>(local_device);
1361 vulkan_dispatch->vtbl = &device->dispatch;
1362
1363 const DeviceDispatchTable& device_dispatch = GetDispatchTable(local_device);
1364 if (!LoadDeviceDispatchTable(
1365 local_device, next_gdpa,
1366 const_cast<DeviceDispatchTable&>(device_dispatch))) {
1367 ALOGV("Failed to initialize device dispatch table");
1368 PFN_vkDestroyDevice destroy_device =
1369 reinterpret_cast<PFN_vkDestroyDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001370 next_gipa(instance.handle, "vkDestroyDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001371 ALOG_ASSERT(destroy_device != nullptr,
1372 "Loader unable to find DestroyDevice");
1373 destroy_device(local_device, allocator);
1374 return VK_ERROR_INITIALIZATION_FAILED;
1375 }
1376 *device_out = local_device;
1377
1378 return VK_SUCCESS;
1379}
1380
Jesse Hall1f91d392015-12-11 16:28:44 -08001381PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1382 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001383 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001384 return nullptr;
1385 if ((pfn = GetLoaderTopProcAddr(name)))
1386 return pfn;
1387 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001388}
1389
Jesse Hall1f91d392015-12-11 16:28:44 -08001390void GetDeviceQueue_Top(VkDevice vkdevice,
1391 uint32_t family,
1392 uint32_t index,
1393 VkQueue* queue_out) {
1394 const auto& table = GetDispatchTable(vkdevice);
1395 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1396 hwvulkan_dispatch_t* queue_dispatch =
1397 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1398 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1399 queue_dispatch->vtbl != &table)
1400 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1401 queue_dispatch->magic);
1402 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001403}
1404
Jesse Hall1f91d392015-12-11 16:28:44 -08001405VkResult AllocateCommandBuffers_Top(
1406 VkDevice vkdevice,
1407 const VkCommandBufferAllocateInfo* alloc_info,
1408 VkCommandBuffer* cmdbufs) {
1409 const auto& table = GetDispatchTable(vkdevice);
1410 VkResult result =
1411 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001412 if (result != VK_SUCCESS)
1413 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001414 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001415 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001416 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001417 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001418 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001419 cmdbuf_dispatch->magic);
1420 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001421 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001422 return VK_SUCCESS;
1423}
1424
Jesse Hall1f91d392015-12-11 16:28:44 -08001425void DestroyDevice_Top(VkDevice vkdevice,
1426 const VkAllocationCallbacks* /*allocator*/) {
1427 if (!vkdevice)
1428 return;
1429 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001430 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1431 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001432}
1433
Jesse Hall1f91d392015-12-11 16:28:44 -08001434// -----------------------------------------------------------------------------
1435
1436const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1437 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001438}
1439
Jesse Hall1f91d392015-12-11 16:28:44 -08001440const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1441 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001442}
1443
Jesse Hall715b86a2016-01-16 16:34:29 -08001444VkInstance GetDriverInstance(VkInstance instance) {
1445 return GetDispatchParent(instance).drv.instance;
1446}
1447
1448const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1449 return GetDispatchParent(instance).drv.dispatch;
1450}
1451
Jesse Hall1f91d392015-12-11 16:28:44 -08001452const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1453 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001454}
1455
Jesse Hall1f91d392015-12-11 16:28:44 -08001456const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1457 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001458}
1459
Jesse Hall715b86a2016-01-16 16:34:29 -08001460DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1461 return GetDispatchParent(instance).debug_report_callbacks;
1462}
1463
Jesse Hall04f4f472015-08-16 19:51:04 -07001464} // namespace vulkan