layers_extensions.cpp revision aa410941d29cba4a3a56e90cb3f0be3f03c76cea
180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall/* 280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * Copyright 2016 The Android Open Source Project 380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * 480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * Licensed under the Apache License, Version 2.0 (the "License"); 580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * you may not use this file except in compliance with the License. 680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * You may obtain a copy of the License at 780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * 880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * http://www.apache.org/licenses/LICENSE-2.0 980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * 1080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * Unless required by applicable law or agreed to in writing, software 1180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * distributed under the License is distributed on an "AS IS" BASIS, 1280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * See the License for the specific language governing permissions and 1480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall * limitations under the License. 1580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall */ 1680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 1780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include "loader.h" 1880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <alloca.h> 1980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dirent.h> 2080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dlfcn.h> 2180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <mutex> 2280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <sys/prctl.h> 2380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <string> 2480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <string.h> 2580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vector> 2680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <log/log.h> 2780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vulkan/vulkan_loader_data.h> 2880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 2980523e2e39c29b06ab40573468dde43a9867f487Jesse Hallusing namespace vulkan; 3080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// TODO(jessehall): This file currently builds up global data structures as it 32aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// loads, and never cleans them up. This means we're doing heap allocations 33aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// without going through an app-provided allocator, but worse, we'll leak those 34aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// allocations if the loader is unloaded. 35aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// 36aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// We should allocate "enough" BSS space, and suballocate from there. Will 37aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// probably want to intern strings, etc., and will need some custom/manual data 38aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// structures. 39aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 40aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// TODO(jessehall): Currently we have separate lists for instance and device 41aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// layers. Most layers are both; we should use one entry for each layer name, 42aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// with a mask saying what kind(s) it is. 43aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 4480523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace vulkan { 4580523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstruct Layer { 4680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall VkLayerProperties properties; 4780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t library_idx; 4880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::vector<VkExtensionProperties> extensions; 4980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 5080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} // namespace vulkan 5180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 5280523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace { 5380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 5480523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstd::mutex g_library_mutex; 5580523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstruct LayerLibrary { 5680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::string path; 5780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall void* dlhandle; 5880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t refcount; 5980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 6080523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstd::vector<LayerLibrary> g_layer_libraries; 61aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallstd::vector<Layer> g_instance_layers; 62aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallstd::vector<Layer> g_device_layers; 6380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 6480523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid AddLayerLibrary(const std::string& path) { 6580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV("examining layer library '%s'", path.c_str()); 6680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 6780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall void* dlhandle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); 6880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!dlhandle) { 6980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGW("failed to load layer library '%s': %s", path.c_str(), dlerror()); 7080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 7180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 7280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 73aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers = 7480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>( 7580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlsym(dlhandle, "vkEnumerateInstanceLayerProperties")); 76aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions = 7780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>( 7880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlsym(dlhandle, "vkEnumerateInstanceExtensionProperties")); 79aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers = 80aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>( 81aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlsym(dlhandle, "vkEnumerateDeviceLayerProperties")); 82aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions = 83aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( 84aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlsym(dlhandle, "vkEnumerateDeviceExtensionProperties")); 85aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (!((enumerate_instance_layers && enumerate_instance_extensions) || 86aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall (enumerate_device_layers && enumerate_device_extensions))) { 87aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGV( 88aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "layer library '%s' has neither instance nor device enumeraion " 89aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "functions", 90aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall path.c_str()); 9180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlclose(dlhandle); 9280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 9380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 9480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 95aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkResult result; 96aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_instance_layers = 0; 97aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_device_layers = 0; 98aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_instance_layers) { 99aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_instance_layers(&num_instance_layers, nullptr); 100aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 101aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 102aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceLayerProperties failed for library '%s': " 103aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "%d", 104aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall path.c_str(), result); 105aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 106aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 107aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 10880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 109aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_layers) { 110aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 111aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall nullptr); 112aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 113aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 114aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 115aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall path.c_str(), result); 116aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 117aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 118aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 11980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 120aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties = static_cast<VkLayerProperties*>(alloca( 121aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall (num_instance_layers + num_device_layers) * sizeof(VkLayerProperties))); 122aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (num_instance_layers > 0) { 123aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_instance_layers(&num_instance_layers, properties); 12480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (result != VK_SUCCESS) { 12580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGW( 126aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceLayerProperties failed for library '%s': " 127aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "%d", 128aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall path.c_str(), result); 12980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlclose(dlhandle); 13080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 13180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 132aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 133aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (num_device_layers > 0) { 134aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 135aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties + num_instance_layers); 13680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (result != VK_SUCCESS) { 13780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGW( 138aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 139aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall path.c_str(), result); 14080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlclose(dlhandle); 14180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 14280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 143aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 144aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 145aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall size_t library_idx = g_layer_libraries.size(); 146aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall size_t prev_num_instance_layers = g_instance_layers.size(); 147aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall size_t prev_num_device_layers = g_device_layers.size(); 148aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.reserve(prev_num_instance_layers + num_instance_layers); 149aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_device_layers.reserve(prev_num_device_layers + num_device_layers); 150aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (size_t i = 0; i < num_instance_layers; i++) { 151aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkLayerProperties& props = properties[i]; 152aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 153aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall Layer layer; 154aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.properties = props; 155aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.library_idx = library_idx; 156aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 157aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_instance_extensions) { 158aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count = 0; 159aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = 160aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall enumerate_instance_extensions(props.layerName, &count, nullptr); 161aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 162aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 163aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceExtensionProperties(%s) failed for " 164aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "library " 165aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "'%s': %d", 166aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall props.layerName, path.c_str(), result); 167aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.resize(prev_num_instance_layers); 168aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 169aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 170aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 171aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.extensions.resize(count); 172aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_instance_extensions(props.layerName, &count, 173aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.extensions.data()); 174aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 175aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 176aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceExtensionProperties(%s) failed for " 177aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "library " 178aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "'%s': %d", 179aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall props.layerName, path.c_str(), result); 180aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.resize(prev_num_instance_layers); 181aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 182aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 183aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 184aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 18580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 186aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.push_back(layer); 187aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGV("added instance layer '%s'", props.layerName); 188aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 189aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (size_t i = 0; i < num_device_layers; i++) { 190aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkLayerProperties& props = properties[num_instance_layers + i]; 191aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 192aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall Layer layer; 193aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.properties = props; 194aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.library_idx = library_idx; 195aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 196aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_extensions) { 197aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count; 198aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_extensions( 199aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VK_NULL_HANDLE, props.layerName, &count, nullptr); 200aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 201aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 202aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 203aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "library " 204aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "'%s': %d", 205aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall props.layerName, path.c_str(), result); 206aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.resize(prev_num_instance_layers); 207aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_device_layers.resize(prev_num_device_layers); 208aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 209aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 210aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 211aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.extensions.resize(count); 212aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = 213aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall enumerate_device_extensions(VK_NULL_HANDLE, props.layerName, 214aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall &count, layer.extensions.data()); 215aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 216aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 217aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 218aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "library " 219aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "'%s': %d", 220aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall props.layerName, path.c_str(), result); 221aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_instance_layers.resize(prev_num_instance_layers); 222aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_device_layers.resize(prev_num_device_layers); 223aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall dlclose(dlhandle); 224aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return; 225aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 226aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 227aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 228aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall g_device_layers.push_back(layer); 229aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGV("added device layer '%s'", props.layerName); 23080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 23180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 23280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlclose(dlhandle); 23380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 23480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall g_layer_libraries.push_back(LayerLibrary{path, nullptr, 0}); 23580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 23680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 23780523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid DiscoverLayersInDirectory(const std::string& dir_path) { 23880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV("looking for layers in '%s'", dir_path.c_str()); 23980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 24080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall DIR* directory = opendir(dir_path.c_str()); 24180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!directory) { 24280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall int err = errno; 24380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV_IF(err != ENOENT, "failed to open layer directory '%s': %s (%d)", 24480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dir_path.c_str(), strerror(err), err); 24580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 24680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 24780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 24880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::string path; 24980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.reserve(dir_path.size() + 20); 25080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(dir_path); 25180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append("/"); 25280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 25380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall struct dirent* entry; 25480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall while ((entry = readdir(directory))) { 25580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t libname_len = strlen(entry->d_name); 256a7ac76df54c30e771ecfd05cdd2b52209af71470Jesse Hall if (strncmp(entry->d_name, "libVkLayer", 10) != 0 || 25780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strncmp(entry->d_name + libname_len - 3, ".so", 3) != 0) 25880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall continue; 25980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(entry->d_name); 26080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall AddLayerLibrary(path); 26180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.resize(dir_path.size() + 1); 26280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 26380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 26480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall closedir(directory); 26580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 26680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 26780523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid* GetLayerGetProcAddr(const Layer& layer, 26880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const char* gpa_name, 26980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t gpa_name_len) { 27080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const LayerLibrary& library = g_layer_libraries[layer.library_idx]; 27180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall void* gpa; 27230ac78b43ce408eb6d666c8667d184b8e44ed9e6Jesse Hall size_t layer_name_len = std::max(size_t{2}, strlen(layer.properties.layerName)); 27380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1)); 27480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strcpy(name, layer.properties.layerName); 27580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strcpy(name + layer_name_len, gpa_name); 27680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!(gpa = dlsym(library.dlhandle, name))) { 27780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strcpy(name, "vk"); 27880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strcpy(name + 2, gpa_name); 27980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall gpa = dlsym(library.dlhandle, name); 28080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 28180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return gpa; 28280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 28380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 284aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateLayers(const std::vector<Layer>& layers, 285aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count, 286aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 287aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t n = std::min(count, static_cast<uint32_t>(layers.size())); 28880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall for (uint32_t i = 0; i < n; i++) { 289aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties[i] = layers[i].properties; 29080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 291aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return static_cast<uint32_t>(layers.size()); 29280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 29380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 294aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetLayerExtensions(const std::vector<Layer>& layers, 295aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const char* name, 29680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const VkExtensionProperties** properties, 29780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall uint32_t* count) { 298aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall auto layer = 299aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall std::find_if(layers.cbegin(), layers.cend(), [=](const Layer& entry) { 300aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return strcmp(entry.properties.layerName, name) == 0; 301aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall }); 302aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (layer == layers.cend()) { 303aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *properties = nullptr; 304aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *count = 0; 305aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } else { 306aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *properties = layer->extensions.data(); 307aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *count = static_cast<uint32_t>(layer->extensions.size()); 30880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 30980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 31080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 311aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetLayerRef(std::vector<Layer>& layers, const char* name) { 312aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (uint32_t id = 0; id < layers.size(); id++) { 313aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (strcmp(name, layers[id].properties.layerName) != 0) { 314aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall LayerLibrary& library = g_layer_libraries[layers[id].library_idx]; 31580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::lock_guard<std::mutex> lock(g_library_mutex); 31680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (library.refcount++ == 0) { 31780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall library.dlhandle = 31880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlopen(library.path.c_str(), RTLD_NOW | RTLD_LOCAL); 31980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!library.dlhandle) { 32080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGE("failed to load layer library '%s': %s", 32180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall library.path.c_str(), dlerror()); 32280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall library.refcount = 0; 32380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return LayerRef(nullptr); 32480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 32580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 326aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return LayerRef(&layers[id]); 32780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 32880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 32980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return LayerRef(nullptr); 33080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 33180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 332aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} // anonymous namespace 333aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 334aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallnamespace vulkan { 335aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 336aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid DiscoverLayers() { 337aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) 338aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory("/data/local/debug/vulkan"); 339aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (!LoaderData::GetInstance().layer_path.empty()) 340aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory(LoaderData::GetInstance().layer_path.c_str()); 341aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 342aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 343aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateInstanceLayers(uint32_t count, 344aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 345aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_instance_layers, count, properties); 346aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 347aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 348aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties) { 349aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_device_layers, count, properties); 350aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 351aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 352aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetInstanceLayerExtensions(const char* name, 353aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 354aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 355aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_instance_layers, name, properties, count); 356aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 357aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 358aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetDeviceLayerExtensions(const char* name, 359aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 360aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 361aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_device_layers, name, properties, count); 362aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 363aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 364aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetInstanceLayerRef(const char* name) { 365aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_instance_layers, name); 366aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 367aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 368aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetDeviceLayerRef(const char* name) { 369aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_device_layers, name); 370aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 371aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 37280523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::LayerRef(Layer* layer) : layer_(layer) {} 37380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 37480523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::~LayerRef() { 37580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (layer_) { 37680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall LayerLibrary& library = g_layer_libraries[layer_->library_idx]; 37780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::lock_guard<std::mutex> lock(g_library_mutex); 37880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (--library.refcount == 0) { 37980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dlclose(library.dlhandle); 38080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall library.dlhandle = nullptr; 38180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 38280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 38380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 38480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 38580523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::LayerRef(LayerRef&& other) : layer_(std::move(other.layer_)) {} 38680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 38780523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const { 38880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>( 38980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr", 19)) 39080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 39180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 39280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 39380523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const { 39480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>( 39580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr", 17)) 39680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 39780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 39880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 3996bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse HallInstanceExtension InstanceExtensionFromName(const char* name) { 4006bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) 4016bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall return kKHR_surface; 4026bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall if (strcmp(name, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) 4036bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall return kKHR_android_surface; 4046bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall if (strcmp(name, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) 4056bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall return kEXT_debug_report; 4066bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall return kInstanceExtensionCount; 4076bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall} 4086bd5dfa9b94d1f1b2d9b6bae52979502c44c2847Jesse Hall 40980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} // namespace vulkan 410