blob: eba58c61b004a205fadd8c26bc226e8783defe10 [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;
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -0600268 VkPhysicalDevice physical_devices_top[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800269 VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
Jesse Hallb1471272016-01-17 21:36:58 -0800270 DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
Jesse Hall1f91d392015-12-11 16:28:44 -0800271
Jesse Hall80523e22016-01-06 16:47:54 -0800272 Vector<LayerRef> active_layers;
Jesse Hall715b86a2016-01-16 16:34:29 -0800273 VkDebugReportCallbackEXT message;
274 DebugReportCallbackList debug_report_callbacks;
Jesse Hall1f91d392015-12-11 16:28:44 -0800275
276 struct {
277 VkInstance instance;
278 DriverDispatchTable dispatch;
279 uint32_t num_physical_devices;
280 } drv; // may eventually be an array
281};
282
283struct Device {
284 Device(Instance* instance_)
285 : instance(instance_),
Jesse Hall80523e22016-01-06 16:47:54 -0800286 active_layers(CallbackAllocator<LayerRef>(instance->alloc)) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800287 memset(&dispatch, 0, sizeof(dispatch));
288 }
289 DeviceDispatchTable dispatch;
290 Instance* instance;
291 PFN_vkGetDeviceProcAddr get_device_proc_addr;
Jesse Hall80523e22016-01-06 16:47:54 -0800292 Vector<LayerRef> active_layers;
Jesse Hall1f91d392015-12-11 16:28:44 -0800293};
294
295template <typename THandle>
296struct HandleTraits {};
297template <>
298struct HandleTraits<VkInstance> {
299 typedef Instance LoaderObjectType;
300};
301template <>
302struct HandleTraits<VkPhysicalDevice> {
303 typedef Instance LoaderObjectType;
304};
305template <>
306struct HandleTraits<VkDevice> {
307 typedef Device LoaderObjectType;
308};
309template <>
310struct HandleTraits<VkQueue> {
311 typedef Device LoaderObjectType;
312};
313template <>
314struct HandleTraits<VkCommandBuffer> {
315 typedef Device LoaderObjectType;
316};
317
318template <typename THandle>
319typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent(
320 THandle handle) {
321 // TODO(jessehall): Make Instance and Device POD types (by removing the
322 // non-default constructors), so that offsetof is actually legal to use.
323 // The specific case we're using here is safe in gcc/clang (and probably
324 // most other C++ compilers), but isn't guaranteed by C++.
325 typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType;
326#pragma clang diagnostic push
327#pragma clang diagnostic ignored "-Winvalid-offsetof"
328 const size_t kDispatchOffset = offsetof(ObjectType, dispatch);
329#pragma clang diagnostic pop
330
331 const auto& dispatch = GetDispatchTable(handle);
332 uintptr_t dispatch_addr = reinterpret_cast<uintptr_t>(&dispatch);
333 uintptr_t object_addr = dispatch_addr - kDispatchOffset;
334 return *reinterpret_cast<ObjectType*>(object_addr);
335}
336
337// -----------------------------------------------------------------------------
338
Jesse Hall04f4f472015-08-16 19:51:04 -0700339void DestroyDevice(Device* device) {
Jesse Hall3fbc8562015-11-29 22:10:52 -0800340 const VkAllocationCallbacks* alloc = device->instance->alloc;
Jesse Hall04f4f472015-08-16 19:51:04 -0700341 device->~Device();
342 alloc->pfnFree(alloc->pUserData, device);
343}
344
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500345template <class TObject>
Jesse Hallaa410942016-01-17 13:07:10 -0800346LayerRef GetLayerRef(const char* name);
347template <>
348LayerRef GetLayerRef<Instance>(const char* name) {
349 return GetInstanceLayerRef(name);
350}
351template <>
352LayerRef GetLayerRef<Device>(const char* name) {
353 return GetDeviceLayerRef(name);
354}
355
356template <class TObject>
Jesse Hall80523e22016-01-06 16:47:54 -0800357bool ActivateLayer(TObject* object, const char* name) {
Jesse Hallaa410942016-01-17 13:07:10 -0800358 LayerRef layer(GetLayerRef<TObject>(name));
Jesse Hall80523e22016-01-06 16:47:54 -0800359 if (!layer)
360 return false;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500361 if (std::find(object->active_layers.begin(), object->active_layers.end(),
Jesse Hall26cecff2016-01-21 19:52:25 -0800362 layer) == object->active_layers.end()) {
363 try {
364 object->active_layers.push_back(std::move(layer));
365 } catch (std::bad_alloc&) {
366 // TODO(jessehall): We should fail with VK_ERROR_OUT_OF_MEMORY
367 // if we can't enable a requested layer. Callers currently ignore
368 // ActivateLayer's return value.
369 ALOGW("failed to activate layer '%s': out of memory", name);
370 return false;
371 }
372 }
Jesse Hall80523e22016-01-06 16:47:54 -0800373 ALOGV("activated layer '%s'", name);
374 return true;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500375}
376
Michael Lentine9da191b2015-10-13 11:08:45 -0500377struct InstanceNamesPair {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500378 Instance* instance;
Michael Lentine9da191b2015-10-13 11:08:45 -0500379 Vector<String>* layer_names;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500380};
381
Michael Lentine9da191b2015-10-13 11:08:45 -0500382void SetLayerNamesFromProperty(const char* name,
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500383 const char* value,
384 void* data) {
Jesse Hall26cecff2016-01-21 19:52:25 -0800385 try {
386 const char prefix[] = "debug.vulkan.layer.";
387 const size_t prefixlen = sizeof(prefix) - 1;
388 if (value[0] == '\0' || strncmp(name, prefix, prefixlen) != 0)
389 return;
390 const char* number_str = name + prefixlen;
391 long layer_number = strtol(number_str, nullptr, 10);
392 if (layer_number <= 0 || layer_number == LONG_MAX) {
393 ALOGW("Cannot use a layer at number %ld from string %s",
394 layer_number, number_str);
395 return;
396 }
397 auto instance_names_pair = static_cast<InstanceNamesPair*>(data);
398 Vector<String>* layer_names = instance_names_pair->layer_names;
399 Instance* instance = instance_names_pair->instance;
400 size_t layer_size = static_cast<size_t>(layer_number);
401 if (layer_size > layer_names->size()) {
402 layer_names->resize(
403 layer_size, String(CallbackAllocator<char>(instance->alloc)));
404 }
405 (*layer_names)[layer_size - 1] = value;
406 } catch (std::bad_alloc&) {
407 ALOGW("failed to handle property '%s'='%s': out of memory", name,
408 value);
Michael Lentine9da191b2015-10-13 11:08:45 -0500409 return;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500410 }
411}
412
413template <class TInfo, class TObject>
Jesse Hall1f91d392015-12-11 16:28:44 -0800414VkResult ActivateAllLayers(TInfo create_info,
415 Instance* instance,
416 TObject* object) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500417 ALOG_ASSERT(create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ||
418 create_info->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
419 "Cannot activate layers for unknown object %p", object);
420 CallbackAllocator<char> string_allocator(instance->alloc);
421 // Load system layers
Jesse Hall21597662015-12-18 13:48:24 -0800422 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500423 char layer_prop[PROPERTY_VALUE_MAX];
424 property_get("debug.vulkan.layers", layer_prop, "");
Jesse Hall26cecff2016-01-21 19:52:25 -0800425 char* strtok_state;
426 char* layer_name = nullptr;
427 while ((layer_name = strtok_r(layer_name ? nullptr : layer_prop, ":",
428 &strtok_state))) {
429 ActivateLayer(object, layer_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500430 }
Michael Lentine9da191b2015-10-13 11:08:45 -0500431 Vector<String> layer_names(CallbackAllocator<String>(instance->alloc));
432 InstanceNamesPair instance_names_pair = {.instance = instance,
433 .layer_names = &layer_names};
434 property_list(SetLayerNamesFromProperty,
435 static_cast<void*>(&instance_names_pair));
436 for (auto layer_name_element : layer_names) {
Jesse Hall80523e22016-01-06 16:47:54 -0800437 ActivateLayer(object, layer_name_element.c_str());
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500438 }
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500439 }
440 // Load app layers
Jesse Hall3dd678a2016-01-08 21:52:01 -0800441 for (uint32_t i = 0; i < create_info->enabledLayerCount; ++i) {
Jesse Hall80523e22016-01-06 16:47:54 -0800442 if (!ActivateLayer(object, create_info->ppEnabledLayerNames[i])) {
Jesse Hall9a16f972015-10-28 15:59:53 -0700443 ALOGE("requested %s layer '%s' not present",
Jesse Hall1f91d392015-12-11 16:28:44 -0800444 create_info->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
445 ? "instance"
446 : "device",
Jesse Hall80523e22016-01-06 16:47:54 -0800447 create_info->ppEnabledLayerNames[i]);
Jesse Hall9a16f972015-10-28 15:59:53 -0700448 return VK_ERROR_LAYER_NOT_PRESENT;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500449 }
450 }
Jesse Hall9a16f972015-10-28 15:59:53 -0700451 return VK_SUCCESS;
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500452}
453
Michael Lentine57036832016-03-04 11:03:35 -0600454template <class TCreateInfo, class TObject>
455bool AddLayersToCreateInfo(TCreateInfo& local_create_info,
456 const TObject& object,
457 const VkAllocationCallbacks* alloc,
458 bool& allocatedMemory) {
459 // This should never happen and means there is a likely a bug in layer
460 // tracking
461 if (object->active_layers.size() < local_create_info.enabledLayerCount) {
462 ALOGE("Total number of layers is less than those enabled by the app!");
463 return false;
464 }
465 // Check if the total number of layers enabled is greater than those
466 // enabled by the application. If it is then we have system enabled
467 // layers which need to be added to the list of layers passed in through
468 // create.
469 if (object->active_layers.size() > local_create_info.enabledLayerCount) {
470 void* mem = alloc->pfnAllocation(
471 alloc->pUserData, object->active_layers.size() * sizeof(char*),
472 alignof(char*), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
473 if (mem) {
474 local_create_info.enabledLayerCount = 0;
475 const char** names = static_cast<const char**>(mem);
476 for (const auto& layer : object->active_layers) {
477 const char* name = layer.GetName();
478 names[local_create_info.enabledLayerCount++] = name;
479 }
480 local_create_info.ppEnabledLayerNames = names;
481 } else {
482 ALOGE("System layers cannot be enabled: memory allocation failed");
483 return false;
484 }
485 allocatedMemory = true;
486 } else {
487 allocatedMemory = false;
488 }
489 return true;
490}
491
492template <class T>
493void FreeAllocatedLayerCreateInfo(T& local_create_info,
494 const VkAllocationCallbacks* alloc) {
495 alloc->pfnFree(alloc->pUserData,
496 const_cast<char**>(local_create_info.ppEnabledLayerNames));
497}
498
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500499template <class TCreateInfo>
500bool AddExtensionToCreateInfo(TCreateInfo& local_create_info,
501 const char* extension_name,
Jesse Hall3fbc8562015-11-29 22:10:52 -0800502 const VkAllocationCallbacks* alloc) {
Jesse Hall3dd678a2016-01-08 21:52:01 -0800503 uint32_t extension_count = local_create_info.enabledExtensionCount;
504 local_create_info.enabledExtensionCount++;
Jesse Hall3fbc8562015-11-29 22:10:52 -0800505 void* mem = alloc->pfnAllocation(
Jesse Hall03b6fe12015-11-24 12:44:21 -0800506 alloc->pUserData,
Jesse Hall3dd678a2016-01-08 21:52:01 -0800507 local_create_info.enabledExtensionCount * sizeof(char*), alignof(char*),
Michael Lentine57036832016-03-04 11:03:35 -0600508 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500509 if (mem) {
510 const char** enabled_extensions = static_cast<const char**>(mem);
511 for (uint32_t i = 0; i < extension_count; ++i) {
512 enabled_extensions[i] =
513 local_create_info.ppEnabledExtensionNames[i];
514 }
515 enabled_extensions[extension_count] = extension_name;
516 local_create_info.ppEnabledExtensionNames = enabled_extensions;
517 } else {
Michael Lentine57036832016-03-04 11:03:35 -0600518 ALOGE("%s extension cannot be enabled: memory allocation failed",
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500519 extension_name);
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500520 return false;
521 }
522 return true;
523}
524
525template <class T>
Michael Lentine57036832016-03-04 11:03:35 -0600526void FreeAllocatedExtensionCreateInfo(T& local_create_info,
527 const VkAllocationCallbacks* alloc) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500528 alloc->pfnFree(
529 alloc->pUserData,
530 const_cast<char**>(local_create_info.ppEnabledExtensionNames));
531}
532
Jesse Halle1b12782015-11-30 11:27:32 -0800533VKAPI_ATTR
Jesse Hall715b86a2016-01-16 16:34:29 -0800534VkBool32 LogDebugMessageCallback(VkDebugReportFlagsEXT flags,
535 VkDebugReportObjectTypeEXT /*objectType*/,
536 uint64_t /*object*/,
Michael Lentineeb970862015-10-15 12:42:22 -0500537 size_t /*location*/,
538 int32_t message_code,
539 const char* layer_prefix,
540 const char* message,
541 void* /*user_data*/) {
Jesse Hall715b86a2016-01-16 16:34:29 -0800542 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500543 ALOGE("[%s] Code %d : %s", layer_prefix, message_code, message);
Jesse Halle2948d82016-02-25 04:19:32 -0800544 } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
Michael Lentine9dbe67f2015-09-16 15:53:50 -0500545 ALOGW("[%s] Code %d : %s", layer_prefix, message_code, message);
546 }
Michael Lentineeb970862015-10-15 12:42:22 -0500547 return false;
Michael Lentine03c64b02015-08-26 18:27:26 -0500548}
549
Jesse Hall06193802015-12-03 16:12:51 -0800550VkResult Noop() {
Michael Lentine03c64b02015-08-26 18:27:26 -0500551 return VK_SUCCESS;
552}
553
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700554/*
555 * This function will return the pNext pointer of any
556 * CreateInfo extensions that are not loader extensions.
557 * This is used to skip past the loader extensions prepended
558 * to the list during CreateInstance and CreateDevice.
559 */
560void* StripCreateExtensions(const void* pNext) {
561 VkLayerInstanceCreateInfo* create_info =
562 const_cast<VkLayerInstanceCreateInfo*>(
563 static_cast<const VkLayerInstanceCreateInfo*>(pNext));
564
565 while (
566 create_info &&
567 (create_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
568 create_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)) {
569 create_info = const_cast<VkLayerInstanceCreateInfo*>(
570 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
571 }
572
573 return create_info;
574}
575
Jesse Hallfee71432016-03-05 22:27:02 -0800576// Clean up and deallocate an Instance; called from both the failure paths in
577// CreateInstance_Top as well as from DestroyInstance_Top. This function does
578// not call down the dispatch chain; that should be done before calling this
579// function, iff the lower vkCreateInstance call has been made and returned
580// successfully.
581void DestroyInstance(Instance* instance,
582 const VkAllocationCallbacks* allocator) {
583 if (instance->message) {
584 PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report_callback;
585 destroy_debug_report_callback =
586 reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
587 GetInstanceProcAddr_Top(instance->handle,
588 "vkDestroyDebugReportCallbackEXT"));
589 destroy_debug_report_callback(instance->handle, instance->message,
590 allocator);
591 }
592 instance->~Instance();
593 allocator->pfnFree(allocator->pUserData, instance);
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -0700594}
595
Jesse Hall1f91d392015-12-11 16:28:44 -0800596} // anonymous namespace
597
598namespace vulkan {
Michael Lentinecd6cabf2015-09-14 17:32:59 -0500599
Jesse Hall04f4f472015-08-16 19:51:04 -0700600// -----------------------------------------------------------------------------
601// "Bottom" functions. These are called at the end of the instance dispatch
602// chain.
603
Jesse Hall1f91d392015-12-11 16:28:44 -0800604VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info,
605 const VkAllocationCallbacks* allocator,
606 VkInstance* vkinstance) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700607 VkResult result;
608
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700609 VkLayerInstanceCreateInfo* chain_info =
610 const_cast<VkLayerInstanceCreateInfo*>(
611 static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext));
612 while (
613 chain_info &&
614 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO &&
615 chain_info->function == VK_LAYER_FUNCTION_INSTANCE)) {
616 chain_info = const_cast<VkLayerInstanceCreateInfo*>(
617 static_cast<const VkLayerInstanceCreateInfo*>(chain_info->pNext));
618 }
619 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
620
621 Instance& instance = GetDispatchParent(
622 static_cast<VkInstance>(chain_info->u.instanceInfo.instance_info));
623
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800624 // Check that all enabled extensions are supported
625 InstanceExtensionSet enabled_extensions;
626 uint32_t num_driver_extensions = 0;
627 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
628 const char* name = create_info->ppEnabledExtensionNames[i];
629 InstanceExtension id = InstanceExtensionFromName(name);
630 if (id != kInstanceExtensionCount) {
631 if (g_driver_instance_extensions[id]) {
632 num_driver_extensions++;
633 enabled_extensions.set(id);
634 continue;
635 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700636 if (id == kKHR_surface || id == kKHR_android_surface) {
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800637 enabled_extensions.set(id);
638 continue;
639 }
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700640 // The loader natively supports debug report.
641 if (id == kEXT_debug_report) {
642 continue;
643 }
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800644 }
645 bool supported = false;
646 for (const auto& layer : instance.active_layers) {
647 if (layer.SupportsExtension(name))
648 supported = true;
649 }
650 if (!supported) {
651 ALOGE(
652 "requested instance extension '%s' not supported by "
653 "loader, driver, or any active layers",
654 name);
655 DestroyInstance_Bottom(instance.handle, allocator);
656 return VK_ERROR_EXTENSION_NOT_PRESENT;
657 }
658 }
659
Jesse Halla7ac76d2016-01-08 22:29:42 -0800660 VkInstanceCreateInfo driver_create_info = *create_info;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700661 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
Jesse Halla7ac76d2016-01-08 22:29:42 -0800662 driver_create_info.enabledLayerCount = 0;
663 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Halla7ac76d2016-01-08 22:29:42 -0800664 driver_create_info.enabledExtensionCount = 0;
665 driver_create_info.ppEnabledExtensionNames = nullptr;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800666 if (num_driver_extensions > 0) {
667 const char** names = static_cast<const char**>(
668 alloca(num_driver_extensions * sizeof(char*)));
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800669 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
Jesse Hallae3b70d2016-01-17 22:05:29 -0800670 const char* name = create_info->ppEnabledExtensionNames[i];
671 InstanceExtension id = InstanceExtensionFromName(name);
672 if (id != kInstanceExtensionCount) {
673 if (g_driver_instance_extensions[id]) {
674 names[driver_create_info.enabledExtensionCount++] = name;
Jesse Hallae3b70d2016-01-17 22:05:29 -0800675 continue;
676 }
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800677 }
678 }
679 driver_create_info.ppEnabledExtensionNames = names;
Jesse Hall4b62e4f2016-01-21 09:49:49 -0800680 ALOG_ASSERT(
681 driver_create_info.enabledExtensionCount == num_driver_extensions,
682 "counted enabled driver instance extensions twice and got "
683 "different answers!");
Jesse Hall6bd5dfa2016-01-16 17:13:30 -0800684 }
Jesse Halla7ac76d2016-01-08 22:29:42 -0800685
686 result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc,
Jesse Hall1f91d392015-12-11 16:28:44 -0800687 &instance.drv.instance);
Jesse Hall04f4f472015-08-16 19:51:04 -0700688 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800689 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700690 return result;
691 }
692
Jesse Hall1f91d392015-12-11 16:28:44 -0800693 hwvulkan_dispatch_t* drv_dispatch =
694 reinterpret_cast<hwvulkan_dispatch_t*>(instance.drv.instance);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700695 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700696 ALOGE("invalid VkInstance dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800697 drv_dispatch->magic);
698 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700699 return VK_ERROR_INITIALIZATION_FAILED;
700 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700701 // Skip setting drv_dispatch->vtbl, since we never call through it;
702 // we go through instance.drv.dispatch instead.
Jesse Hall04f4f472015-08-16 19:51:04 -0700703
Courtney Goeltzenleuchteraa6c8722016-01-29 08:57:16 -0700704 if (!LoadDriverDispatchTable(instance.drv.instance,
705 g_hwdevice->GetInstanceProcAddr,
706 enabled_extensions, instance.drv.dispatch)) {
707 DestroyInstance_Bottom(instance.handle, allocator);
708 return VK_ERROR_INITIALIZATION_FAILED;
709 }
710
Jesse Hall04f4f472015-08-16 19:51:04 -0700711 uint32_t num_physical_devices = 0;
Jesse Hall1f91d392015-12-11 16:28:44 -0800712 result = instance.drv.dispatch.EnumeratePhysicalDevices(
713 instance.drv.instance, &num_physical_devices, nullptr);
Jesse Hall04f4f472015-08-16 19:51:04 -0700714 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800715 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700716 return VK_ERROR_INITIALIZATION_FAILED;
717 }
718 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
Jesse Hall1f91d392015-12-11 16:28:44 -0800719 result = instance.drv.dispatch.EnumeratePhysicalDevices(
720 instance.drv.instance, &num_physical_devices,
721 instance.physical_devices);
Jesse Hall04f4f472015-08-16 19:51:04 -0700722 if (result != VK_SUCCESS) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800723 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700724 return VK_ERROR_INITIALIZATION_FAILED;
725 }
Jesse Hallb1471272016-01-17 21:36:58 -0800726
727 Vector<VkExtensionProperties> extensions(
728 Vector<VkExtensionProperties>::allocator_type(instance.alloc));
Jesse Hall04f4f472015-08-16 19:51:04 -0700729 for (uint32_t i = 0; i < num_physical_devices; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800730 hwvulkan_dispatch_t* pdev_dispatch =
731 reinterpret_cast<hwvulkan_dispatch_t*>(
732 instance.physical_devices[i]);
733 if (pdev_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
Jesse Hall04f4f472015-08-16 19:51:04 -0700734 ALOGE("invalid VkPhysicalDevice dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -0800735 pdev_dispatch->magic);
736 DestroyInstance_Bottom(instance.handle, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700737 return VK_ERROR_INITIALIZATION_FAILED;
738 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800739 pdev_dispatch->vtbl = instance.dispatch_ptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800740
741 uint32_t count;
742 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
743 instance.physical_devices[i], nullptr, &count, nullptr)) !=
744 VK_SUCCESS) {
745 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
746 result);
747 continue;
748 }
Jesse Hall26cecff2016-01-21 19:52:25 -0800749 try {
750 extensions.resize(count);
751 } catch (std::bad_alloc&) {
752 ALOGE("instance creation failed: out of memory");
753 DestroyInstance_Bottom(instance.handle, allocator);
754 return VK_ERROR_OUT_OF_HOST_MEMORY;
755 }
Jesse Hallb1471272016-01-17 21:36:58 -0800756 if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties(
757 instance.physical_devices[i], nullptr, &count,
758 extensions.data())) != VK_SUCCESS) {
759 ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i,
760 result);
761 continue;
762 }
763 ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i);
764 for (const auto& extension : extensions) {
765 ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion);
766 DeviceExtension id =
767 DeviceExtensionFromName(extension.extensionName);
768 if (id == kDeviceExtensionCount) {
769 ALOGW("driver gpu[%u] extension '%s' unknown to loader", i,
770 extension.extensionName);
771 } else {
772 instance.physical_device_driver_extensions[i].set(id);
773 }
774 }
775 // Ignore driver attempts to support loader extensions
776 instance.physical_device_driver_extensions[i].reset(kKHR_swapchain);
Jesse Hall04f4f472015-08-16 19:51:04 -0700777 }
Jesse Hall1f91d392015-12-11 16:28:44 -0800778 instance.drv.num_physical_devices = num_physical_devices;
Jesse Hall1f91d392015-12-11 16:28:44 -0800779 instance.num_physical_devices = instance.drv.num_physical_devices;
Jesse Hallb1471272016-01-17 21:36:58 -0800780
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700781 *vkinstance = instance.handle;
782
Jesse Hall04f4f472015-08-16 19:51:04 -0700783 return VK_SUCCESS;
784}
785
Jesse Hall1f91d392015-12-11 16:28:44 -0800786PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name) {
787 PFN_vkVoidFunction pfn;
788 if ((pfn = GetLoaderBottomProcAddr(name)))
789 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -0800790 return nullptr;
791}
792
793VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
794 uint32_t* pdev_count,
795 VkPhysicalDevice* pdevs) {
796 Instance& instance = GetDispatchParent(vkinstance);
797 uint32_t count = instance.num_physical_devices;
Jesse Hall04f4f472015-08-16 19:51:04 -0700798 if (pdevs) {
799 count = std::min(count, *pdev_count);
Jesse Hall1f91d392015-12-11 16:28:44 -0800800 std::copy(instance.physical_devices, instance.physical_devices + count,
801 pdevs);
Jesse Hall04f4f472015-08-16 19:51:04 -0700802 }
803 *pdev_count = count;
804 return VK_SUCCESS;
805}
806
Jesse Hall1f91d392015-12-11 16:28:44 -0800807void GetPhysicalDeviceProperties_Bottom(
808 VkPhysicalDevice pdev,
809 VkPhysicalDeviceProperties* properties) {
810 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
811 pdev, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700812}
813
Jesse Hall1f91d392015-12-11 16:28:44 -0800814void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
815 VkPhysicalDeviceFeatures* features) {
816 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
817 features);
818}
819
820void GetPhysicalDeviceMemoryProperties_Bottom(
821 VkPhysicalDevice pdev,
822 VkPhysicalDeviceMemoryProperties* properties) {
823 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
824 pdev, properties);
825}
826
827void GetPhysicalDeviceQueueFamilyProperties_Bottom(
828 VkPhysicalDevice pdev,
829 uint32_t* pCount,
830 VkQueueFamilyProperties* properties) {
831 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
832 pdev, pCount, properties);
833}
834
835void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
836 VkFormat format,
837 VkFormatProperties* properties) {
838 GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
Jesse Hall04f4f472015-08-16 19:51:04 -0700839 pdev, format, properties);
840}
841
Jesse Hall1f91d392015-12-11 16:28:44 -0800842VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700843 VkPhysicalDevice pdev,
844 VkFormat format,
845 VkImageType type,
846 VkImageTiling tiling,
847 VkImageUsageFlags usage,
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700848 VkImageCreateFlags flags,
Jesse Hall04f4f472015-08-16 19:51:04 -0700849 VkImageFormatProperties* properties) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800850 return GetDispatchParent(pdev)
851 .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
Jesse Halla9e57032015-11-30 01:03:10 -0800852 pdev, format, type, tiling, usage, flags, properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700853}
854
Jesse Hall1f91d392015-12-11 16:28:44 -0800855void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
Jesse Hall04f4f472015-08-16 19:51:04 -0700856 VkPhysicalDevice pdev,
Jesse Hall1f91d392015-12-11 16:28:44 -0800857 VkFormat format,
858 VkImageType type,
859 VkSampleCountFlagBits samples,
860 VkImageUsageFlags usage,
861 VkImageTiling tiling,
862 uint32_t* properties_count,
863 VkSparseImageFormatProperties* properties) {
864 GetDispatchParent(pdev)
865 .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
866 pdev, format, type, samples, usage, tiling, properties_count,
867 properties);
Jesse Hall04f4f472015-08-16 19:51:04 -0700868}
869
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700870// This is a no-op, the Top function returns the aggregate layer property
871// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800872VKAPI_ATTR
Jesse Hall1f91d392015-12-11 16:28:44 -0800873VkResult EnumerateDeviceExtensionProperties_Bottom(
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -0700874 VkPhysicalDevice /*pdev*/,
875 const char* /*layer_name*/,
876 uint32_t* /*properties_count*/,
877 VkExtensionProperties* /*properties*/) {
878 return VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -0700879}
880
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700881// This is a no-op, the Top function returns the aggregate layer property
882// data. This is to keep the dispatch generator happy.
Jesse Halle1b12782015-11-30 11:27:32 -0800883VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -0700884VkResult EnumerateDeviceLayerProperties_Bottom(
885 VkPhysicalDevice /*pdev*/,
886 uint32_t* /*properties_count*/,
887 VkLayerProperties* /*properties*/) {
888 return VK_SUCCESS;
Jesse Hall1f91d392015-12-11 16:28:44 -0800889}
890
891VKAPI_ATTR
Jesse Hallb1471272016-01-17 21:36:58 -0800892VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
Jesse Hall1f91d392015-12-11 16:28:44 -0800893 const VkDeviceCreateInfo* create_info,
894 const VkAllocationCallbacks* allocator,
895 VkDevice* device_out) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700896 VkLayerDeviceCreateInfo* chain_info = const_cast<VkLayerDeviceCreateInfo*>(
897 static_cast<const VkLayerDeviceCreateInfo*>(create_info->pNext));
898 while (chain_info &&
899 !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO &&
900 chain_info->function == VK_LAYER_FUNCTION_DEVICE)) {
901 chain_info = const_cast<VkLayerDeviceCreateInfo*>(
902 static_cast<const VkLayerDeviceCreateInfo*>(chain_info->pNext));
Jesse Hall9a16f972015-10-28 15:59:53 -0700903 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700904 ALOG_ASSERT(chain_info != nullptr, "Missing initialization chain info!");
Jesse Hall9a16f972015-10-28 15:59:53 -0700905
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700906 Instance& instance = GetDispatchParent(gpu);
Jesse Hallb1471272016-01-17 21:36:58 -0800907 size_t gpu_idx = 0;
908 while (instance.physical_devices[gpu_idx] != gpu)
909 gpu_idx++;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700910 Device* device = static_cast<Device*>(chain_info->u.deviceInfo.device_info);
911 PFN_vkGetInstanceProcAddr get_instance_proc_addr =
912 chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
913
914 VkDeviceCreateInfo driver_create_info = *create_info;
915 driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
916 driver_create_info.enabledLayerCount = 0;
917 driver_create_info.ppEnabledLayerNames = nullptr;
Jesse Hallb1471272016-01-17 21:36:58 -0800918
919 uint32_t num_driver_extensions = 0;
920 const char** driver_extensions = static_cast<const char**>(
921 alloca(create_info->enabledExtensionCount * sizeof(const char*)));
922 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
923 const char* name = create_info->ppEnabledExtensionNames[i];
Jesse Hallb1471272016-01-17 21:36:58 -0800924 DeviceExtension id = DeviceExtensionFromName(name);
Jesse Hallae3b70d2016-01-17 22:05:29 -0800925 if (id != kDeviceExtensionCount) {
926 if (instance.physical_device_driver_extensions[gpu_idx][id]) {
927 driver_extensions[num_driver_extensions++] = name;
928 continue;
929 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700930 // Add the VK_ANDROID_native_buffer extension to the list iff
931 // the VK_KHR_swapchain extension was requested
Jesse Hallae3b70d2016-01-17 22:05:29 -0800932 if (id == kKHR_swapchain &&
933 instance.physical_device_driver_extensions
934 [gpu_idx][kANDROID_native_buffer]) {
935 driver_extensions[num_driver_extensions++] =
936 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;
937 continue;
938 }
Jesse Hallb1471272016-01-17 21:36:58 -0800939 }
Jesse Hallb1471272016-01-17 21:36:58 -0800940 bool supported = false;
941 for (const auto& layer : device->active_layers) {
942 if (layer.SupportsExtension(name))
943 supported = true;
944 }
945 if (!supported) {
946 ALOGE(
Jesse Hallae3b70d2016-01-17 22:05:29 -0800947 "requested device extension '%s' not supported by loader, "
948 "driver, or any active layers",
Jesse Hallb1471272016-01-17 21:36:58 -0800949 name);
Jesse Hallb1471272016-01-17 21:36:58 -0800950 return VK_ERROR_EXTENSION_NOT_PRESENT;
951 }
952 }
953
Jesse Hallb1471272016-01-17 21:36:58 -0800954 driver_create_info.enabledExtensionCount = num_driver_extensions;
955 driver_create_info.ppEnabledExtensionNames = driver_extensions;
Jesse Hall04f4f472015-08-16 19:51:04 -0700956 VkDevice drv_device;
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700957 VkResult result = instance.drv.dispatch.CreateDevice(
958 gpu, &driver_create_info, allocator, &drv_device);
Jesse Hall04f4f472015-08-16 19:51:04 -0700959 if (result != VK_SUCCESS) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700960 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -0700961 }
962
Jesse Hall1f91d392015-12-11 16:28:44 -0800963 hwvulkan_dispatch_t* drv_dispatch =
Jesse Hall04f4f472015-08-16 19:51:04 -0700964 reinterpret_cast<hwvulkan_dispatch_t*>(drv_device);
Jesse Hall1f91d392015-12-11 16:28:44 -0800965 if (drv_dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
966 ALOGE("invalid VkDevice dispatch magic: 0x%" PRIxPTR,
967 drv_dispatch->magic);
Michael Lentine03c64b02015-08-26 18:27:26 -0500968 PFN_vkDestroyDevice destroy_device =
969 reinterpret_cast<PFN_vkDestroyDevice>(
Jesse Hall1f91d392015-12-11 16:28:44 -0800970 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
971 "vkDestroyDevice"));
Jesse Hall03b6fe12015-11-24 12:44:21 -0800972 destroy_device(drv_device, allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -0700973 return VK_ERROR_INITIALIZATION_FAILED;
974 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -0700975
976 // Set dispatch table for newly created Device
977 // CreateDevice_Top will fill in the details
Jesse Hall1f91d392015-12-11 16:28:44 -0800978 drv_dispatch->vtbl = &device->dispatch;
979 device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
980 instance.drv.dispatch.GetDeviceProcAddr(drv_device,
981 "vkGetDeviceProcAddr"));
Jesse Hall1f91d392015-12-11 16:28:44 -0800982 *device_out = drv_device;
Jesse Hall04f4f472015-08-16 19:51:04 -0700983 return VK_SUCCESS;
984}
985
Jesse Hall1f91d392015-12-11 16:28:44 -0800986void DestroyInstance_Bottom(VkInstance vkinstance,
987 const VkAllocationCallbacks* allocator) {
988 Instance& instance = GetDispatchParent(vkinstance);
989
990 // These checks allow us to call DestroyInstance_Bottom from any error
991 // path in CreateInstance_Bottom, before the driver instance is fully
992 // initialized.
993 if (instance.drv.instance != VK_NULL_HANDLE &&
994 instance.drv.dispatch.DestroyInstance) {
995 instance.drv.dispatch.DestroyInstance(instance.drv.instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -0800996 instance.drv.instance = VK_NULL_HANDLE;
Jesse Hall1f91d392015-12-11 16:28:44 -0800997 }
Jesse Hall04f4f472015-08-16 19:51:04 -0700998}
999
Jesse Hall1f91d392015-12-11 16:28:44 -08001000PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
1001 const char* name) {
1002 if (strcmp(name, "vkCreateDevice") == 0) {
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001003 return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom);
Michael Lentine03c64b02015-08-26 18:27:26 -05001004 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001005
1006 // VK_ANDROID_native_buffer should be hidden from applications and layers.
1007 // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
1008 PFN_vkVoidFunction pfn;
1009 if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
1010 strcmp(name, "vkAcquireImageANDROID") == 0 ||
1011 strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
1012 return nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001013 }
Jesse Hall1f91d392015-12-11 16:28:44 -08001014 if ((pfn = GetLoaderBottomProcAddr(name)))
1015 return pfn;
1016 return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001017}
1018
Jesse Hall04f4f472015-08-16 19:51:04 -07001019// -----------------------------------------------------------------------------
Jesse Hall1f91d392015-12-11 16:28:44 -08001020// Loader top functions. These are called directly from the loader entry
1021// points or from the application (via vkGetInstanceProcAddr) without going
1022// through a dispatch table.
Jesse Hall04f4f472015-08-16 19:51:04 -07001023
Jesse Hall1f91d392015-12-11 16:28:44 -08001024VkResult EnumerateInstanceExtensionProperties_Top(
Jesse Hall80523e22016-01-06 16:47:54 -08001025 const char* layer_name,
1026 uint32_t* properties_count,
1027 VkExtensionProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001028 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001029 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001030
Jesse Hall80523e22016-01-06 16:47:54 -08001031 const VkExtensionProperties* extensions = nullptr;
1032 uint32_t num_extensions = 0;
1033 if (layer_name) {
Jesse Hallaa410942016-01-17 13:07:10 -08001034 GetInstanceLayerExtensions(layer_name, &extensions, &num_extensions);
Jesse Hall80523e22016-01-06 16:47:54 -08001035 } else {
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001036 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1037 alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties)));
1038 available[num_extensions++] = VkExtensionProperties{
1039 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION};
1040 available[num_extensions++] =
1041 VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
1042 VK_KHR_ANDROID_SURFACE_SPEC_VERSION};
1043 if (g_driver_instance_extensions[kEXT_debug_report]) {
1044 available[num_extensions++] =
1045 VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1046 VK_EXT_DEBUG_REPORT_SPEC_VERSION};
1047 }
Jesse Hall80523e22016-01-06 16:47:54 -08001048 // TODO(jessehall): We need to also enumerate extensions supported by
1049 // implicitly-enabled layers. Currently we don't have that list of
1050 // layers until instance creation.
Jesse Hall6bd5dfa2016-01-16 17:13:30 -08001051 extensions = available;
Jesse Hall80523e22016-01-06 16:47:54 -08001052 }
Jesse Hall04f4f472015-08-16 19:51:04 -07001053
Jesse Hall80523e22016-01-06 16:47:54 -08001054 if (!properties || *properties_count > num_extensions)
1055 *properties_count = num_extensions;
1056 if (properties)
1057 std::copy(extensions, extensions + *properties_count, properties);
1058 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001059}
1060
Jesse Hall80523e22016-01-06 16:47:54 -08001061VkResult EnumerateInstanceLayerProperties_Top(uint32_t* properties_count,
1062 VkLayerProperties* properties) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001063 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001064 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001065
Jesse Hall80523e22016-01-06 16:47:54 -08001066 uint32_t layer_count =
Jesse Hallaa410942016-01-17 13:07:10 -08001067 EnumerateInstanceLayers(properties ? *properties_count : 0, properties);
Jesse Hall80523e22016-01-06 16:47:54 -08001068 if (!properties || *properties_count > layer_count)
1069 *properties_count = layer_count;
1070 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
Jesse Hall04f4f472015-08-16 19:51:04 -07001071}
1072
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -07001073VKAPI_ATTR
1074VkResult EnumerateDeviceExtensionProperties_Top(
1075 VkPhysicalDevice gpu,
1076 const char* layer_name,
1077 uint32_t* properties_count,
1078 VkExtensionProperties* properties) {
1079 const VkExtensionProperties* extensions = nullptr;
1080 uint32_t num_extensions = 0;
1081
1082 ALOGV("EnumerateDeviceExtensionProperties_Top:");
1083 if (layer_name) {
1084 ALOGV(" layer %s", layer_name);
1085 GetDeviceLayerExtensions(layer_name, &extensions, &num_extensions);
1086 } else {
1087 ALOGV(" no layer");
1088 Instance& instance = GetDispatchParent(gpu);
1089 size_t gpu_idx = 0;
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -06001090 while (instance.physical_devices_top[gpu_idx] != gpu)
Courtney Goeltzenleuchter26d394b2016-02-07 10:32:27 -07001091 gpu_idx++;
1092 const DeviceExtensionSet driver_extensions =
1093 instance.physical_device_driver_extensions[gpu_idx];
1094
1095 // We only support VK_KHR_swapchain if the GPU supports
1096 // VK_ANDROID_native_buffer
1097 VkExtensionProperties* available = static_cast<VkExtensionProperties*>(
1098 alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties)));
1099 if (driver_extensions[kANDROID_native_buffer]) {
1100 available[num_extensions++] = VkExtensionProperties{
1101 VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION};
1102 }
1103
1104 // TODO(jessehall): We need to also enumerate extensions supported by
1105 // implicitly-enabled layers. Currently we don't have that list of
1106 // layers until instance creation.
1107 extensions = available;
1108 }
1109
1110 ALOGV(" num: %d, extensions: %p", num_extensions, extensions);
1111 if (!properties || *properties_count > num_extensions)
1112 *properties_count = num_extensions;
1113 if (properties)
1114 std::copy(extensions, extensions + *properties_count, properties);
1115 return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
1116}
1117
Jesse Hall1f91d392015-12-11 16:28:44 -08001118VkResult CreateInstance_Top(const VkInstanceCreateInfo* create_info,
1119 const VkAllocationCallbacks* allocator,
1120 VkInstance* instance_out) {
Jesse Hall04f4f472015-08-16 19:51:04 -07001121 VkResult result;
1122
1123 if (!EnsureInitialized())
Jesse Hall5ae3abb2015-10-08 14:00:22 -07001124 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Hall04f4f472015-08-16 19:51:04 -07001125
Jesse Hall03b6fe12015-11-24 12:44:21 -08001126 if (!allocator)
1127 allocator = &kDefaultAllocCallbacks;
1128
Jesse Hall04f4f472015-08-16 19:51:04 -07001129 VkInstanceCreateInfo local_create_info = *create_info;
Jesse Hall04f4f472015-08-16 19:51:04 -07001130 create_info = &local_create_info;
1131
Jesse Hall3fbc8562015-11-29 22:10:52 -08001132 void* instance_mem = allocator->pfnAllocation(
1133 allocator->pUserData, sizeof(Instance), alignof(Instance),
1134 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Jesse Hall04f4f472015-08-16 19:51:04 -07001135 if (!instance_mem)
1136 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall03b6fe12015-11-24 12:44:21 -08001137 Instance* instance = new (instance_mem) Instance(allocator);
Jesse Hall04f4f472015-08-16 19:51:04 -07001138
Jesse Hall9a16f972015-10-28 15:59:53 -07001139 result = ActivateAllLayers(create_info, instance, instance);
1140 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001141 DestroyInstance(instance, allocator);
Jesse Hall9a16f972015-10-28 15:59:53 -07001142 return result;
1143 }
Michael Lentine03c64b02015-08-26 18:27:26 -05001144
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001145 uint32_t activated_layers = 0;
1146 VkLayerInstanceCreateInfo chain_info;
1147 VkLayerInstanceLink* layer_instance_link_info = nullptr;
1148 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1149 VkInstance local_instance = nullptr;
Michael Lentine03c64b02015-08-26 18:27:26 -05001150
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001151 if (instance->active_layers.size() > 0) {
1152 chain_info.u.pLayerInfo = nullptr;
1153 chain_info.pNext = create_info->pNext;
1154 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1155 chain_info.function = VK_LAYER_FUNCTION_LINK;
1156 local_create_info.pNext = &chain_info;
Michael Lentine03c64b02015-08-26 18:27:26 -05001157
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001158 layer_instance_link_info = static_cast<VkLayerInstanceLink*>(alloca(
1159 sizeof(VkLayerInstanceLink) * instance->active_layers.size()));
1160 if (!layer_instance_link_info) {
1161 ALOGE("Failed to alloc Instance objects for layers");
Jesse Hallfee71432016-03-05 22:27:02 -08001162 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001163 return VK_ERROR_OUT_OF_HOST_MEMORY;
1164 }
1165
1166 /* Create instance chain of enabled layers */
1167 for (auto rit = instance->active_layers.rbegin();
1168 rit != instance->active_layers.rend(); ++rit) {
1169 LayerRef& layer = *rit;
1170 layer_instance_link_info[activated_layers].pNext =
1171 chain_info.u.pLayerInfo;
1172 layer_instance_link_info[activated_layers]
1173 .pfnNextGetInstanceProcAddr = next_gipa;
1174 chain_info.u.pLayerInfo =
1175 &layer_instance_link_info[activated_layers];
1176 next_gipa = layer.GetGetInstanceProcAddr();
1177
1178 ALOGV("Insert instance layer %s (v%u)", layer.GetName(),
1179 layer.GetSpecVersion());
1180
1181 activated_layers++;
Michael Lentine03c64b02015-08-26 18:27:26 -05001182 }
1183 }
1184
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001185 PFN_vkCreateInstance create_instance =
1186 reinterpret_cast<PFN_vkCreateInstance>(
1187 next_gipa(VK_NULL_HANDLE, "vkCreateInstance"));
1188 if (!create_instance) {
Jesse Hallfee71432016-03-05 22:27:02 -08001189 DestroyInstance(instance, allocator);
Michael Lentine03c64b02015-08-26 18:27:26 -05001190 return VK_ERROR_INITIALIZATION_FAILED;
1191 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001192 VkLayerInstanceCreateInfo instance_create_info;
1193
1194 instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
1195 instance_create_info.function = VK_LAYER_FUNCTION_INSTANCE;
1196
1197 instance_create_info.u.instanceInfo.instance_info = instance;
1198 instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1199
1200 instance_create_info.pNext = local_create_info.pNext;
1201 local_create_info.pNext = &instance_create_info;
1202
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001203 // Force enable callback extension if required
1204 bool enable_callback = false;
1205 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
1206 enable_callback =
1207 property_get_bool("debug.vulkan.enable_callback", false);
1208 if (enable_callback) {
Michael Lentine57036832016-03-04 11:03:35 -06001209 if (!AddExtensionToCreateInfo(local_create_info,
1210 "VK_EXT_debug_report", allocator)) {
1211 DestroyInstance(instance, allocator);
1212 return VK_ERROR_INITIALIZATION_FAILED;
1213 }
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001214 }
1215 }
Michael Lentine57036832016-03-04 11:03:35 -06001216 bool allocatedLayerMem;
1217 if (!AddLayersToCreateInfo(local_create_info, instance, allocator,
1218 allocatedLayerMem)) {
1219 if (enable_callback) {
1220 FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
1221 }
1222 DestroyInstance(instance, allocator);
1223 return VK_ERROR_INITIALIZATION_FAILED;
1224 }
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001225
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001226 result = create_instance(&local_create_info, allocator, &local_instance);
Michael Lentine57036832016-03-04 11:03:35 -06001227
1228 if (allocatedLayerMem) {
1229 FreeAllocatedLayerCreateInfo(local_create_info, allocator);
1230 }
1231 if (enable_callback) {
1232 FreeAllocatedExtensionCreateInfo(local_create_info, allocator);
1233 }
1234
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001235 if (result != VK_SUCCESS) {
Jesse Hallfee71432016-03-05 22:27:02 -08001236 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001237 return result;
1238 }
1239
1240 const InstanceDispatchTable& instance_dispatch =
1241 GetDispatchTable(local_instance);
1242 if (!LoadInstanceDispatchTable(
1243 local_instance, next_gipa,
1244 const_cast<InstanceDispatchTable&>(instance_dispatch))) {
1245 ALOGV("Failed to initialize instance dispatch table");
1246 PFN_vkDestroyInstance destroy_instance =
1247 reinterpret_cast<PFN_vkDestroyInstance>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001248 next_gipa(local_instance, "vkDestroyInstance"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001249 if (!destroy_instance) {
1250 ALOGD("Loader unable to find DestroyInstance");
1251 return VK_ERROR_INITIALIZATION_FAILED;
1252 }
1253 destroy_instance(local_instance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001254 DestroyInstance(instance, allocator);
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001255 return VK_ERROR_INITIALIZATION_FAILED;
1256 }
Courtney Goeltzenleuchter84cd4c22016-03-16 12:20:13 -06001257
1258 // Capture the physical devices from the top of the
1259 // chain in case it has been wrapped by a layer.
1260 uint32_t num_physical_devices = 0;
1261 result = instance_dispatch.EnumeratePhysicalDevices(
1262 local_instance, &num_physical_devices, nullptr);
1263 if (result != VK_SUCCESS) {
1264 DestroyInstance(instance, allocator);
1265 return VK_ERROR_INITIALIZATION_FAILED;
1266 }
1267 num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
1268 result = instance_dispatch.EnumeratePhysicalDevices(
1269 local_instance, &num_physical_devices,
1270 instance->physical_devices_top);
1271 if (result != VK_SUCCESS) {
1272 DestroyInstance(instance, allocator);
1273 return VK_ERROR_INITIALIZATION_FAILED;
1274 }
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001275 *instance_out = local_instance;
Michael Lentine03c64b02015-08-26 18:27:26 -05001276
Courtney Goeltzenleuchter12086222016-02-12 07:53:12 -07001277 if (enable_callback) {
Jesse Hall715b86a2016-01-16 16:34:29 -08001278 const VkDebugReportCallbackCreateInfoEXT callback_create_info = {
1279 .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
1280 .flags =
Jesse Halle2948d82016-02-25 04:19:32 -08001281 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
Jesse Hall715b86a2016-01-16 16:34:29 -08001282 .pfnCallback = LogDebugMessageCallback,
1283 };
1284 PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
1285 reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
1286 GetInstanceProcAddr_Top(instance->handle,
1287 "vkCreateDebugReportCallbackEXT"));
1288 create_debug_report_callback(instance->handle, &callback_create_info,
1289 allocator, &instance->message);
Michael Lentinecd6cabf2015-09-14 17:32:59 -05001290 }
1291
Jesse Hall04f4f472015-08-16 19:51:04 -07001292 return result;
1293}
1294
Jesse Hall1f91d392015-12-11 16:28:44 -08001295PFN_vkVoidFunction GetInstanceProcAddr_Top(VkInstance vkinstance,
1296 const char* name) {
1297 // vkGetInstanceProcAddr(NULL_HANDLE, ..) only works for global commands
1298 if (!vkinstance)
1299 return GetLoaderGlobalProcAddr(name);
1300
1301 const InstanceDispatchTable& dispatch = GetDispatchTable(vkinstance);
1302 PFN_vkVoidFunction pfn;
1303 // Always go through the loader-top function if there is one.
1304 if ((pfn = GetLoaderTopProcAddr(name)))
1305 return pfn;
1306 // Otherwise, look up the handler in the instance dispatch table
1307 if ((pfn = GetDispatchProcAddr(dispatch, name)))
1308 return pfn;
Jesse Hall1f91d392015-12-11 16:28:44 -08001309 // Anything not handled already must be a device-dispatched function
1310 // without a loader-top. We must return a function that will dispatch based
1311 // on the dispatchable object parameter -- which is exactly what the
1312 // exported functions do. So just return them here.
1313 return GetLoaderExportProcAddr(name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001314}
1315
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001316void DestroyInstance_Top(VkInstance vkinstance,
Jesse Hall1f91d392015-12-11 16:28:44 -08001317 const VkAllocationCallbacks* allocator) {
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001318 if (!vkinstance)
Jesse Hall1f91d392015-12-11 16:28:44 -08001319 return;
Jesse Hallfee71432016-03-05 22:27:02 -08001320 if (!allocator)
1321 allocator = &kDefaultAllocCallbacks;
Courtney Goeltzenleuchtere6e69682016-01-28 17:26:17 -07001322 GetDispatchTable(vkinstance).DestroyInstance(vkinstance, allocator);
Jesse Hallfee71432016-03-05 22:27:02 -08001323 DestroyInstance(&(GetDispatchParent(vkinstance)), allocator);
Jesse Hall1f91d392015-12-11 16:28:44 -08001324}
1325
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001326VKAPI_ATTR
Courtney Goeltzenleuchter1cc0d372016-02-05 17:10:59 -07001327VkResult EnumerateDeviceLayerProperties_Top(VkPhysicalDevice /*pdev*/,
1328 uint32_t* properties_count,
1329 VkLayerProperties* properties) {
1330 uint32_t layer_count =
1331 EnumerateDeviceLayers(properties ? *properties_count : 0, properties);
1332 if (!properties || *properties_count > layer_count)
1333 *properties_count = layer_count;
1334 return *properties_count < layer_count ? VK_INCOMPLETE : VK_SUCCESS;
1335}
1336
1337VKAPI_ATTR
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001338VkResult CreateDevice_Top(VkPhysicalDevice gpu,
1339 const VkDeviceCreateInfo* create_info,
1340 const VkAllocationCallbacks* allocator,
1341 VkDevice* device_out) {
1342 Instance& instance = GetDispatchParent(gpu);
1343 VkResult result;
1344
1345 // FIXME(jessehall): We don't have good conventions or infrastructure yet to
1346 // do better than just using the instance allocator and scope for
1347 // everything. See b/26732122.
1348 if (true /*!allocator*/)
1349 allocator = instance.alloc;
1350
1351 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device),
1352 alignof(Device),
1353 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1354 if (!mem)
1355 return VK_ERROR_OUT_OF_HOST_MEMORY;
1356 Device* device = new (mem) Device(&instance);
1357
1358 result = ActivateAllLayers(create_info, &instance, device);
1359 if (result != VK_SUCCESS) {
1360 DestroyDevice(device);
1361 return result;
1362 }
1363
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001364 uint32_t activated_layers = 0;
1365 VkLayerDeviceCreateInfo chain_info;
1366 VkLayerDeviceLink* layer_device_link_info = nullptr;
1367 PFN_vkGetInstanceProcAddr next_gipa = GetInstanceProcAddr_Bottom;
1368 PFN_vkGetDeviceProcAddr next_gdpa = GetDeviceProcAddr_Bottom;
1369 VkDeviceCreateInfo local_create_info = *create_info;
1370 VkDevice local_device = nullptr;
1371
1372 if (device->active_layers.size() > 0) {
1373 chain_info.u.pLayerInfo = nullptr;
1374 chain_info.pNext = local_create_info.pNext;
1375 chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1376 chain_info.function = VK_LAYER_FUNCTION_LINK;
1377 local_create_info.pNext = &chain_info;
1378
1379 layer_device_link_info = static_cast<VkLayerDeviceLink*>(
1380 alloca(sizeof(VkLayerDeviceLink) * device->active_layers.size()));
1381 if (!layer_device_link_info) {
1382 ALOGE("Failed to alloc Device objects for layers");
1383 DestroyDevice(device);
1384 return VK_ERROR_OUT_OF_HOST_MEMORY;
1385 }
1386
1387 /* Create device chain of enabled layers */
1388 for (auto rit = device->active_layers.rbegin();
1389 rit != device->active_layers.rend(); ++rit) {
1390 LayerRef& layer = *rit;
1391 layer_device_link_info[activated_layers].pNext =
1392 chain_info.u.pLayerInfo;
1393 layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr =
1394 next_gdpa;
1395 layer_device_link_info[activated_layers]
1396 .pfnNextGetInstanceProcAddr = next_gipa;
1397 chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
1398
1399 next_gipa = layer.GetGetInstanceProcAddr();
1400 next_gdpa = layer.GetGetDeviceProcAddr();
1401
1402 ALOGV("Insert device layer %s (v%u)", layer.GetName(),
1403 layer.GetSpecVersion());
1404
1405 activated_layers++;
1406 }
1407 }
1408
1409 PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001410 next_gipa(instance.handle, "vkCreateDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001411 if (!create_device) {
1412 ALOGE("Unable to find vkCreateDevice for driver");
1413 DestroyDevice(device);
1414 return VK_ERROR_INITIALIZATION_FAILED;
1415 }
1416
1417 VkLayerDeviceCreateInfo device_create_info;
1418
1419 device_create_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
1420 device_create_info.function = VK_LAYER_FUNCTION_DEVICE;
1421
1422 device_create_info.u.deviceInfo.device_info = device;
1423 device_create_info.u.deviceInfo.pfnNextGetInstanceProcAddr = next_gipa;
1424
1425 device_create_info.pNext = local_create_info.pNext;
1426 local_create_info.pNext = &device_create_info;
1427
Michael Lentine57036832016-03-04 11:03:35 -06001428 bool allocatedLayerMem;
1429 if (!AddLayersToCreateInfo(local_create_info, device, allocator,
1430 allocatedLayerMem)) {
1431 DestroyDevice(device);
1432 return VK_ERROR_INITIALIZATION_FAILED;
1433 }
1434
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001435 result = create_device(gpu, &local_create_info, allocator, &local_device);
1436
Michael Lentine57036832016-03-04 11:03:35 -06001437 if (allocatedLayerMem) {
1438 FreeAllocatedLayerCreateInfo(local_create_info, allocator);
1439 }
1440
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001441 if (result != VK_SUCCESS) {
1442 DestroyDevice(device);
1443 return result;
1444 }
1445
1446 // Set dispatch table for newly created Device
1447 hwvulkan_dispatch_t* vulkan_dispatch =
1448 reinterpret_cast<hwvulkan_dispatch_t*>(local_device);
1449 vulkan_dispatch->vtbl = &device->dispatch;
1450
1451 const DeviceDispatchTable& device_dispatch = GetDispatchTable(local_device);
1452 if (!LoadDeviceDispatchTable(
1453 local_device, next_gdpa,
1454 const_cast<DeviceDispatchTable&>(device_dispatch))) {
1455 ALOGV("Failed to initialize device dispatch table");
1456 PFN_vkDestroyDevice destroy_device =
1457 reinterpret_cast<PFN_vkDestroyDevice>(
Courtney Goeltzenleuchter4fe2d922016-03-10 13:28:52 -07001458 next_gipa(instance.handle, "vkDestroyDevice"));
Courtney Goeltzenleuchtera90ce612016-02-08 20:48:05 -07001459 ALOG_ASSERT(destroy_device != nullptr,
1460 "Loader unable to find DestroyDevice");
1461 destroy_device(local_device, allocator);
1462 return VK_ERROR_INITIALIZATION_FAILED;
1463 }
1464 *device_out = local_device;
1465
1466 return VK_SUCCESS;
1467}
1468
Jesse Hall1f91d392015-12-11 16:28:44 -08001469PFN_vkVoidFunction GetDeviceProcAddr_Top(VkDevice device, const char* name) {
1470 PFN_vkVoidFunction pfn;
Jesse Hall04f4f472015-08-16 19:51:04 -07001471 if (!device)
Jesse Hall1f91d392015-12-11 16:28:44 -08001472 return nullptr;
1473 if ((pfn = GetLoaderTopProcAddr(name)))
1474 return pfn;
1475 return GetDispatchProcAddr(GetDispatchTable(device), name);
Jesse Hall04f4f472015-08-16 19:51:04 -07001476}
1477
Jesse Hall1f91d392015-12-11 16:28:44 -08001478void GetDeviceQueue_Top(VkDevice vkdevice,
1479 uint32_t family,
1480 uint32_t index,
1481 VkQueue* queue_out) {
1482 const auto& table = GetDispatchTable(vkdevice);
1483 table.GetDeviceQueue(vkdevice, family, index, queue_out);
1484 hwvulkan_dispatch_t* queue_dispatch =
1485 reinterpret_cast<hwvulkan_dispatch_t*>(*queue_out);
1486 if (queue_dispatch->magic != HWVULKAN_DISPATCH_MAGIC &&
1487 queue_dispatch->vtbl != &table)
1488 ALOGE("invalid VkQueue dispatch magic: 0x%" PRIxPTR,
1489 queue_dispatch->magic);
1490 queue_dispatch->vtbl = &table;
Jesse Hall04f4f472015-08-16 19:51:04 -07001491}
1492
Jesse Hall1f91d392015-12-11 16:28:44 -08001493VkResult AllocateCommandBuffers_Top(
1494 VkDevice vkdevice,
1495 const VkCommandBufferAllocateInfo* alloc_info,
1496 VkCommandBuffer* cmdbufs) {
1497 const auto& table = GetDispatchTable(vkdevice);
1498 VkResult result =
1499 table.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs);
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001500 if (result != VK_SUCCESS)
1501 return result;
Jesse Hall3dd678a2016-01-08 21:52:01 -08001502 for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) {
Jesse Hall1f91d392015-12-11 16:28:44 -08001503 hwvulkan_dispatch_t* cmdbuf_dispatch =
Jesse Hall3fbc8562015-11-29 22:10:52 -08001504 reinterpret_cast<hwvulkan_dispatch_t*>(cmdbufs[i]);
Jesse Hall1f91d392015-12-11 16:28:44 -08001505 ALOGE_IF(cmdbuf_dispatch->magic != HWVULKAN_DISPATCH_MAGIC,
Jesse Hall3fbc8562015-11-29 22:10:52 -08001506 "invalid VkCommandBuffer dispatch magic: 0x%" PRIxPTR,
Jesse Hall1f91d392015-12-11 16:28:44 -08001507 cmdbuf_dispatch->magic);
1508 cmdbuf_dispatch->vtbl = &table;
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001509 }
Jesse Hallc7a6eb52015-08-31 12:52:03 -07001510 return VK_SUCCESS;
1511}
1512
Jesse Hall1f91d392015-12-11 16:28:44 -08001513void DestroyDevice_Top(VkDevice vkdevice,
1514 const VkAllocationCallbacks* /*allocator*/) {
1515 if (!vkdevice)
1516 return;
1517 Device& device = GetDispatchParent(vkdevice);
Jesse Hall1f91d392015-12-11 16:28:44 -08001518 device.dispatch.DestroyDevice(vkdevice, device.instance->alloc);
1519 DestroyDevice(&device);
Jesse Hall04f4f472015-08-16 19:51:04 -07001520}
1521
Jesse Hall1f91d392015-12-11 16:28:44 -08001522// -----------------------------------------------------------------------------
1523
1524const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) {
1525 return GetDispatchParent(vkinstance).alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001526}
1527
Jesse Hall1f91d392015-12-11 16:28:44 -08001528const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) {
1529 return GetDispatchParent(vkdevice).instance->alloc;
Jesse Hall1356b0d2015-11-23 17:24:58 -08001530}
1531
Jesse Hall715b86a2016-01-16 16:34:29 -08001532VkInstance GetDriverInstance(VkInstance instance) {
1533 return GetDispatchParent(instance).drv.instance;
1534}
1535
1536const DriverDispatchTable& GetDriverDispatch(VkInstance instance) {
1537 return GetDispatchParent(instance).drv.dispatch;
1538}
1539
Jesse Hall1f91d392015-12-11 16:28:44 -08001540const DriverDispatchTable& GetDriverDispatch(VkDevice device) {
1541 return GetDispatchParent(device).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001542}
1543
Jesse Hall1f91d392015-12-11 16:28:44 -08001544const DriverDispatchTable& GetDriverDispatch(VkQueue queue) {
1545 return GetDispatchParent(queue).instance->drv.dispatch;
Jesse Halld7b994a2015-09-07 14:17:37 -07001546}
1547
Jesse Hall715b86a2016-01-16 16:34:29 -08001548DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) {
1549 return GetDispatchParent(instance).debug_report_callbacks;
1550}
1551
Jesse Hall04f4f472015-08-16 19:51:04 -07001552} // namespace vulkan