layers_extensions.cpp revision 279ccc0048d5bc7105af02538e33946814c68dc7
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 230279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu bool is_global = false; 231279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu for (size_t j = 0; j < num_device_layers; j++) { 232279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu const auto& dev_props = properties[num_instance_layers + j]; 233279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu if (memcmp(&props, &dev_props, sizeof(props)) == 0) { 234279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu is_global = true; 235279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu break; 236279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu } 237279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu } 238279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu 239279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu if (!is_global) 240279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu continue; 241aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 242279ccc0048d5bc7105af02538e33946814c68dc7Chia-I Wu layer.extensions.clear(); 243aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (enumerate_device_extensions) { 244aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = enumerate_device_extensions( 245aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VK_NULL_HANDLE, props.layerName, &count, nullptr); 246aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 247aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 248aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 24950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2506693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 25150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 25250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.resize(prev_num_device_layers); 25350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 254aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 255aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall layer.extensions.resize(count); 256aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall result = 257aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall enumerate_device_extensions(VK_NULL_HANDLE, props.layerName, 258aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall &count, layer.extensions.data()); 259aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (result != VK_SUCCESS) { 260aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall ALOGW( 261aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall "vkEnumerateDeviceExtensionProperties(%s) failed for " 26250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu "library '%s': %d", 2636693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu props.layerName, path_.c_str(), result); 26450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu instance_layers.resize(prev_num_instance_layers); 26550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.resize(prev_num_device_layers); 26650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return false; 267aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 268aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall } 269aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 27050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu device_layers.push_back(layer); 271b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall ALOGV(" added device layer '%s'", props.layerName); 27280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 27380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 27450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return true; 27550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu} 27650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 277ba113275287a2293136d8737bf364651ea0b576dChia-I Wuvoid* LayerLibrary::GetGPA(const Layer& layer, 278ba113275287a2293136d8737bf364651ea0b576dChia-I Wu const char* gpa_name, 279ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t gpa_name_len) const { 280ba113275287a2293136d8737bf364651ea0b576dChia-I Wu void* gpa; 281ba113275287a2293136d8737bf364651ea0b576dChia-I Wu size_t layer_name_len = 282ba113275287a2293136d8737bf364651ea0b576dChia-I Wu std::max(size_t{2}, strlen(layer.properties.layerName)); 283ba113275287a2293136d8737bf364651ea0b576dChia-I Wu char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1)); 284ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, layer.properties.layerName); 285ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + layer_name_len, gpa_name); 2866693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu if (!(gpa = dlsym(dlhandle_, name))) { 287ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name, "vk"); 288ba113275287a2293136d8737bf364651ea0b576dChia-I Wu strcpy(name + 2, gpa_name); 2896693f5cd2238fe08b382bf762e33b701312c7038Chia-I Wu gpa = dlsym(dlhandle_, name); 290ba113275287a2293136d8737bf364651ea0b576dChia-I Wu } 291ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return gpa; 292ba113275287a2293136d8737bf364651ea0b576dChia-I Wu} 293ba113275287a2293136d8737bf364651ea0b576dChia-I Wu 29450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<LayerLibrary> g_layer_libraries; 29550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<Layer> g_instance_layers; 29650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wustd::vector<Layer> g_device_layers; 29750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 29850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wuvoid AddLayerLibrary(const std::string& path) { 29950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu ALOGV("examining layer library '%s'", path.c_str()); 30050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 30150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu LayerLibrary library(path); 30250174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu if (!library.Open()) 30350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 30450174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 30550174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu if (!library.EnumerateLayers(g_layer_libraries.size(), g_instance_layers, 30650174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu g_device_layers)) { 30750174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 30850174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu return; 30950174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu } 31050174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu 31150174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu library.Close(); 31280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31350174ee4ff2f6537c4aa4e8aa475f0dc8d910870Chia-I Wu g_layer_libraries.emplace_back(std::move(library)); 31480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 31580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31680523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid DiscoverLayersInDirectory(const std::string& dir_path) { 31780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV("looking for layers in '%s'", dir_path.c_str()); 31880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 31980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall DIR* directory = opendir(dir_path.c_str()); 32080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (!directory) { 32180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall int err = errno; 32280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall ALOGV_IF(err != ENOENT, "failed to open layer directory '%s': %s (%d)", 32380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall dir_path.c_str(), strerror(err), err); 32480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return; 32580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 32680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 32780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall std::string path; 32880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.reserve(dir_path.size() + 20); 32980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(dir_path); 33080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append("/"); 33180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 33280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall struct dirent* entry; 33380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall while ((entry = readdir(directory))) { 33480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t libname_len = strlen(entry->d_name); 335a7ac76df54c30e771ecfd05cdd2b52209af71470Jesse Hall if (strncmp(entry->d_name, "libVkLayer", 10) != 0 || 33680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall strncmp(entry->d_name + libname_len - 3, ".so", 3) != 0) 33780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall continue; 33880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.append(entry->d_name); 33980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall AddLayerLibrary(path); 34080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall path.resize(dir_path.size() + 1); 34180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 34280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 34380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall closedir(directory); 34480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 34580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 34650db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wuconst Layer* FindLayer(const std::vector<Layer>& layers, const char* name) { 34750db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu auto layer = 34850db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu std::find_if(layers.cbegin(), layers.cend(), [=](const Layer& entry) { 34950db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return strcmp(entry.properties.layerName, name) == 0; 35050db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu }); 35150db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return (layer != layers.cend()) ? &*layer : nullptr; 35250db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu} 35350db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu 35480523e2e39c29b06ab40573468dde43a9867f487Jesse Hallvoid* GetLayerGetProcAddr(const Layer& layer, 35580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const char* gpa_name, 35680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall size_t gpa_name_len) { 35780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const LayerLibrary& library = g_layer_libraries[layer.library_idx]; 358ba113275287a2293136d8737bf364651ea0b576dChia-I Wu return library.GetGPA(layer, gpa_name, gpa_name_len); 35980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 36080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 361aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateLayers(const std::vector<Layer>& layers, 362aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t count, 363aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 364aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t n = std::min(count, static_cast<uint32_t>(layers.size())); 36580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall for (uint32_t i = 0; i < n; i++) { 366aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall properties[i] = layers[i].properties; 36780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 368aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return static_cast<uint32_t>(layers.size()); 36980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 37080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 371aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetLayerExtensions(const std::vector<Layer>& layers, 372aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const char* name, 37380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall const VkExtensionProperties** properties, 37480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall uint32_t* count) { 37550db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu const Layer* layer = FindLayer(layers, name); 37650db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (layer) { 377aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *properties = layer->extensions.data(); 378aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall *count = static_cast<uint32_t>(layer->extensions.size()); 37950db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu } else { 38050db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu *properties = nullptr; 38150db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu *count = 0; 38280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 38380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 38480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 385aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetLayerRef(std::vector<Layer>& layers, const char* name) { 38650db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu const Layer* layer = FindLayer(layers, name); 38750db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (layer) { 38850db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu LayerLibrary& library = g_layer_libraries[layer->library_idx]; 38950db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu if (!library.Open()) 39050db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu layer = nullptr; 39180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 39250db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu 39350db9035b034385a27fb557e4da3c48b51a0e3ebChia-I Wu return LayerRef(layer); 39480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 39580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 396aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} // anonymous namespace 397aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 398aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid DiscoverLayers() { 399aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) 400aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory("/data/local/debug/vulkan"); 401aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall if (!LoaderData::GetInstance().layer_path.empty()) 402aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall DiscoverLayersInDirectory(LoaderData::GetInstance().layer_path.c_str()); 403aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 404aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 405aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateInstanceLayers(uint32_t count, 406aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall VkLayerProperties* properties) { 407aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_instance_layers, count, properties); 408aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 409aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 410aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Halluint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties) { 411aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return EnumerateLayers(g_device_layers, count, properties); 412aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 413aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 414aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetInstanceLayerExtensions(const char* name, 415aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 416aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 417aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_instance_layers, name, properties, count); 418aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 419aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 420aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hallvoid GetDeviceLayerExtensions(const char* name, 421aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall const VkExtensionProperties** properties, 422aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall uint32_t* count) { 423aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall GetLayerExtensions(g_device_layers, name, properties, count); 424aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 425aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 426aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetInstanceLayerRef(const char* name) { 427aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_instance_layers, name); 428aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 429aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 430aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse HallLayerRef GetDeviceLayerRef(const char* name) { 431aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall return GetLayerRef(g_device_layers, name); 432aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall} 433aa410941d29cba4a3a56e90cb3f0be3f03c76ceaJesse Hall 43483506d84d00bbb35ecebb44261b2139bc40ef3e2Chia-I WuLayerRef::LayerRef(const Layer* layer) : layer_(layer) {} 43580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 43680523e2e39c29b06ab40573468dde43a9867f487Jesse HallLayerRef::~LayerRef() { 43780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall if (layer_) { 43880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall LayerLibrary& library = g_layer_libraries[layer_->library_idx]; 439d91c74f917b603d8d1dec7d27da03e580919e0a6Chia-I Wu library.Close(); 44080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall } 44180523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 44280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 4435703683fb645a7e31ac25aaf7136013a6a9b9fbcMichael Lentineconst char* LayerRef::GetName() const { 444eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter return layer_->properties.layerName; 445eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter} 446eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter 44783506d84d00bbb35ecebb44261b2139bc40ef3e2Chia-I Wuuint32_t LayerRef::GetSpecVersion() const { 448eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter return layer_->properties.specVersion; 449eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter} 450eff631189b135a9579a7f8510f9b1ccadd6fb4f9Courtney Goeltzenleuchter 45154e6f086a6b373a0f496343451a76dde8aa86238Michael LentineLayerRef::LayerRef(LayerRef&& other) : layer_(std::move(other.layer_)) { 45254e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine other.layer_ = nullptr; 45354e6f086a6b373a0f496343451a76dde8aa86238Michael Lentine} 45480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 45580523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const { 45680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>( 45780523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr", 19)) 45880523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 45980523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 46080523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 46180523e2e39c29b06ab40573468dde43a9867f487Jesse HallPFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const { 46280523e2e39c29b06ab40573468dde43a9867f487Jesse Hall return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>( 46380523e2e39c29b06ab40573468dde43a9867f487Jesse Hall GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr", 17)) 46480523e2e39c29b06ab40573468dde43a9867f487Jesse Hall : nullptr; 46580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} 46680523e2e39c29b06ab40573468dde43a9867f487Jesse Hall 467b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hallbool LayerRef::SupportsExtension(const char* name) const { 468b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall return std::find_if(layer_->extensions.cbegin(), layer_->extensions.cend(), 469b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall [=](const VkExtensionProperties& ext) { 470b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall return strcmp(ext.extensionName, name) == 0; 471b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall }) != layer_->extensions.cend(); 472b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall} 473b147127b06c1ce6443839e8102d1ed2631a57b07Jesse Hall 474c96880f2cd1d34ffb9e3d10d80f0a3ddcc5579a8Chia-I Wu} // namespace api 47580523e2e39c29b06ab40573468dde43a9867f487Jesse Hall} // namespace vulkan 476