10c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu/* 20c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * Copyright 2016 The Android Open Source Project 30c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * 40c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * Licensed under the Apache License, Version 2.0 (the "License"); 50c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * you may not use this file except in compliance with the License. 60c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * You may obtain a copy of the License at 70c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * 80c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * http://www.apache.org/licenses/LICENSE-2.0 90c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * 100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * Unless required by applicable law or agreed to in writing, software 110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * distributed under the License is distributed on an "AS IS" BASIS, 120c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * See the License for the specific language governing permissions and 140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu * limitations under the License. 150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu */ 160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// The API layer of the loader defines Vulkan API and manages layers. The 180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// entrypoints are generated and defined in api_dispatch.cpp. Most of them 190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// simply find the dispatch table and jump. 200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// 210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// There are a few of them requiring manual code for things such as layer 220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// discovery or chaining. They call into functions defined in this file. 230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <stdlib.h> 250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <string.h> 260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <algorithm> 270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <mutex> 280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <new> 290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <utility> 300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <cutils/properties.h> 310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <log/log.h> 320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include <vulkan/vk_layer_interface.h> 340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include "api.h" 350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu#include "driver.h" 36c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu#include "layers_extensions.h" 370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wunamespace vulkan { 390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wunamespace api { 400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wunamespace { 420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// Provide overridden layer names when there are implicit layers. No effect 440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// otherwise. 450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wuclass OverrideLayerNames { 460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu public: 470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator) 480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu : is_instance_(is_instance), 490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_(allocator), 500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND), 510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu names_(nullptr), 520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu name_count_(0), 530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu implicit_layers_() { 540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu implicit_layers_.result = VK_SUCCESS; 550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ~OverrideLayerNames() { 580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pfnFree(allocator_.pUserData, names_); 590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements); 600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool); 610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 63026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu VkResult Parse(const char* const* names, uint32_t count) { 64026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu AddImplicitLayers(); 650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const auto& arr = implicit_layers_; 670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (arr.result != VK_SUCCESS) 680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return arr.result; 690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // no need to override when there is no implicit layer 710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!arr.count) 720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 74026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu names_ = AllocateNameArray(arr.count + count); 750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!names_) 760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 780c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // add implicit layer names 790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < arr.count; i++) 80026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu names_[i] = GetImplicitLayerName(i); 810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu name_count_ = arr.count; 830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // add explicit layer names 850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < count; i++) { 860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // ignore explicit layers that are also implicit 87026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (IsImplicitLayer(names[i])) 880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu continue; 890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu names_[name_count_++] = names[i]; 910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 96026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu const char* const* Names() const { return names_; } 970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 98026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu uint32_t Count() const { return name_count_; } 990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu private: 1010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu struct ImplicitLayer { 1020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu int priority; 1030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu size_t name_offset; 1040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu }; 1050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu struct ImplicitLayerArray { 1070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ImplicitLayer* elements; 1080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t max_count; 1090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t count; 1100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu char* name_pool; 1120c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu size_t max_pool_size; 1130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu size_t pool_size; 1140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkResult result; 1160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu }; 1170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 118026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu void AddImplicitLayers() { 119c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!is_instance_ || !driver::Debuggable()) 1200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return; 1210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 122026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu ParseDebugVulkanLayers(); 123026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu property_list(ParseDebugVulkanLayer, this); 1240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // sort by priorities 1260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu auto& arr = implicit_layers_; 1270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::sort(arr.elements, arr.elements + arr.count, 1280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu [](const ImplicitLayer& a, const ImplicitLayer& b) { 1290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return (a.priority < b.priority); 1300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu }); 1310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 133026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu void ParseDebugVulkanLayers() { 1340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // debug.vulkan.layers specifies colon-separated layer names 1350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu char prop[PROPERTY_VALUE_MAX]; 1360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!property_get("debug.vulkan.layers", prop, "")) 1370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return; 1380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // assign negative/high priorities to them 1400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu int prio = -PROPERTY_VALUE_MAX; 1410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char* p = prop; 1430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char* delim; 1440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu while ((delim = strchr(p, ':'))) { 1450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (delim > p) 146026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu AddImplicitLayer(prio, p, static_cast<size_t>(delim - p)); 1470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio++; 1490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu p = delim + 1; 1500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (p[0] != '\0') 153026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu AddImplicitLayer(prio, p, strlen(p)); 1540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 156026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu static void ParseDebugVulkanLayer(const char* key, 157026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu const char* val, 158026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu void* user_data) { 1590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu static const char prefix[] = "debug.vulkan.layer."; 1600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const size_t prefix_len = sizeof(prefix) - 1; 1610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (strncmp(key, prefix, prefix_len) || val[0] == '\0') 1630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return; 1640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu key += prefix_len; 1650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // debug.vulkan.layer.<priority> 1670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu int priority = -1; 1680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (key[0] >= '0' && key[0] <= '9') 1690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu priority = atoi(key); 1700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (priority < 0) { 1720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ALOGW("Ignored implicit layer %s with invalid priority %s", val, 1730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu key); 1740c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return; 1750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu OverrideLayerNames& override_layers = 1780c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *reinterpret_cast<OverrideLayerNames*>(user_data); 179026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu override_layers.AddImplicitLayer(priority, val, strlen(val)); 1800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 182026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu void AddImplicitLayer(int priority, const char* name, size_t len) { 183026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (!GrowImplicitLayerArray(1, 0)) 1840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return; 1850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu auto& arr = implicit_layers_; 1870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu auto& layer = arr.elements[arr.count++]; 1880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.priority = priority; 190026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu layer.name_offset = AddImplicitLayerName(name, len); 1910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 192026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu ALOGV("Added implicit layer %s", GetImplicitLayerName(arr.count - 1)); 1930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 1940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 195026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu size_t AddImplicitLayerName(const char* name, size_t len) { 196026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (!GrowImplicitLayerArray(0, len + 1)) 1970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return 0; 1980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // add the name to the pool 2000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu auto& arr = implicit_layers_; 2010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu size_t offset = arr.pool_size; 2020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu char* dst = arr.name_pool + offset; 2030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::copy(name, name + len, dst); 2050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu dst[len] = '\0'; 2060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.pool_size += len + 1; 2080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return offset; 2100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 212026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu bool GrowImplicitLayerArray(uint32_t layer_count, size_t name_size) { 2130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const uint32_t initial_max_count = 16; 2140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const size_t initial_max_pool_size = 512; 2150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu auto& arr = implicit_layers_; 2170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // grow the element array if needed 2190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu while (arr.count + layer_count > arr.max_count) { 2200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t new_max_count = 2210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (arr.max_count) ? (arr.max_count << 1) : initial_max_count; 2220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu void* new_mem = nullptr; 2230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (new_max_count > arr.max_count) { 2250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu new_mem = allocator_.pfnReallocation( 2260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pUserData, arr.elements, 2270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu sizeof(ImplicitLayer) * new_max_count, 2280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu alignof(ImplicitLayer), scope_); 2290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!new_mem) { 2320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.result = VK_ERROR_OUT_OF_HOST_MEMORY; 2330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.count = 0; 2340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return false; 2350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem); 2380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.max_count = new_max_count; 2390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // grow the name pool if needed 2420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu while (arr.pool_size + name_size > arr.max_pool_size) { 2430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu size_t new_max_pool_size = (arr.max_pool_size) 2440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ? (arr.max_pool_size << 1) 2450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu : initial_max_pool_size; 2460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu void* new_mem = nullptr; 2470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (new_max_pool_size > arr.max_pool_size) { 2490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu new_mem = allocator_.pfnReallocation( 2500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pUserData, arr.name_pool, new_max_pool_size, 2510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu alignof(char), scope_); 2520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!new_mem) { 2550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.result = VK_ERROR_OUT_OF_HOST_MEMORY; 2560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.pool_size = 0; 2570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return false; 2580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.name_pool = reinterpret_cast<char*>(new_mem); 2610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu arr.max_pool_size = new_max_pool_size; 2620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return true; 2650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 267026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu const char* GetImplicitLayerName(uint32_t index) const { 2680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const auto& arr = implicit_layers_; 2690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // this may return nullptr when arr.result is not VK_SUCCESS 2710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return implicit_layers_.name_pool + arr.elements[index].name_offset; 2720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 274026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu bool IsImplicitLayer(const char* name) const { 2750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const auto& arr = implicit_layers_; 2760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < arr.count; i++) { 278026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (strcmp(name, GetImplicitLayerName(i)) == 0) 2790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return true; 2800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return false; 2830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 285026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu const char** AllocateNameArray(uint32_t count) const { 2860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return reinterpret_cast<const char**>(allocator_.pfnAllocation( 2870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pUserData, sizeof(const char*) * count, 2880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu alignof(const char*), scope_)); 2890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 2900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const bool is_instance_; 2920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks& allocator_; 2930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkSystemAllocationScope scope_; 2940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char** names_; 2960c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t name_count_; 2970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 2980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ImplicitLayerArray implicit_layers_; 2990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu}; 3000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// Provide overridden extension names when there are implicit extensions. 3020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// No effect otherwise. 3030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// 3040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// This is used only to enable VK_EXT_debug_report. 3050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wuclass OverrideExtensionNames { 3060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu public: 3070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu OverrideExtensionNames(bool is_instance, 3080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks& allocator) 3090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu : is_instance_(is_instance), 3100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_(allocator), 3110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND), 3120c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu names_(nullptr), 3130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu name_count_(0), 3140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu install_debug_callback_(false) {} 3150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ~OverrideExtensionNames() { 3170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pfnFree(allocator_.pUserData, names_); 3180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 3190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 320c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu VkResult Parse(const char* const* names, uint32_t count) { 3210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // this is only for debug.vulkan.enable_callback 322c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu if (!EnableDebugCallback()) 3230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 3240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 325c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu names_ = AllocateNameArray(count + 1); 3260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!names_) 3270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 3280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::copy(names, names + count, names_); 3300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu name_count_ = count; 3320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu names_[name_count_++] = "VK_EXT_debug_report"; 3330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu install_debug_callback_ = true; 3350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 3370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 3380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 339c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu const char* const* Names() const { return names_; } 3400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 341c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu uint32_t Count() const { return name_count_; } 3420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 343c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu bool InstallDebugCallback() const { return install_debug_callback_; } 3440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu private: 346c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu bool EnableDebugCallback() const { 3470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return (is_instance_ && driver::Debuggable() && 3480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu property_get_bool("debug.vulkan.enable_callback", false)); 3490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 3500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 351c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu const char** AllocateNameArray(uint32_t count) const { 3520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return reinterpret_cast<const char**>(allocator_.pfnAllocation( 3530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pUserData, sizeof(const char*) * count, 3540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu alignof(const char*), scope_)); 3550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 3560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const bool is_instance_; 3580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks& allocator_; 3590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkSystemAllocationScope scope_; 3600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char** names_; 3620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t name_count_; 3630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu bool install_debug_callback_; 3640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu}; 3650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 3660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// vkCreateInstance and vkCreateDevice helpers with support for layer 3670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// chaining. 3680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wuclass LayerChain { 3690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu public: 370c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu struct ActiveLayer { 371c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu LayerRef ref; 372c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu union { 373c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkLayerInstanceLink instance_link; 374c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkLayerDeviceLink device_link; 375c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu }; 376c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu }; 377c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 378eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu static VkResult CreateInstance(const VkInstanceCreateInfo* create_info, 379eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator, 380eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkInstance* instance_out); 3810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 382eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu static VkResult CreateDevice(VkPhysicalDevice physical_dev, 383eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkDeviceCreateInfo* create_info, 384eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator, 385eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkDevice* dev_out); 3860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 387eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu static void DestroyInstance(VkInstance instance, 388eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator); 3890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 390eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu static void DestroyDevice(VkDevice dev, 391eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator); 3920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 393c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu static const ActiveLayer* GetActiveLayers(VkPhysicalDevice physical_dev, 394c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t& count); 3950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 396c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu private: 397a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu LayerChain(bool is_instance, 398a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu const driver::DebugReportLogger& logger, 399a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu const VkAllocationCallbacks& allocator); 4000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ~LayerChain(); 4010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 402eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult ActivateLayers(const char* const* layer_names, 403eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t layer_count, 404eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* const* extension_names, 405eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count); 406c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkResult ActivateLayers(VkPhysicalDevice physical_dev, 407c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const char* const* layer_names, 408c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t layer_count, 409c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const char* const* extension_names, 410c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t extension_count); 411eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu ActiveLayer* AllocateLayerArray(uint32_t count) const; 412eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult LoadLayer(ActiveLayer& layer, const char* name); 413eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void SetupLayerLinks(); 4140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 415eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu bool Empty() const; 416eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void ModifyCreateInfo(VkInstanceCreateInfo& info); 417eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void ModifyCreateInfo(VkDeviceCreateInfo& info); 4180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 419eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult Create(const VkInstanceCreateInfo* create_info, 4200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* allocator, 4210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkInstance* instance_out); 4220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 423eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult Create(VkPhysicalDevice physical_dev, 4240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkDeviceCreateInfo* create_info, 4250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* allocator, 4260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDevice* dev_out); 4270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 428eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult ValidateExtensions(const char* const* extension_names, 429eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count); 430eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult ValidateExtensions(VkPhysicalDevice physical_dev, 431eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* const* extension_names, 432eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count); 433eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkExtensionProperties* AllocateDriverExtensionArray(uint32_t count) const; 434eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu bool IsLayerExtension(const char* name) const; 435eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu bool IsDriverExtension(const char* name) const; 4361f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 4370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu template <typename DataType> 438eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void StealLayers(DataType& data); 4390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 440eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu static void DestroyLayers(ActiveLayer* layers, 441eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t count, 442eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks& allocator); 4430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 44494a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu static VKAPI_ATTR VkResult SetInstanceLoaderData(VkInstance instance, 44594a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu void* object); 44694a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu static VKAPI_ATTR VkResult SetDeviceLoaderData(VkDevice device, 44794a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu void* object); 44894a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu 4490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu static VKAPI_ATTR VkBool32 450eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu DebugReportCallback(VkDebugReportFlagsEXT flags, 451eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkDebugReportObjectTypeEXT obj_type, 452eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint64_t obj, 453eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu size_t location, 454eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu int32_t msg_code, 455eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* layer_prefix, 456eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* msg, 457eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void* user_data); 4580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const bool is_instance_; 460a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu const driver::DebugReportLogger& logger_; 4610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks& allocator_; 4620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu OverrideLayerNames override_layers_; 4640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu OverrideExtensionNames override_extensions_; 4650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ActiveLayer* layers_; 4670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t layer_count_; 4680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu PFN_vkGetInstanceProcAddr get_instance_proc_addr_; 4700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu PFN_vkGetDeviceProcAddr get_device_proc_addr_; 4710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu union { 47394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu VkLayerInstanceCreateInfo instance_chain_info_[2]; 47494a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu VkLayerDeviceCreateInfo device_chain_info_[2]; 4750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu }; 4761f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 4771f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu VkExtensionProperties* driver_extensions_; 4781f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu uint32_t driver_extension_count_; 4798925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu std::bitset<driver::ProcHook::EXTENSION_COUNT> enabled_extensions_; 4800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu}; 4810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 482a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I WuLayerChain::LayerChain(bool is_instance, 483a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu const driver::DebugReportLogger& logger, 484a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu const VkAllocationCallbacks& allocator) 4850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu : is_instance_(is_instance), 486a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu logger_(logger), 4870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_(allocator), 4880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu override_layers_(is_instance, allocator), 4890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu override_extensions_(is_instance, allocator), 4900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layers_(nullptr), 4910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer_count_(0), 4920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_(nullptr), 4931f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu get_device_proc_addr_(nullptr), 4941f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu driver_extensions_(nullptr), 4958925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu driver_extension_count_(0) { 4968925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE); 4978925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu} 4980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 4990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuLayerChain::~LayerChain() { 5001f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu allocator_.pfnFree(allocator_.pUserData, driver_extensions_); 501eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu DestroyLayers(layers_, layer_count_, allocator_); 5020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 5030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 504eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::ActivateLayers(const char* const* layer_names, 505eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t layer_count, 506eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* const* extension_names, 507eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count) { 508026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu VkResult result = override_layers_.Parse(layer_names, layer_count); 5090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 5100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 5110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 512c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu result = override_extensions_.Parse(extension_names, extension_count); 5130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 5140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 5150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 516026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (override_layers_.Count()) { 517026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu layer_names = override_layers_.Names(); 518026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu layer_count = override_layers_.Count(); 5190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 5200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 5210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!layer_count) { 5220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // point head of chain to the driver 5230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_ = driver::GetInstanceProcAddr; 5240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 5250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 5260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 5270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 528eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu layers_ = AllocateLayerArray(layer_count); 5290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!layers_) 5300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 5310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 5320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // load layers 5330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < layer_count; i++) { 534eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu result = LoadLayer(layers_[i], layer_names[i]); 5350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 5360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 5370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 5380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // count loaded layers for proper destructions on errors 5390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer_count_++; 5400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 5410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 542eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu SetupLayerLinks(); 5430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 5440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 5450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 5460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 547c3a28913b6a95d2faee0db537c48557e04267511Chia-I WuVkResult LayerChain::ActivateLayers(VkPhysicalDevice physical_dev, 548c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const char* const* layer_names, 549c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t layer_count, 550c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const char* const* extension_names, 551c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t extension_count) { 552c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t instance_layer_count; 553c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const ActiveLayer* instance_layers = 554c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu GetActiveLayers(physical_dev, instance_layer_count); 555c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 556c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // log a message if the application device layer array is not empty nor an 557c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // exact match of the instance layer array. 558c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (layer_count) { 559c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu bool exact_match = (instance_layer_count == layer_count); 560c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (exact_match) { 561c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu for (uint32_t i = 0; i < instance_layer_count; i++) { 562c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const Layer& l = *instance_layers[i].ref; 563c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (strcmp(GetLayerProperties(l).layerName, layer_names[i])) { 564c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu exact_match = false; 565c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu break; 566c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 567c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 568c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 569c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 570c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!exact_match) { 571a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu logger_.Warn(physical_dev, 572a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu "Device layers disagree with instance layers and are " 573a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu "overridden by instance layers"); 574c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 575c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 576c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 577c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkResult result = 578c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu override_extensions_.Parse(extension_names, extension_count); 579c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (result != VK_SUCCESS) 580c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu return result; 581c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 582c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!instance_layer_count) { 583c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // point head of chain to the driver 584c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu get_instance_proc_addr_ = driver::GetInstanceProcAddr; 585c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu get_device_proc_addr_ = driver::GetDeviceProcAddr; 586c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 587c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu return VK_SUCCESS; 588c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 589c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 590c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu layers_ = AllocateLayerArray(instance_layer_count); 591c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!layers_) 592c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 593c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 594c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu for (uint32_t i = 0; i < instance_layer_count; i++) { 595c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const Layer& l = *instance_layers[i].ref; 596c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 597c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // no need to and cannot chain non-global layers 598c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!IsLayerGlobal(l)) 599c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu continue; 600c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 601c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // this never fails 602c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu new (&layers_[layer_count_++]) ActiveLayer{GetLayerRef(l), {}}; 603c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu } 604c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 60561b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu // this may happen when all layers are non-global ones 60661b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu if (!layer_count_) { 60761b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu get_instance_proc_addr_ = driver::GetInstanceProcAddr; 60861b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu get_device_proc_addr_ = driver::GetDeviceProcAddr; 60961b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu return VK_SUCCESS; 61061b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu } 61161b25fdffc360ab70e1f33be0bb43c911150277bChia-I Wu 612c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu SetupLayerLinks(); 613c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 614c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu return VK_SUCCESS; 615c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu} 616c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu 617eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuLayerChain::ActiveLayer* LayerChain::AllocateLayerArray(uint32_t count) const { 6180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkSystemAllocationScope scope = (is_instance_) 6190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE 620c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu : VK_SYSTEM_ALLOCATION_SCOPE_COMMAND; 6210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation( 6230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer), 6240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu scope)); 6250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 6260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 627eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::LoadLayer(ActiveLayer& layer, const char* name) { 628d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu const Layer* l = FindLayer(name); 629c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!l) { 630a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu logger_.Err(VK_NULL_HANDLE, "Failed to find layer %s", name); 631d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 632d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu } 633d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu 634dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu new (&layer) ActiveLayer{GetLayerRef(*l), {}}; 6350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!layer.ref) { 636d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu ALOGW("Failed to open layer %s", name); 6370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.ref.~LayerRef(); 6380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 6390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 6400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 641c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu ALOGI("Loaded layer %s", name); 6420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 6440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 6450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 646eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::SetupLayerLinks() { 6470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (is_instance_) { 6480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < layer_count_; i++) { 6490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ActiveLayer& layer = layers_[i]; 6500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // point head of chain to the first layer 6520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (i == 0) 6530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr(); 6540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // point tail of chain to the driver 6560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (i == layer_count_ - 1) { 6570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.instance_link.pNext = nullptr; 6580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.instance_link.pfnNextGetInstanceProcAddr = 6590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu driver::GetInstanceProcAddr; 6600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu break; 6610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 6620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const ActiveLayer& next = layers_[i + 1]; 6640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // const_cast as some naughty layers want to modify our links! 6660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.instance_link.pNext = 6670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const_cast<VkLayerInstanceLink*>(&next.instance_link); 6680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.instance_link.pfnNextGetInstanceProcAddr = 6690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu next.ref.GetGetInstanceProcAddr(); 6700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 6710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } else { 6720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < layer_count_; i++) { 6730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ActiveLayer& layer = layers_[i]; 6740c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // point head of chain to the first layer 6760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (i == 0) { 6770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr(); 6780c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr(); 6790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 6800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // point tail of chain to the driver 6820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (i == layer_count_ - 1) { 6830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pNext = nullptr; 6840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pfnNextGetInstanceProcAddr = 6850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu driver::GetInstanceProcAddr; 6860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pfnNextGetDeviceProcAddr = 6870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu driver::GetDeviceProcAddr; 6880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu break; 6890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 6900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const ActiveLayer& next = layers_[i + 1]; 6920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 6930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // const_cast as some naughty layers want to modify our links! 6940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pNext = 6950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const_cast<VkLayerDeviceLink*>(&next.device_link); 6960c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pfnNextGetInstanceProcAddr = 6970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu next.ref.GetGetInstanceProcAddr(); 6980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer.device_link.pfnNextGetDeviceProcAddr = 6990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu next.ref.GetGetDeviceProcAddr(); 7000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 7030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 704eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wubool LayerChain::Empty() const { 705026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu return (!layer_count_ && !override_layers_.Count() && 706c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu !override_extensions_.Count()); 7070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 7080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 709eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::ModifyCreateInfo(VkInstanceCreateInfo& info) { 7100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (layer_count_) { 71194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu auto& link_info = instance_chain_info_[1]; 71294a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO; 71394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.pNext = info.pNext; 71494a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.function = VK_LAYER_FUNCTION_LINK; 71594a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.u.pLayerInfo = &layers_[0].instance_link; 7160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 71794a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu auto& cb_info = instance_chain_info_[0]; 71894a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO; 71994a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.pNext = &link_info; 72094a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK; 72194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.u.pfnSetInstanceLoaderData = SetInstanceLoaderData; 7220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 72394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu info.pNext = &cb_info; 7240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 726026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (override_layers_.Count()) { 727026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu info.enabledLayerCount = override_layers_.Count(); 728026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu info.ppEnabledLayerNames = override_layers_.Names(); 7290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 731c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu if (override_extensions_.Count()) { 732c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu info.enabledExtensionCount = override_extensions_.Count(); 733c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu info.ppEnabledExtensionNames = override_extensions_.Names(); 7340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 7360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 737eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::ModifyCreateInfo(VkDeviceCreateInfo& info) { 7380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (layer_count_) { 73994a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu auto& link_info = device_chain_info_[1]; 74094a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO; 74194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.pNext = info.pNext; 74294a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.function = VK_LAYER_FUNCTION_LINK; 74394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu link_info.u.pLayerInfo = &layers_[0].device_link; 7440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 74594a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu auto& cb_info = device_chain_info_[0]; 74694a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO; 74794a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.pNext = &link_info; 74894a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.function = VK_LAYER_FUNCTION_DATA_CALLBACK; 74994a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu cb_info.u.pfnSetDeviceLoaderData = SetDeviceLoaderData; 7500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 75194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu info.pNext = &cb_info; 7520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 754026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu if (override_layers_.Count()) { 755026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu info.enabledLayerCount = override_layers_.Count(); 756026b8facd53e2db16bb73f6dccb064f00d8e9b00Chia-I Wu info.ppEnabledLayerNames = override_layers_.Names(); 7570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 759c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu if (override_extensions_.Count()) { 760c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu info.enabledExtensionCount = override_extensions_.Count(); 761c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu info.ppEnabledExtensionNames = override_extensions_.Names(); 7620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 7640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 765eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::Create(const VkInstanceCreateInfo* create_info, 7660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* allocator, 7670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkInstance* instance_out) { 768eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult result = ValidateExtensions(create_info->ppEnabledExtensionNames, 769eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu create_info->enabledExtensionCount); 7701f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result != VK_SUCCESS) 7711f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return result; 7721f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 7730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // call down the chain 7740c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu PFN_vkCreateInstance create_instance = 7750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu reinterpret_cast<PFN_vkCreateInstance>( 7760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance")); 7770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkInstance instance; 7781f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu result = create_instance(create_info, allocator, &instance); 7790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 7800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 7810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 7820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // initialize InstanceData 7830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu InstanceData& data = GetData(instance); 7840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 7858925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu if (!InitDispatchTable(instance, get_instance_proc_addr_, 7868925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu enabled_extensions_)) { 7870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (data.dispatch.DestroyInstance) 7880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyInstance(instance, allocator); 7890c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 7900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 7910c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 7920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 7930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // install debug report callback 794c3fa20cee7156f9393ff319e0f884705483d3bf8Chia-I Wu if (override_extensions_.InstallDebugCallback()) { 7950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback = 7960c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( 7970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_(instance, 7980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu "vkCreateDebugReportCallbackEXT")); 7990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.destroy_debug_callback = 8000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( 8010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu get_instance_proc_addr_(instance, 8020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu "vkDestroyDebugReportCallbackEXT")); 8030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!create_debug_report_callback || !data.destroy_debug_callback) { 8040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ALOGE("Broken VK_EXT_debug_report support"); 8050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyInstance(instance, allocator); 8060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 8070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 8080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDebugReportCallbackCreateInfoEXT debug_callback_info = {}; 8100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu debug_callback_info.sType = 8110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 8120c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu debug_callback_info.flags = 8130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; 814eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu debug_callback_info.pfnCallback = DebugReportCallback; 8150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDebugReportCallbackEXT debug_callback; 8170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu result = create_debug_report_callback(instance, &debug_callback_info, 8180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu nullptr, &debug_callback); 8190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) { 8200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ALOGE("Failed to install debug report callback"); 8210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyInstance(instance, allocator); 8220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 8230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 8240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.debug_callback = debug_callback; 8260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ALOGI("Installed debug report callback"); 8280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 8290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 830eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu StealLayers(data); 8310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *instance_out = instance; 8330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 8350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 8360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 837eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::Create(VkPhysicalDevice physical_dev, 8380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkDeviceCreateInfo* create_info, 8390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* allocator, 8400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDevice* dev_out) { 8411f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu VkResult result = 842eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu ValidateExtensions(physical_dev, create_info->ppEnabledExtensionNames, 843eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu create_info->enabledExtensionCount); 8441f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result != VK_SUCCESS) 8451f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return result; 8461f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 8470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // call down the chain 848c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu PFN_vkCreateDevice create_device = 849c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu GetData(physical_dev).dispatch.CreateDevice; 8500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDevice dev; 8511f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu result = create_device(physical_dev, create_info, allocator, &dev); 8520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 8530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 8540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // initialize DeviceData 8560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu DeviceData& data = GetData(dev); 8570c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8588925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu if (!InitDispatchTable(dev, get_device_proc_addr_, enabled_extensions_)) { 8590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (data.dispatch.DestroyDevice) 8600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyDevice(dev, allocator); 8610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 8630c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 8640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 865c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // no StealLayers so that active layers are destroyed with this 866c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // LayerChain 8670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *dev_out = dev; 8680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 8690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_SUCCESS; 8700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 8710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 872eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::ValidateExtensions(const char* const* extension_names, 873eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count) { 8741f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (!extension_count) 8751f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_SUCCESS; 8761f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 8771f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu // query driver instance extensions 8781f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu uint32_t count; 8791f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu VkResult result = 8801f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu EnumerateInstanceExtensionProperties(nullptr, &count, nullptr); 8811f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result == VK_SUCCESS && count) { 882eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu driver_extensions_ = AllocateDriverExtensionArray(count); 8831f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu result = (driver_extensions_) ? EnumerateInstanceExtensionProperties( 8841f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu nullptr, &count, driver_extensions_) 8851f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu : VK_ERROR_OUT_OF_HOST_MEMORY; 8861f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 8871f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result != VK_SUCCESS) 8881f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return result; 8891f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 8901f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu driver_extension_count_ = count; 8911f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 8921f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu for (uint32_t i = 0; i < extension_count; i++) { 8931f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu const char* name = extension_names[i]; 894eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu if (!IsLayerExtension(name) && !IsDriverExtension(name)) { 895a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu logger_.Err(VK_NULL_HANDLE, 896a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu "Failed to enable missing instance extension %s", name); 8971f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_ERROR_EXTENSION_NOT_PRESENT; 8981f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 8998925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu 9008925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu auto ext_bit = driver::GetProcHookExtension(name); 9018925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN) 9028925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu enabled_extensions_.set(ext_bit); 9031f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9041f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9051f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_SUCCESS; 9061f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu} 9071f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 908eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::ValidateExtensions(VkPhysicalDevice physical_dev, 909eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* const* extension_names, 910eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t extension_count) { 9111f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (!extension_count) 9121f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_SUCCESS; 9131f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9141f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu // query driver device extensions 9151f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu uint32_t count; 9161f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr, 9171f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu &count, nullptr); 9181f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result == VK_SUCCESS && count) { 919eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu driver_extensions_ = AllocateDriverExtensionArray(count); 9201f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu result = (driver_extensions_) 9211f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu ? EnumerateDeviceExtensionProperties( 9221f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu physical_dev, nullptr, &count, driver_extensions_) 9231f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu : VK_ERROR_OUT_OF_HOST_MEMORY; 9241f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9251f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (result != VK_SUCCESS) 9261f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return result; 9271f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9281f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu driver_extension_count_ = count; 9291f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9301f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu for (uint32_t i = 0; i < extension_count; i++) { 9311f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu const char* name = extension_names[i]; 932eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu if (!IsLayerExtension(name) && !IsDriverExtension(name)) { 933a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu logger_.Err(physical_dev, 934a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu "Failed to enable missing device extension %s", name); 9351f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_ERROR_EXTENSION_NOT_PRESENT; 9361f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9378925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu 9388925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu auto ext_bit = driver::GetProcHookExtension(name); 9398925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN) 9408925efd0a87d96885834a00f3bdef220edf6d8eaChia-I Wu enabled_extensions_.set(ext_bit); 9411f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9421f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9431f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return VK_SUCCESS; 9441f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu} 9451f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 946eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkExtensionProperties* LayerChain::AllocateDriverExtensionArray( 9471f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu uint32_t count) const { 9481f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation( 9491f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu allocator_.pUserData, sizeof(VkExtensionProperties) * count, 9501f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu alignof(VkExtensionProperties), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); 9511f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu} 9521f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 953eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wubool LayerChain::IsLayerExtension(const char* name) const { 954dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu if (is_instance_) { 955dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu for (uint32_t i = 0; i < layer_count_; i++) { 956dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const ActiveLayer& layer = layers_[i]; 957dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu if (FindLayerInstanceExtension(*layer.ref, name)) 958dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return true; 959dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu } 960dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu } else { 961dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu for (uint32_t i = 0; i < layer_count_; i++) { 962dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const ActiveLayer& layer = layers_[i]; 963dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu if (FindLayerDeviceExtension(*layer.ref, name)) 964dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return true; 965dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu } 9661f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9671f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9681f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return false; 9691f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu} 9701f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 971eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wubool LayerChain::IsDriverExtension(const char* name) const { 9721f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu for (uint32_t i = 0; i < driver_extension_count_; i++) { 9731f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu if (strcmp(driver_extensions_[i].extensionName, name) == 0) 9741f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return true; 9751f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu } 9761f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9771f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu return false; 9781f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu} 9791f8f46bbccce0f1aabe7f12a6a26d772cd17b5b7Chia-I Wu 9800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wutemplate <typename DataType> 981eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::StealLayers(DataType& data) { 9820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.layers = layers_; 9830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.layer_count = layer_count_; 9840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 9850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layers_ = nullptr; 9860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layer_count_ = 0; 9870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 9880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 989eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::DestroyLayers(ActiveLayer* layers, 990eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint32_t count, 991eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks& allocator) { 9920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu for (uint32_t i = 0; i < count; i++) 9930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu layers[i].ref.~LayerRef(); 9940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 9950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu allocator.pfnFree(allocator.pUserData, layers); 9960c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 9970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 99894a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I WuVkResult LayerChain::SetInstanceLoaderData(VkInstance instance, void* object) { 99994a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu driver::InstanceDispatchable dispatchable = 100094a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu reinterpret_cast<driver::InstanceDispatchable>(object); 100194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu 100294a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu return (driver::SetDataInternal(dispatchable, &driver::GetData(instance))) 100394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu ? VK_SUCCESS 100494a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu : VK_ERROR_INITIALIZATION_FAILED; 100594a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu} 100694a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu 100794a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I WuVkResult LayerChain::SetDeviceLoaderData(VkDevice device, void* object) { 100894a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu driver::DeviceDispatchable dispatchable = 100994a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu reinterpret_cast<driver::DeviceDispatchable>(object); 101094a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu 101194a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu return (driver::SetDataInternal(dispatchable, &driver::GetData(device))) 101294a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu ? VK_SUCCESS 101394a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu : VK_ERROR_INITIALIZATION_FAILED; 101494a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu} 101594a2c0ecd4537c52e6b4a3ef9d119dce44627ca8Chia-I Wu 1016eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkBool32 LayerChain::DebugReportCallback(VkDebugReportFlagsEXT flags, 1017eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkDebugReportObjectTypeEXT obj_type, 1018eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu uint64_t obj, 1019eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu size_t location, 1020eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu int32_t msg_code, 1021eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* layer_prefix, 1022eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const char* msg, 1023eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu void* user_data) { 10240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu int prio; 10250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) 10270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio = ANDROID_LOG_ERROR; 10280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | 10290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) 10300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio = ANDROID_LOG_WARN; 10310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) 10320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio = ANDROID_LOG_INFO; 10330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) 10340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio = ANDROID_LOG_DEBUG; 10350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu else 10360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu prio = ANDROID_LOG_UNKNOWN; 10370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg); 10390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (void)obj_type; 10410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (void)obj; 10420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (void)location; 10430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (void)user_data; 10440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return false; 10460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 10470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1048eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::CreateInstance(const VkInstanceCreateInfo* create_info, 1049eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator, 1050eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkInstance* instance_out) { 1051a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu LayerChain chain(true, driver::DebugReportLogger(*create_info), 10520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu (allocator) ? *allocator : driver::GetDefaultAllocator()); 10530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1054eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkResult result = chain.ActivateLayers(create_info->ppEnabledLayerNames, 1055eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu create_info->enabledLayerCount, 1056eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu create_info->ppEnabledExtensionNames, 1057eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu create_info->enabledExtensionCount); 10580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 10590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 10600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // use a local create info when the chain is not empty 10620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkInstanceCreateInfo local_create_info; 1063eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu if (!chain.Empty()) { 10640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu local_create_info = *create_info; 1065eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu chain.ModifyCreateInfo(local_create_info); 10660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu create_info = &local_create_info; 10670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 10680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1069eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu return chain.Create(create_info, allocator, instance_out); 10700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 10710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1072eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I WuVkResult LayerChain::CreateDevice(VkPhysicalDevice physical_dev, 1073eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkDeviceCreateInfo* create_info, 1074eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator, 1075eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu VkDevice* dev_out) { 1076a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu LayerChain chain( 1077a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu false, driver::Logger(physical_dev), 1078a4a0555a168efd2e93f6d8b63de7cdc7aeb61a11Chia-I Wu (allocator) ? *allocator : driver::GetData(physical_dev).allocator); 10790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1080c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkResult result = chain.ActivateLayers( 1081c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu physical_dev, create_info->ppEnabledLayerNames, 1082c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu create_info->enabledLayerCount, create_info->ppEnabledExtensionNames, 1083c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu create_info->enabledExtensionCount); 10840c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (result != VK_SUCCESS) 10850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return result; 10860c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 10870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // use a local create info when the chain is not empty 10880c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDeviceCreateInfo local_create_info; 1089eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu if (!chain.Empty()) { 10900c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu local_create_info = *create_info; 1091eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu chain.ModifyCreateInfo(local_create_info); 10920c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu create_info = &local_create_info; 10930c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 10940c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1095eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu return chain.Create(physical_dev, create_info, allocator, dev_out); 10960c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 10970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1098eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::DestroyInstance(VkInstance instance, 1099eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator) { 11000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu InstanceData& data = GetData(instance); 11010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (data.debug_callback != VK_NULL_HANDLE) 11030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.destroy_debug_callback(instance, data.debug_callback, allocator); 11040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers); 11060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t layer_count = data.layer_count; 11070c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11080c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkAllocationCallbacks local_allocator; 11090c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!allocator) 11100c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu local_allocator = driver::GetData(instance).allocator; 11110c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11120c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // this also destroys InstanceData 11130c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyInstance(instance, allocator); 11140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1115eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu DestroyLayers(layers, layer_count, 1116eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu (allocator) ? *allocator : local_allocator); 11170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1119eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wuvoid LayerChain::DestroyDevice(VkDevice device, 1120eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu const VkAllocationCallbacks* allocator) { 11210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu DeviceData& data = GetData(device); 11220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // this also destroys DeviceData 11230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu data.dispatch.DestroyDevice(device, allocator); 1124c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu} 11250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1126c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wuconst LayerChain::ActiveLayer* LayerChain::GetActiveLayers( 1127c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu VkPhysicalDevice physical_dev, 1128c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t& count) { 1129c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu count = GetData(physical_dev).layer_count; 1130c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu return reinterpret_cast<const ActiveLayer*>(GetData(physical_dev).layers); 11310c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11320c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11330c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu// ---------------------------------------------------------------------------- 11340c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11350c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wubool EnsureInitialized() { 11360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu static std::once_flag once_flag; 11370c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu static bool initialized; 11380c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11390c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::call_once(once_flag, []() { 11400c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (driver::OpenHAL()) { 11410c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu DiscoverLayers(); 11420c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu initialized = true; 11430c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 11440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu }); 11450c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return initialized; 11470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} // anonymous namespace 11500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, 11520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* pAllocator, 11530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkInstance* pInstance) { 11540c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!EnsureInitialized()) 11550c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 11560c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 1157eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu return LayerChain::CreateInstance(pCreateInfo, pAllocator, pInstance); 11580c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11590c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11600c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wuvoid DestroyInstance(VkInstance instance, 11610c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* pAllocator) { 11620c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (instance != VK_NULL_HANDLE) 1163eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu LayerChain::DestroyInstance(instance, pAllocator); 11640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult CreateDevice(VkPhysicalDevice physicalDevice, 11670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkDeviceCreateInfo* pCreateInfo, 11680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const VkAllocationCallbacks* pAllocator, 11690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkDevice* pDevice) { 1170eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu return LayerChain::CreateDevice(physicalDevice, pCreateInfo, pAllocator, 1171eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu pDevice); 11720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11740c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wuvoid DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { 11750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (device != VK_NULL_HANDLE) 1176eef27fa3a0c7d153603b7fd69849fee73a07af5bChia-I Wu LayerChain::DestroyDevice(device, pAllocator); 11770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11780c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount, 11800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkLayerProperties* pProperties) { 11810c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!EnsureInitialized()) 11820c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 11830c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 118425700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu uint32_t count = GetLayerCount(); 11850c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 118625700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu if (!pProperties) { 11870c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *pPropertyCount = count; 118825700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return VK_SUCCESS; 118925700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu } 119025700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu 119125700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu uint32_t copied = std::min(*pPropertyCount, count); 119225700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu for (uint32_t i = 0; i < copied; i++) 119325700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu pProperties[i] = GetLayerProperties(GetLayer(i)); 119425700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu *pPropertyCount = copied; 11950c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 119625700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE; 11970c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 11980c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 11990c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult EnumerateInstanceExtensionProperties( 12000c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char* pLayerName, 12010c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t* pPropertyCount, 12020c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkExtensionProperties* pProperties) { 12030c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!EnsureInitialized()) 12040c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return VK_ERROR_INITIALIZATION_FAILED; 12050c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12060c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (pLayerName) { 120704c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu const Layer* layer = FindLayer(pLayerName); 12086184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu if (!layer) 12096184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 12106184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu 12116184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu uint32_t count; 12126184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu const VkExtensionProperties* props = 12136184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu GetLayerInstanceExtensions(*layer, count); 12140c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12150c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!pProperties || *pPropertyCount > count) 12160c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *pPropertyCount = count; 12170c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (pProperties) 12180c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::copy(props, props + *pPropertyCount, pProperties); 12190c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12200c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS; 12210c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 12220c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12230c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // TODO how about extensions from implicitly enabled layers? 12240c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return vulkan::driver::EnumerateInstanceExtensionProperties( 12250c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu nullptr, pPropertyCount, pProperties); 12260c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 12270c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12280c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, 12290c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t* pPropertyCount, 12300c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkLayerProperties* pProperties) { 1231c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t count; 1232c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu const LayerChain::ActiveLayer* layers = 1233c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu LayerChain::GetActiveLayers(physicalDevice, count); 123425700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu 123525700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu if (!pProperties) { 12360c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *pPropertyCount = count; 123725700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return VK_SUCCESS; 123825700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu } 123925700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu 1240c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu uint32_t copied = std::min(*pPropertyCount, count); 1241c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu for (uint32_t i = 0; i < copied; i++) 1242c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu pProperties[i] = GetLayerProperties(*layers[i].ref); 124325700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu *pPropertyCount = copied; 12440c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 124525700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return (copied == count) ? VK_SUCCESS : VK_INCOMPLETE; 12460c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 12470c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12480c2032490b80178ec823bf22a7f5d08398851cc3Chia-I WuVkResult EnumerateDeviceExtensionProperties( 12490c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkPhysicalDevice physicalDevice, 12500c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const char* pLayerName, 12510c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu uint32_t* pPropertyCount, 12520c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu VkExtensionProperties* pProperties) { 12530c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (pLayerName) { 1254c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // EnumerateDeviceLayerProperties enumerates active layers for 1255c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // backward compatibility. The extension query here should work for 1256c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu // all layers. 125704c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu const Layer* layer = FindLayer(pLayerName); 1258c3a28913b6a95d2faee0db537c48557e04267511Chia-I Wu if (!layer) 12596184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 12606184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu 12616184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu uint32_t count; 12626184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu const VkExtensionProperties* props = 12636184b20d8e2301ecc21f815e1f9c2676c43878d1Chia-I Wu GetLayerDeviceExtensions(*layer, count); 12640c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12650c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (!pProperties || *pPropertyCount > count) 12660c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu *pPropertyCount = count; 12670c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu if (pProperties) 12680c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu std::copy(props, props + *pPropertyCount, pProperties); 12690c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12700c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS; 12710c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu } 12720c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12730c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu // TODO how about extensions from implicitly enabled layers? 12740c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu const InstanceData& data = GetData(physicalDevice); 12750c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu return data.dispatch.EnumerateDeviceExtensionProperties( 12760c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu physicalDevice, nullptr, pPropertyCount, pProperties); 12770c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} 12780c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu 12790c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} // namespace api 12800c2032490b80178ec823bf22a7f5d08398851cc3Chia-I Wu} // namespace vulkan 1281