layers_extensions.cpp revision 5f093bf18120a5cbf18d0f3e255b2178f524e438
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 17d0b7cb566288a4f6646e356a17188b7922ba5740Michael Lentine// #define LOG_NDEBUG 0 18d0b7cb566288a4f6646e356a17188b7922ba5740Michael Lentine 19c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu#include "layers_extensions.h" 2080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <alloca.h> 2180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dirent.h> 2280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <dlfcn.h> 2380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <mutex> 2480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <sys/prctl.h> 2580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <string> 2680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <string.h> 2780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vector> 2880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <log/log.h> 2980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall#include <vulkan/vulkan_loader_data.h> 3080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// TODO(jessehall): The whole way we deal with extensions is pretty hokey, and 32b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// not a good long-term solution. Having a hard-coded enum of extensions is 33b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// bad, of course. Representing sets of extensions (requested, supported, etc.) 34b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// as a bitset isn't necessarily bad, if the mapping from extension to bit were 35b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall// dynamic. Need to rethink this completely when there's a little more time. 36b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall 37aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// TODO(jessehall): This file currently builds up global data structures as it 38aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// loads, and never cleans them up. This means we're doing heap allocations 39aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// without going through an app-provided allocator, but worse, we'll leak those 40aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// allocations if the loader is unloaded. 41aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// 42aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// We should allocate "enough" BSS space, and suballocate from there. Will 43aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// probably want to intern strings, etc., and will need some custom/manual data 44aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// structures. 45aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 46aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// TODO(jessehall): Currently we have separate lists for instance and device 47aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// layers. Most layers are both; we should use one entry for each layer name, 48aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall// with a mask saying what kind(s) it is. 49aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 5080523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace vulkan { 51c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wunamespace api { 52c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu 5380523e2e39c29b06ab40573468dde43a9867f487Jesse Hallstruct Layer { 5480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall VkLayerProperties properties; 5580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t library_idx; 5680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::vector<VkExtensionProperties> extensions; 5780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 5880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 5980523e2e39c29b06ab40573468dde43a9867f487Jesse Hallnamespace { 6080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 616693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wuclass LayerLibrary { 626693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu public: 636693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu LayerLibrary(const std::string& path) 646693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu : path_(path), dlhandle_(nullptr), refcount_(0) {} 65743495943b1a0b6d81ac70df524f67041f116ba6Chia-I Wu 6650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary(LayerLibrary&& other) 676693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu : path_(std::move(other.path_)), 686693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlhandle_(other.dlhandle_), 696693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu refcount_(other.refcount_) { 706693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu other.dlhandle_ = nullptr; 716693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu other.refcount_ = 0; 7250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu } 7350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 7450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary(const LayerLibrary&) = delete; 7550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary& operator=(const LayerLibrary&) = delete; 7650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 77a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu // these are thread-safe 78fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu bool Open(); 79d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu void Close(); 80fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu 8150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu bool EnumerateLayers(size_t library_idx, 8250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu std::vector<Layer>& instance_layers, 8350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu std::vector<Layer>& device_layers) const; 8450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 85ba113275287a2293136d8737bf364651ea0b576dChia-I Wu void* GetGPA(const Layer& layer, 86ba113275287a2293136d8737bf364651ea0b576dChia-I Wu const char* gpa_name, 87ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t gpa_name_len) const; 88ba113275287a2293136d8737bf364651ea0b576dChia-I Wu 896693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu private: 906693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu const std::string path_; 91a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu 92a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::mutex mutex_; 936693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu void* dlhandle_; 946693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu size_t refcount_; 9580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall}; 96743495943b1a0b6d81ac70df524f67041f116ba6Chia-I Wu 97fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wubool LayerLibrary::Open() { 98a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::lock_guard<std::mutex> lock(mutex_); 99a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu 1006693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (refcount_++ == 0) { 1016693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); 1026693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGV("Opening library %s", path_.c_str()); 1036693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (!dlhandle_) { 1046693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGE("failed to load layer library '%s': %s", path_.c_str(), 105fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu dlerror()); 1066693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu refcount_ = 0; 107fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu return false; 108fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu } 109fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu } 1106693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGV("Refcount on activate is %zu", refcount_); 111fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu return true; 112fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu} 113fd0389fb67298e530142566e7a5f6fb16741cabaChia-I Wu 114d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wuvoid LayerLibrary::Close() { 115a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu std::lock_guard<std::mutex> lock(mutex_); 116a6229749aeef225803c6a5411be9e8a40637454dChia-I Wu 1176693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (--refcount_ == 0) { 1186693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGV("Closing library %s", path_.c_str()); 1196693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlclose(dlhandle_); 1206693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlhandle_ = nullptr; 121d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu } 1226693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu ALOGV("Refcount on destruction is %zu", refcount_); 123d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu} 124d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu 12550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wubool LayerLibrary::EnumerateLayers(size_t library_idx, 12650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu std::vector<Layer>& instance_layers, 12750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu std::vector<Layer>& device_layers) const { 128aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers = 12980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>( 1306693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateInstanceLayerProperties")); 131aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions = 13280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>( 1336693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateInstanceExtensionProperties")); 1345f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (!enumerate_instance_layers || !enumerate_instance_extensions) { 1355f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu ALOGV("layer library '%s' misses some instance enumeraion functions", 1365f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu path_.c_str()); 1375f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 1385f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu } 1395f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu 1405f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // device functions are optional 141aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers = 142aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>( 1436693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateDeviceLayerProperties")); 144aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions = 145aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( 1466693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu dlsym(dlhandle_, "vkEnumerateDeviceExtensionProperties")); 14780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 1485f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // get layer counts 149aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_instance_layers = 0; 150aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t num_device_layers = 0; 1515f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu VkResult result = enumerate_instance_layers(&num_instance_layers, nullptr); 1525f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS || !num_instance_layers) { 153aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 154aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 155aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateInstanceLayerProperties failed for library '%s': " 156aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "%d", 1576693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 158aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 1595f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 16080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 161aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_layers) { 162aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 163aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall nullptr); 164aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 165aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 166aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 1676693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 16850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 169aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 17080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 1715f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu 1725f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // get layer properties 173aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties = static_cast<VkLayerProperties*>(alloca( 174aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall (num_instance_layers + num_device_layers) * sizeof(VkLayerProperties))); 1755f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu result = enumerate_instance_layers(&num_instance_layers, properties); 1765f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 1775f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu ALOGW("vkEnumerateInstanceLayerProperties failed for library '%s': %d", 1785f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu path_.c_str(), result); 1795f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 180aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 181aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (num_device_layers > 0) { 182aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers, 183aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties + num_instance_layers); 18480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (result != VK_SUCCESS) { 18580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGW( 186aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceLayerProperties failed for library '%s': %d", 1876693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu path_.c_str(), result); 18850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 18980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 190aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 191aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 1925f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu // append layers to instance_layers/device_layers 19350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu size_t prev_num_instance_layers = instance_layers.size(); 19450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu size_t prev_num_device_layers = device_layers.size(); 19550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.reserve(prev_num_instance_layers + num_instance_layers); 19650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.reserve(prev_num_device_layers + num_device_layers); 197aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (size_t i = 0; i < num_instance_layers; i++) { 198aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkLayerProperties& props = properties[i]; 199aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 200aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall Layer layer; 201aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.properties = props; 202aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.library_idx = library_idx; 203aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 2045f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu uint32_t count = 0; 2055f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu result = 2065f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu enumerate_instance_extensions(props.layerName, &count, nullptr); 2075f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 2085f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu ALOGW( 2095f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu "vkEnumerateInstanceExtensionProperties(%s) failed for library " 2105f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu "'%s': %d", 2115f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu props.layerName, path_.c_str(), result); 2125f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu instance_layers.resize(prev_num_instance_layers); 2135f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 2145f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu } 2155f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu layer.extensions.resize(count); 2165f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu result = enumerate_instance_extensions(props.layerName, &count, 2175f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu layer.extensions.data()); 2185f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu if (result != VK_SUCCESS) { 2195f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu ALOGW( 2205f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu "vkEnumerateInstanceExtensionProperties(%s) failed for library " 2215f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu "'%s': %d", 2225f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu props.layerName, path_.c_str(), result); 2235f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu instance_layers.resize(prev_num_instance_layers); 2245f093bf18120a5cbf18d0f3e255b2178f524e438Chia-I Wu return false; 225aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 22680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 22750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.push_back(layer); 228b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall ALOGV(" added instance layer '%s'", props.layerName); 229aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 230aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall for (size_t i = 0; i < num_device_layers; i++) { 231aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkLayerProperties& props = properties[num_instance_layers + i]; 232aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 233aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall Layer layer; 234aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.properties = props; 235aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.library_idx = library_idx; 236aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 237aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_extensions) { 238aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count; 239aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_extensions( 240aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VK_NULL_HANDLE, props.layerName, &count, nullptr); 241aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 242aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 243aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 24450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2456693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 24650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 24750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.resize(prev_num_device_layers); 24850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 249aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 250aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.extensions.resize(count); 251aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = 252aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall enumerate_device_extensions(VK_NULL_HANDLE, props.layerName, 253aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall &count, layer.extensions.data()); 254aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 255aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 256aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 25750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2586693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 25950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 26050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.resize(prev_num_device_layers); 26150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 262aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 263aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 264aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 26550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.push_back(layer); 266b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall ALOGV(" added device layer '%s'", props.layerName); 26780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 26880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 26950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return true; 27050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu} 27150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 272ba113275287a2293136d8737bf364651ea0b576dChia-I Wuvoid* LayerLibrary::GetGPA(const Layer& layer, 273ba113275287a2293136d8737bf364651ea0b576dChia-I Wu const char* gpa_name, 274ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t gpa_name_len) const { 275ba113275287a2293136d8737bf364651ea0b576dChia-I Wu void* gpa; 276ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t layer_name_len = 277ba113275287a2293136d8737bf364651ea0b576dChia-I Wu std::max(size_t{2}, strlen(layer.properties.layerName)); 278ba113275287a2293136d8737bf364651ea0b576dChia-I Wu char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1)); 279ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, layer.properties.layerName); 280ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + layer_name_len, gpa_name); 2816693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (!(gpa = dlsym(dlhandle_, name))) { 282ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, "vk"); 283ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + 2, gpa_name); 2846693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu gpa = dlsym(dlhandle_, name); 285ba113275287a2293136d8737bf364651ea0b576dChia-I Wu } 286ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return gpa; 287ba113275287a2293136d8737bf364651ea0b576dChia-I Wu} 288ba113275287a2293136d8737bf364651ea0b576dChia-I Wu 28950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<LayerLibrary> g_layer_libraries; 29050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<Layer> g_instance_layers; 29150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<Layer> g_device_layers; 29250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 29350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wuvoid AddLayerLibrary(const std::string& path) { 29450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu ALOGV("examining layer library '%s'", path.c_str()); 29550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 29650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary library(path); 29750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu if (!library.Open()) 29850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 29950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 30050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu if (!library.EnumerateLayers(g_layer_libraries.size(), g_instance_layers, 30150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu g_device_layers)) { 30250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 30350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 30450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu } 30550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 30650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 30780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 30850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu g_layer_libraries.emplace_back(std::move(library)); 30980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 31080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31180523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid DiscoverLayersInDirectory(const std::string& dir_path) { 31280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV("looking for layers in '%s'", dir_path.c_str()); 31380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall DIR* directory = opendir(dir_path.c_str()); 31580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!directory) { 31680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall int err = errno; 31780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV_IF(err != ENOENT, "failed to open layer directory '%s': %s (%d)", 31880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dir_path.c_str(), strerror(err), err); 31980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 32080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 32180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 32280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::string path; 32380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.reserve(dir_path.size() + 20); 32480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(dir_path); 32580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append("/"); 32680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 32780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall struct dirent* entry; 32880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall while ((entry = readdir(directory))) { 32980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t libname_len = strlen(entry->d_name); 330a7ac76df54c30e771ecfd05cdd2b52209af71470Jesse Hall if (strncmp(entry->d_name, "libVkLayer", 10) != 0 || 33180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strncmp(entry->d_name + libname_len - 3, ".so", 3) != 0) 33280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall continue; 33380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(entry->d_name); 33480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall AddLayerLibrary(path); 33580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.resize(dir_path.size() + 1); 33680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 33780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 33880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall closedir(directory); 33980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 34080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 34150db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wuconst Layer* FindLayer(const std::vector<Layer>& layers, const char* name) { 34250db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu auto layer = 34350db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu std::find_if(layers.cbegin(), layers.cend(), [=](const Layer& entry) { 34450db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return strcmp(entry.properties.layerName, name) == 0; 34550db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu }); 34650db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return (layer != layers.cend()) ? &*layer : nullptr; 34750db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu} 34850db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu 34980523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid* GetLayerGetProcAddr(const Layer& layer, 35080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const char* gpa_name, 35180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t gpa_name_len) { 35280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const LayerLibrary& library = g_layer_libraries[layer.library_idx]; 353ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return library.GetGPA(layer, gpa_name, gpa_name_len); 35480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 35580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 356aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateLayers(const std::vector<Layer>& layers, 357aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count, 358aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 359aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t n = std::min(count, static_cast<uint32_t>(layers.size())); 36080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall for (uint32_t i = 0; i < n; i++) { 361aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties[i] = layers[i].properties; 36280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 363aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return static_cast<uint32_t>(layers.size()); 36480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 36580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 366aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetLayerExtensions(const std::vector<Layer>& layers, 367aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const char* name, 36880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const VkExtensionProperties** properties, 36980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall uint32_t* count) { 37050db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu const Layer* layer = FindLayer(layers, name); 37150db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (layer) { 372aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *properties = layer->extensions.data(); 373aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *count = static_cast<uint32_t>(layer->extensions.size()); 37450db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu } else { 37550db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu *properties = nullptr; 37650db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu *count = 0; 37780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 37880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 37980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 380aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetLayerRef(std::vector<Layer>& layers, const char* name) { 38150db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu const Layer* layer = FindLayer(layers, name); 38250db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (layer) { 38350db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu LayerLibrary& library = g_layer_libraries[layer->library_idx]; 38450db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (!library.Open()) 38550db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu layer = nullptr; 38680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 38750db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu 38850db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return LayerRef(layer); 38980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 39080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 391aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} // anonymous namespace 392aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 393aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid DiscoverLayers() { 394aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) 395aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory("/data/local/debug/vulkan"); 396aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (!LoaderData::GetInstance().layer_path.empty()) 397aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory(LoaderData::GetInstance().layer_path.c_str()); 398aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 399aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 400aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateInstanceLayers(uint32_t count, 401aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 402aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_instance_layers, count, properties); 403aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 404aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 405aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties) { 406aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_device_layers, count, properties); 407aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 408aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 409aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetInstanceLayerExtensions(const char* name, 410aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 411aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 412aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_instance_layers, name, properties, count); 413aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 414aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 415aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetDeviceLayerExtensions(const char* name, 416aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 417aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 418aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_device_layers, name, properties, count); 419aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 420aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 421aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetInstanceLayerRef(const char* name) { 422aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_instance_layers, name); 423aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 424aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 425aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetDeviceLayerRef(const char* name) { 426aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_device_layers, name); 427aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 428aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 42983506d84d00bbb35ecebb44261b2139bc40ef3e2Chia-I WuLayerRef::LayerRef(const Layer* layer) : layer_(layer) {} 43080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 43180523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::~LayerRef() { 43280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (layer_) { 43380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall LayerLibrary& library = g_layer_libraries[layer_->library_idx]; 434d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu library.Close(); 43580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 43680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 43780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 4385703683fb645a7e31ac25aaf7136013a6a9b9fbcMichael Lentineconst char* LayerRef::GetName() const { 439eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter return layer_->properties.layerName; 440eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter} 441eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter 44283506d84d00bbb35ecebb44261b2139bc40ef3e2Chia-I Wuuint32_t LayerRef::GetSpecVersion() const { 443eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter return layer_->properties.specVersion; 444eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter} 445eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter 44654e6f086a6b373a0f496343451a76dde8aa86238Michael LentineLayerRef::LayerRef(LayerRef&& other) : layer_(std::move(other.layer_)) { 44754e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine other.layer_ = nullptr; 44854e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine} 44980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 45080523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const { 45180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>( 45280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr", 19)) 45380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 45480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 45580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 45680523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const { 45780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>( 45880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr", 17)) 45980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 46080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 46180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 462b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hallbool LayerRef::SupportsExtension(const char* name) const { 463b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall return std::find_if(layer_->extensions.cbegin(), layer_->extensions.cend(), 464b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall [=](const VkExtensionProperties& ext) { 465b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall return strcmp(ext.extensionName, name) == 0; 466b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall }) != layer_->extensions.cend(); 467b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall} 468b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall 469c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu} // namespace api 47080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} // namespace vulkan 471