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 17c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu#include "layers_extensions.h" 181a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 1980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <alloca.h> 2080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dirent.h> 2180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dlfcn.h> 22a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <string.h> 2380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <sys/prctl.h> 24a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn 25a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <mutex> 2680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <string> 2780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vector> 281a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 2940c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall#include <android/dlext.h> 30a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <android-base/strings.h> 311a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall#include <cutils/properties.h> 327823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 331a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall#include <ziparchive/zip_archive.h> 341a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 3580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vulkan/vulkan_loader_data.h> 3680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 37b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// TODO(jessehall): The whole way we deal with extensions is pretty hokey, and 38b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// not a good long-term solution. Having a hard-coded enum of extensions is 39b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// bad, of course. Representing sets of extensions (requested, supported, etc.) 40b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// as a bitset isn't necessarily bad, if the mapping from extension to bit were 41b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// dynamic. Need to rethink this completely when there's a little more time. 42b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall 43aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// TODO(jessehall): This file currently builds up global data structures as it 44aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// loads, and never cleans them up. This means we're doing heap allocations 45aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// without going through an app-provided allocator, but worse, we'll leak those 46aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// allocations if the loader is unloaded. 47aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// 48aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// We should allocate "enough" BSS space, and suballocate from there. Will 49aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// probably want to intern strings, etc., and will need some custom/manual data 50aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// structures. 51aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 5280523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace vulkan { 53c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wunamespace api { 54c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu 5580523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstruct Layer { 5680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall VkLayerProperties properties; 5780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t library_idx; 58bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu 5925700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu // true if the layer intercepts vkCreateDevice and device commands 60bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu bool is_global; 61bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu 62bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu std::vector<VkExtensionProperties> instance_extensions; 63bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu std::vector<VkExtensionProperties> device_extensions; 6480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 6580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 6680523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace { 6780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 681a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hallconst char kSystemLayerLibraryDir[] = "/data/local/debug/vulkan"; 691a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 706693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wuclass LayerLibrary { 716693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu public: 72c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit LayerLibrary(const std::string& path) 736693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu : path_(path), dlhandle_(nullptr), refcount_(0) {} 74743495943b1a0b6d81ac70df524f67041f116ba6Chia-I Wu 7550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary(LayerLibrary&& other) 766693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu : path_(std::move(other.path_)), 776693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlhandle_(other.dlhandle_), 786693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu refcount_(other.refcount_) { 796693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu other.dlhandle_ = nullptr; 806693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu other.refcount_ = 0; 8150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu } 8250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 8350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary(const LayerLibrary&) = delete; 8450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary& operator=(const LayerLibrary&) = delete; 8550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 86a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu // these are thread-safe 87fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu bool Open(); 88d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu void Close(); 89fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu 9050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu bool EnumerateLayers(size_t library_idx, 91bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu std::vector<Layer>& instance_layers) const; 9250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 93ba113275287a2293136d8737bf364651ea0b576dChia-I Wu void* GetGPA(const Layer& layer, 94ba113275287a2293136d8737bf364651ea0b576dChia-I Wu const char* gpa_name, 95ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t gpa_name_len) const; 96ba113275287a2293136d8737bf364651ea0b576dChia-I Wu 976693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu private: 986693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu const std::string path_; 99a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu 100a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::mutex mutex_; 1016693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu void* dlhandle_; 1026693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu size_t refcount_; 10380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 104743495943b1a0b6d81ac70df524f67041f116ba6Chia-I Wu 105fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wubool LayerLibrary::Open() { 106a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::lock_guard<std::mutex> lock(mutex_); 1076693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (refcount_++ == 0) { 1081a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGV("opening layer library '%s'", path_.c_str()); 10940c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall // Libraries in the system layer library dir can't be loaded into 11040c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall // the application namespace. That causes compatibility problems, since 11140c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall // any symbol dependencies will be resolved by system libraries. They 11240c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall // can't safely use libc++_shared, for example. Which is one reason 11340c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall // (among several) we only allow them in non-user builds. 11440c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall auto app_namespace = LoaderData::GetInstance().app_namespace; 11540c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall if (app_namespace && 11640c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall !android::base::StartsWith(path_, kSystemLayerLibraryDir)) { 11740c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall android_dlextinfo dlextinfo = {}; 11840c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall dlextinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; 11940c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall dlextinfo.library_namespace = app_namespace; 12040c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall dlhandle_ = android_dlopen_ext(path_.c_str(), RTLD_NOW | RTLD_LOCAL, 12140c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall &dlextinfo); 12240c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall } else { 12340c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); 12440c07a1d002561fc8db987ec30d890b041fb6336Jesse Hall } 1256693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (!dlhandle_) { 1266693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGE("failed to load layer library '%s': %s", path_.c_str(), 127fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu dlerror()); 1286693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu refcount_ = 0; 129fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu return false; 130fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu } 131fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu } 132fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu return true; 133fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu} 134fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu 135d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wuvoid LayerLibrary::Close() { 136a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::lock_guard<std::mutex> lock(mutex_); 1376693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (--refcount_ == 0) { 1381a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGV("closing layer library '%s'", path_.c_str()); 1396693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlclose(dlhandle_); 1406693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlhandle_ = nullptr; 141d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu } 142d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu} 143d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu 14450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wubool LayerLibrary::EnumerateLayers(size_t library_idx, 145bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu std::vector<Layer>& instance_layers) const { 146aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers = 14780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>( 1486693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateInstanceLayerProperties")); 149aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions = 15080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>( 1516693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateInstanceExtensionProperties")); 1525f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (!enumerate_instance_layers || !enumerate_instance_extensions) { 1531a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE("layer library '%s' missing some instance enumeration functions", 1545f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu path_.c_str()); 1555f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 1565f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu } 1575f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu 1585f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // device functions are optional 159aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers = 160aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>( 1616693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateDeviceLayerProperties")); 162aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions = 163aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( 1646693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateDeviceExtensionProperties")); 16580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 1665f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // get layer counts 167aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_instance_layers = 0; 168aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_device_layers = 0; 1695f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu VkResult result = enumerate_instance_layers(&num_instance_layers, nullptr); 1705f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS || !num_instance_layers) { 171aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 1721a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 173aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceLayerProperties failed for library '%s': " 174aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "%d", 1756693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 176aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 1775f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 17880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 179aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_layers) { 180aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 181aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall nullptr); 182aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 1831a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 184aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 1856693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 18650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 187aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 18880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 1895f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu 1905f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // get layer properties 191aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties = static_cast<VkLayerProperties*>(alloca( 192aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall (num_instance_layers + num_device_layers) * sizeof(VkLayerProperties))); 1935f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu result = enumerate_instance_layers(&num_instance_layers, properties); 1945f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 1951a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE("vkEnumerateInstanceLayerProperties failed for library '%s': %d", 1965f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu path_.c_str(), result); 1975f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 198aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 199aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (num_device_layers > 0) { 200aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 201aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties + num_instance_layers); 20280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (result != VK_SUCCESS) { 2031a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 204aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 2056693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 20650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 20780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 208aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 209aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 210bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu // append layers to instance_layers 21150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu size_t prev_num_instance_layers = instance_layers.size(); 21250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.reserve(prev_num_instance_layers + num_instance_layers); 213aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (size_t i = 0; i < num_instance_layers; i++) { 214aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkLayerProperties& props = properties[i]; 215aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 216aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall Layer layer; 217aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.properties = props; 218aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.library_idx = library_idx; 219bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu layer.is_global = false; 220aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 2215f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu uint32_t count = 0; 2225f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu result = 2235f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu enumerate_instance_extensions(props.layerName, &count, nullptr); 2245f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 2251a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 2261a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "vkEnumerateInstanceExtensionProperties(\"%s\") failed for " 2271a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "library '%s': %d", 2285f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu props.layerName, path_.c_str(), result); 2295f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu instance_layers.resize(prev_num_instance_layers); 2305f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 2315f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu } 232bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu layer.instance_extensions.resize(count); 233bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu result = enumerate_instance_extensions( 234bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu props.layerName, &count, layer.instance_extensions.data()); 2355f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 2361a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 2371a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "vkEnumerateInstanceExtensionProperties(\"%s\") failed for " 2381a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "library '%s': %d", 2395f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu props.layerName, path_.c_str(), result); 2405f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu instance_layers.resize(prev_num_instance_layers); 2415f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 242aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 24380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 244279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu for (size_t j = 0; j < num_device_layers; j++) { 245279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu const auto& dev_props = properties[num_instance_layers + j]; 246279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu if (memcmp(&props, &dev_props, sizeof(props)) == 0) { 247bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu layer.is_global = true; 248279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu break; 249279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu } 250279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu } 251279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu 252bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu if (layer.is_global && enumerate_device_extensions) { 253aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_extensions( 254aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VK_NULL_HANDLE, props.layerName, &count, nullptr); 255aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 2561a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 2571a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "vkEnumerateDeviceExtensionProperties(\"%s\") failed for " 25850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2596693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 26050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 26150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 262aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 263bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu layer.device_extensions.resize(count); 264bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu result = enumerate_device_extensions( 265bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu VK_NULL_HANDLE, props.layerName, &count, 266bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu layer.device_extensions.data()); 267aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 2681a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE( 2691a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall "vkEnumerateDeviceExtensionProperties(\"%s\") failed for " 27050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2716693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 27250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 27350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 274aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 275aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 276aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 277bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu instance_layers.push_back(layer); 2781a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGD("added %s layer '%s' from library '%s'", 2791a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall (layer.is_global) ? "global" : "instance", props.layerName, 2801a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall path_.c_str()); 28180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 28280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 28350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return true; 28450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu} 28550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 286ba113275287a2293136d8737bf364651ea0b576dChia-I Wuvoid* LayerLibrary::GetGPA(const Layer& layer, 287ba113275287a2293136d8737bf364651ea0b576dChia-I Wu const char* gpa_name, 288ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t gpa_name_len) const { 289ba113275287a2293136d8737bf364651ea0b576dChia-I Wu void* gpa; 290ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t layer_name_len = 291ba113275287a2293136d8737bf364651ea0b576dChia-I Wu std::max(size_t{2}, strlen(layer.properties.layerName)); 292ba113275287a2293136d8737bf364651ea0b576dChia-I Wu char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1)); 293ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, layer.properties.layerName); 294ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + layer_name_len, gpa_name); 2956693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (!(gpa = dlsym(dlhandle_, name))) { 296ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, "vk"); 297ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + 2, gpa_name); 2986693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu gpa = dlsym(dlhandle_, name); 299ba113275287a2293136d8737bf364651ea0b576dChia-I Wu } 300ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return gpa; 301ba113275287a2293136d8737bf364651ea0b576dChia-I Wu} 302ba113275287a2293136d8737bf364651ea0b576dChia-I Wu 3031a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall// ---------------------------------------------------------------------------- 3041a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 30550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<LayerLibrary> g_layer_libraries; 30650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<Layer> g_instance_layers; 30750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 30850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wuvoid AddLayerLibrary(const std::string& path) { 30950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary library(path); 31050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu if (!library.Open()) 31150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 31250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 313bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu if (!library.EnumerateLayers(g_layer_libraries.size(), g_instance_layers)) { 31450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 31550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 31650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu } 31750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 31850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 31980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 32050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu g_layer_libraries.emplace_back(std::move(library)); 32180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 32280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 3231a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Halltemplate <typename Functor> 3241a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hallvoid ForEachFileInDir(const std::string& dirname, Functor functor) { 3251a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall auto dir_deleter = [](DIR* handle) { closedir(handle); }; 3261a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall std::unique_ptr<DIR, decltype(dir_deleter)> dir(opendir(dirname.c_str()), 3271a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall dir_deleter); 3281a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if (!dir) { 3291a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall // It's normal for some search directories to not exist, especially 3301a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall // /data/local/debug/vulkan. 33180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall int err = errno; 3321a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGW_IF(err != ENOENT, "failed to open layer directory '%s': %s", 3331a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall dirname.c_str(), strerror(err)); 33480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 33580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 3361a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGD("searching for layers in '%s'", dirname.c_str()); 3371a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall dirent* entry; 3381a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall while ((entry = readdir(dir.get())) != nullptr) 3391a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall functor(entry->d_name); 3401a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall} 34180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 3421a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Halltemplate <typename Functor> 3431a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hallvoid ForEachFileInZip(const std::string& zipname, 3441a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall const std::string& dir_in_zip, 3451a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall Functor functor) { 3461a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall int32_t err; 3471a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ZipArchiveHandle zip = nullptr; 3481a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if ((err = OpenArchive(zipname.c_str(), &zip)) != 0) { 3491a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE("failed to open apk '%s': %d", zipname.c_str(), err); 3501a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall return; 3511a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 3521a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall std::string prefix(dir_in_zip + "/"); 3531a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall const ZipString prefix_str(prefix.c_str()); 3541a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall void* iter_cookie = nullptr; 3551a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if ((err = StartIteration(zip, &iter_cookie, &prefix_str, nullptr)) != 0) { 3561a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGE("failed to iterate entries in apk '%s': %d", zipname.c_str(), 3571a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall err); 3581a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall CloseArchive(zip); 3591a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall return; 36080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 3611a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ALOGD("searching for layers in '%s!/%s'", zipname.c_str(), 3621a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall dir_in_zip.c_str()); 3631a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ZipEntry entry; 3641a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ZipString name; 3651a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall while (Next(iter_cookie, &entry, &name) == 0) { 3661a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall std::string filename( 3671a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall reinterpret_cast<const char*>(name.name) + prefix.length(), 3681a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall name.name_length - prefix.length()); 3691a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall // only enumerate direct entries of the directory, not subdirectories 3708c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall if (filename.find('/') != filename.npos) 3718c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall continue; 3728c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall // Check whether it *may* be possible to load the library directly from 3738c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall // the APK. Loading still may fail for other reasons, but this at least 3748c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall // lets us avoid failed-to-load log messages in the typical case of 3758c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall // compressed and/or unaligned libraries. 3768c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall if (entry.method != kCompressStored || entry.offset % PAGE_SIZE != 0) 3778c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall continue; 3788c6c10e20d40066468bf4350b64703e11d5bff10Jesse Hall functor(filename); 3791a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 3801a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall EndIteration(iter_cookie); 3811a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall CloseArchive(zip); 3821a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall} 38380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 3841a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Halltemplate <typename Functor> 3851a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hallvoid ForEachFileInPath(const std::string& path, Functor functor) { 3861a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall size_t zip_pos = path.find("!/"); 3871a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if (zip_pos == std::string::npos) { 3881a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ForEachFileInDir(path, functor); 3891a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } else { 3901a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ForEachFileInZip(path.substr(0, zip_pos), path.substr(zip_pos + 2), 3911a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall functor); 3921a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 3931a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall} 3941a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall 3951a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hallvoid DiscoverLayersInPathList(const std::string& pathstr) { 3961a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall std::vector<std::string> paths = android::base::Split(pathstr, ":"); 3971a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall for (const auto& path : paths) { 3981a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall ForEachFileInPath(path, [&](const std::string& filename) { 3991a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if (android::base::StartsWith(filename, "libVkLayer") && 4001a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall android::base::EndsWith(filename, ".so")) { 4011a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall AddLayerLibrary(path + "/" + filename); 4021a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 4031a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall }); 4041a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 40580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 40680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 407dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wuconst VkExtensionProperties* FindExtension( 408dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const std::vector<VkExtensionProperties>& extensions, 409dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const char* name) { 410dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu auto it = std::find_if(extensions.cbegin(), extensions.cend(), 411dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu [=](const VkExtensionProperties& ext) { 412dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return (strcmp(ext.extensionName, name) == 0); 413dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu }); 414dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return (it != extensions.cend()) ? &*it : nullptr; 415dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu} 416dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu 41780523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid* GetLayerGetProcAddr(const Layer& layer, 41880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const char* gpa_name, 41980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t gpa_name_len) { 42080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const LayerLibrary& library = g_layer_libraries[layer.library_idx]; 421ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return library.GetGPA(layer, gpa_name, gpa_name_len); 42280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 42380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 424aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} // anonymous namespace 425aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 426aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid DiscoverLayers() { 4271a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall if (property_get_bool("ro.debuggable", false) && 4281a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { 4291a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall DiscoverLayersInPathList(kSystemLayerLibraryDir); 4301a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall } 431aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (!LoaderData::GetInstance().layer_path.empty()) 4321a7eb59c2a7907ea4c4925c6d13d66e53fb60339Jesse Hall DiscoverLayersInPathList(LoaderData::GetInstance().layer_path); 433aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 434aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 43525700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wuuint32_t GetLayerCount() { 436bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu return static_cast<uint32_t>(g_instance_layers.size()); 437aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 438aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 43925700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wuconst Layer& GetLayer(uint32_t index) { 44025700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return g_instance_layers[index]; 44125700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu} 442bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu 44304c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wuconst Layer* FindLayer(const char* name) { 44404c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu auto layer = 44504c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu std::find_if(g_instance_layers.cbegin(), g_instance_layers.cend(), 44604c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu [=](const Layer& entry) { 44704c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu return strcmp(entry.properties.layerName, name) == 0; 44804c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu }); 44904c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu return (layer != g_instance_layers.cend()) ? &*layer : nullptr; 45004c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu} 45104c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu 45225700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wuconst VkLayerProperties& GetLayerProperties(const Layer& layer) { 45325700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return layer.properties; 45425700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu} 455bea09db9c2165f06771f3a3da423f4f85ac6347eChia-I Wu 45625700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wubool IsLayerGlobal(const Layer& layer) { 45725700b452535ce7ae838bfe832392b46ed555ed2Chia-I Wu return layer.is_global; 458aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 459aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 46004c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wuconst VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer, 46104c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu uint32_t& count) { 46204c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu count = static_cast<uint32_t>(layer.instance_extensions.size()); 46304c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu return layer.instance_extensions.data(); 464aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 465aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 46604c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wuconst VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer, 46704c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu uint32_t& count) { 46804c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu count = static_cast<uint32_t>(layer.device_extensions.size()); 46904c6551eb812a7efe38fa74e6ac67c17aab3df2dChia-I Wu return layer.device_extensions.data(); 470aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 471aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 472dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wuconst VkExtensionProperties* FindLayerInstanceExtension(const Layer& layer, 473dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const char* name) { 474dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return FindExtension(layer.instance_extensions, name); 475aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 476aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 477dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wuconst VkExtensionProperties* FindLayerDeviceExtension(const Layer& layer, 478dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu const char* name) { 479dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return FindExtension(layer.device_extensions, name); 480dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu} 481dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu 482dab25658fb17ec76569b8e91dfed801855027f08Chia-I WuLayerRef GetLayerRef(const Layer& layer) { 483d6e6f51426c566cd67ed765e5c4b206a063aaa30Chia-I Wu LayerLibrary& library = g_layer_libraries[layer.library_idx]; 484dab25658fb17ec76569b8e91dfed801855027f08Chia-I Wu return LayerRef((library.Open()) ? &layer : nullptr); 485aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 486aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 487dab25658fb17ec76569b8e91dfed801855027f08Chia-I WuLayerRef::LayerRef(const Layer* layer) : layer_(layer) {} 48880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 48980523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::~LayerRef() { 49080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (layer_) { 49180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall LayerLibrary& library = g_layer_libraries[layer_->library_idx]; 492d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu library.Close(); 49380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 49480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 49580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 496dab25658fb17ec76569b8e91dfed801855027f08Chia-I WuLayerRef::LayerRef(LayerRef&& other) : layer_(other.layer_) { 49754e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine other.layer_ = nullptr; 49854e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine} 49980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 50080523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const { 50180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>( 50280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr", 19)) 50380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 50480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 50580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 50680523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const { 50780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>( 50880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr", 17)) 50980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 51080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 51180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 512c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu} // namespace api 51380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} // namespace vulkan 514