/*
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "layers_extensions.h"

#include <alloca.h>
#include <dirent.h>
#include <dlfcn.h>
#include <string.h>
#include <sys/prctl.h>
#include <unistd.h>

#include <mutex>
#include <string>
#include <vector>

#include <android/dlext.h>
#include <android-base/strings.h>
#include <cutils/properties.h>
#include <graphicsenv/GraphicsEnv.h>
#include <log/log.h>
#include <nativebridge/native_bridge.h>
#include <nativeloader/native_loader.h>
#include <utils/Trace.h>
#include <ziparchive/zip_archive.h>

#include <com_android_graphics_libvulkan_flags.h>
using namespace com::android::graphics::libvulkan;

#include <VulkanProperties.sysprop.h>
using namespace android::sysprop;

// TODO(b/143296676): This file currently builds up global data structures as it
// loads, and never cleans them up. This means we're doing heap allocations
// without going through an app-provided allocator, but worse, we'll leak those
// allocations if the loader is unloaded.
//
// We should allocate "enough" BSS space, and suballocate from there. Will
// probably want to intern strings, etc., and will need some custom/manual data
// structures.

namespace vulkan {
namespace api {

enum LayerType {
    IMPLICIT,
    EXPLICIT,
    PLATFORM,
    OEM,
};

struct Layer {
    VkLayerProperties properties;
    size_t library_idx;

    LayerType type;

    // true if the layer intercepts vkCreateDevice and device commands
    bool is_global;

    std::vector<VkExtensionProperties> instance_extensions;
    std::vector<VkExtensionProperties> device_extensions;
};

namespace {

const char kSystemDebugLayerLibraryDir[] = "/data/local/debug/vulkan";
#if defined(__LP64__)
const char kSystemPlatformLayerLibraryDir[] = "/system/lib64/vulkan";
const char kSystemOEMLayerLibraryDir[] = "/product/lib64/vulkan";
#else
const char kSystemPlatformLayerLibraryDir[] = "/system/lib/vulkan";
const char kSystemOEMLayerLibraryDir[] = "/product/lib/vulkan";
#endif

class LayerLibrary {
   public:
    explicit LayerLibrary(const std::string& path,
                          const std::string& filename)
        : path_(path),
          filename_(filename),
          dlhandle_(nullptr),
          native_bridge_(false),
          opened_with_native_loader_(false),
          refcount_(0) {}

    LayerLibrary(LayerLibrary&& other) noexcept
        : path_(std::move(other.path_)),
          filename_(std::move(other.filename_)),
          dlhandle_(other.dlhandle_),
          native_bridge_(other.native_bridge_),
          opened_with_native_loader_(other.opened_with_native_loader_),
          refcount_(other.refcount_) {
        other.dlhandle_ = nullptr;
        other.refcount_ = 0;
    }

    LayerLibrary(const LayerLibrary&) = delete;
    LayerLibrary& operator=(const LayerLibrary&) = delete;

    // these are thread-safe
    bool Open();
    void Close();

    bool EnumerateLayers(size_t library_idx,
                         std::vector<Layer>& instance_layers,
                         LayerType type) const;

    void* GetGPA(const Layer& layer, const std::string_view gpa_name) const;

    const std::string GetFilename() { return filename_; }

   private:
    // TODO(b/79940628): remove that adapter when we could use NativeBridgeGetTrampoline
    // for native libraries.
    template<typename Func = void*>
    Func GetTrampoline(const char* name) const {
        if (native_bridge_) {
            return reinterpret_cast<Func>(android::NativeBridgeGetTrampoline(
                dlhandle_, name, nullptr, 0));
        }
        return reinterpret_cast<Func>(dlsym(dlhandle_, name));
    }

    const std::string path_;

    // Track the filename alone so we can detect duplicates
    const std::string filename_;

    std::mutex mutex_;
    void* dlhandle_;
    bool native_bridge_;
    bool opened_with_native_loader_;
    size_t refcount_;
};

bool LayerLibrary::Open() {
    std::lock_guard<std::mutex> lock(mutex_);
    if (refcount_++ == 0) {
        ALOGV("opening layer library '%s'", path_.c_str());
        // Libraries in the system layer library dir can't be loaded into
        // the application namespace. That causes compatibility problems, since
        // any symbol dependencies will be resolved by system libraries. They
        // can't safely use libc++_shared, for example. Which is one reason
        // (among several) we only allow them in non-user builds.
        auto app_namespace = android::GraphicsEnv::getInstance().getAppNamespace();
        if (app_namespace &&
            !(android::base::StartsWith(path_, kSystemDebugLayerLibraryDir) ||
              android::base::StartsWith(path_,
                                        kSystemPlatformLayerLibraryDir) ||
              android::base::StartsWith(path_, kSystemOEMLayerLibraryDir))) {
            char* error_msg = nullptr;
            dlhandle_ = android::OpenNativeLibraryInNamespace(
                app_namespace, path_.c_str(), &native_bridge_, &error_msg);
            if (!dlhandle_) {
                ALOGE("failed to load layer library '%s': %s", path_.c_str(), error_msg);
                android::NativeLoaderFreeErrorMessage(error_msg);
                refcount_ = 0;
                return false;
            }
            opened_with_native_loader_ = true;
        } else {
            dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL);
            if (!dlhandle_) {
                ALOGE("failed to load layer library '%s': %s", path_.c_str(),
                      dlerror());
                refcount_ = 0;
                return false;
            }
            opened_with_native_loader_ = false;
        }
    }
    return true;
}

void LayerLibrary::Close() {
    std::lock_guard<std::mutex> lock(mutex_);
    if (--refcount_ == 0) {
        ALOGV("closing layer library '%s'", path_.c_str());
        // we close the .so same way as we opened. It's importain, because
        // android::CloseNativeLibrary lives in libnativeloader.so, which is
        // not accessible for early loaded services like SurfaceFlinger
        if (opened_with_native_loader_) {
            char* error_msg = nullptr;
            if (!android::CloseNativeLibrary(dlhandle_, native_bridge_, &error_msg)) {
                ALOGE("failed to unload library '%s': %s", path_.c_str(), error_msg);
                android::NativeLoaderFreeErrorMessage(error_msg);
                refcount_++;
                return;
            }
        } else {
            if (dlclose(dlhandle_) != 0) {
                ALOGE("failed to unload library '%s': %s", path_.c_str(), dlerror());
                refcount_++;
                return;
            }
        }
        dlhandle_ = nullptr;
    }
}

bool LayerLibrary::EnumerateLayers(size_t library_idx,
                                   std::vector<Layer>& instance_layers,
                                   LayerType type) const {
    PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers =
        GetTrampoline<PFN_vkEnumerateInstanceLayerProperties>(
            "vkEnumerateInstanceLayerProperties");
    PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions =
        GetTrampoline<PFN_vkEnumerateInstanceExtensionProperties>(
            "vkEnumerateInstanceExtensionProperties");
    if (!enumerate_instance_layers || !enumerate_instance_extensions) {
        ALOGE("layer library '%s' missing some instance enumeration functions",
              path_.c_str());
        return false;
    }

    // device functions are optional
    PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers =
        GetTrampoline<PFN_vkEnumerateDeviceLayerProperties>(
            "vkEnumerateDeviceLayerProperties");
    PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions =
        GetTrampoline<PFN_vkEnumerateDeviceExtensionProperties>(
            "vkEnumerateDeviceExtensionProperties");

    // get layer counts
    uint32_t num_instance_layers = 0;
    uint32_t num_device_layers = 0;
    VkResult result = enumerate_instance_layers(&num_instance_layers, nullptr);
    if (result != VK_SUCCESS || !num_instance_layers) {
        if (result != VK_SUCCESS) {
            ALOGE(
                "vkEnumerateInstanceLayerProperties failed for library '%s': "
                "%d",
                path_.c_str(), result);
        }
        return false;
    }
    if (enumerate_device_layers) {
        result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers,
                                         nullptr);
        if (result != VK_SUCCESS) {
            ALOGE(
                "vkEnumerateDeviceLayerProperties failed for library '%s': %d",
                path_.c_str(), result);
            return false;
        }
    }

    // get layer properties
    std::vector<VkLayerProperties> properties(num_instance_layers + num_device_layers);
    result = enumerate_instance_layers(&num_instance_layers, properties.data());
    if (result != VK_SUCCESS) {
        ALOGE("vkEnumerateInstanceLayerProperties failed for library '%s': %d",
              path_.c_str(), result);
        return false;
    }
    if (num_device_layers > 0) {
        result = enumerate_device_layers(VK_NULL_HANDLE, &num_device_layers,
                                         &properties[num_instance_layers]);
        if (result != VK_SUCCESS) {
            ALOGE(
                "vkEnumerateDeviceLayerProperties failed for library '%s': %d",
                path_.c_str(), result);
            return false;
        }
    }

    // append layers to instance_layers
    size_t prev_num_instance_layers = instance_layers.size();
    instance_layers.reserve(prev_num_instance_layers + num_instance_layers);
    for (size_t i = 0; i < num_instance_layers; i++) {
        const VkLayerProperties& props = properties[i];

        Layer layer;
        layer.properties = props;
        layer.library_idx = library_idx;
        layer.is_global = false;
        layer.type = type;

        uint32_t count = 0;
        result =
            enumerate_instance_extensions(props.layerName, &count, nullptr);
        if (result != VK_SUCCESS) {
            ALOGE(
                "vkEnumerateInstanceExtensionProperties(\"%s\") failed for "
                "library '%s': %d",
                props.layerName, path_.c_str(), result);
            instance_layers.resize(prev_num_instance_layers);
            return false;
        }
        layer.instance_extensions.resize(count);
        result = enumerate_instance_extensions(
            props.layerName, &count, layer.instance_extensions.data());
        if (result != VK_SUCCESS) {
            ALOGE(
                "vkEnumerateInstanceExtensionProperties(\"%s\") failed for "
                "library '%s': %d",
                props.layerName, path_.c_str(), result);
            instance_layers.resize(prev_num_instance_layers);
            return false;
        }

        for (size_t j = 0; j < num_device_layers; j++) {
            const auto& dev_props = properties[num_instance_layers + j];
            if (memcmp(&props, &dev_props, sizeof(props)) == 0) {
                layer.is_global = true;
                break;
            }
        }

        if (layer.is_global && enumerate_device_extensions) {
            result = enumerate_device_extensions(
                VK_NULL_HANDLE, props.layerName, &count, nullptr);
            if (result != VK_SUCCESS) {
                ALOGE(
                    "vkEnumerateDeviceExtensionProperties(\"%s\") failed for "
                    "library '%s': %d",
                    props.layerName, path_.c_str(), result);
                instance_layers.resize(prev_num_instance_layers);
                return false;
            }
            layer.device_extensions.resize(count);
            result = enumerate_device_extensions(
                VK_NULL_HANDLE, props.layerName, &count,
                layer.device_extensions.data());
            if (result != VK_SUCCESS) {
                ALOGE(
                    "vkEnumerateDeviceExtensionProperties(\"%s\") failed for "
                    "library '%s': %d",
                    props.layerName, path_.c_str(), result);
                instance_layers.resize(prev_num_instance_layers);
                return false;
            }
        }

        instance_layers.push_back(layer);
        ALOGD("added %s layer '%s' from library '%s'",
              (layer.is_global) ? "global" : "instance", props.layerName,
              path_.c_str());
    }

    return true;
}

void* LayerLibrary::GetGPA(const Layer& layer, const std::string_view gpa_name) const {
    std::string layer_name { layer.properties.layerName };
    if (void* gpa = GetTrampoline((layer_name.append(gpa_name).c_str())))
        return gpa;
    return GetTrampoline((std::string {"vk"}.append(gpa_name)).c_str());
}

// ----------------------------------------------------------------------------

std::vector<LayerLibrary> g_layer_libraries;
std::vector<Layer> g_instance_layers;

void AddLayerLibrary(const std::string& path,
                     const std::string& filename,
                     LayerType type) {
    LayerLibrary library(path + "/" + filename, filename);
    if (!library.Open())
        return;

    if (!library.EnumerateLayers(g_layer_libraries.size(), g_instance_layers,
                                 type)) {
        library.Close();
        return;
    }

    library.Close();

    g_layer_libraries.emplace_back(std::move(library));
}

template <typename Functor>
void ForEachFileInDir(const std::string& dirname, Functor functor) {
    auto dir_deleter = [](DIR* handle) { closedir(handle); };
    std::unique_ptr<DIR, decltype(dir_deleter)> dir(opendir(dirname.c_str()),
                                                    dir_deleter);
    if (!dir) {
        // It's normal for some search directories to not exist, especially
        // /data/local/debug/vulkan.
        int err = errno;
        ALOGW_IF(err != ENOENT, "failed to open layer directory '%s': %s",
                 dirname.c_str(), strerror(err));
        return;
    }
    ALOGD("searching for layers in '%s'", dirname.c_str());
    dirent* entry;
    while ((entry = readdir(dir.get())) != nullptr)
        functor(entry->d_name);
}

template <typename Functor>
void ForEachFileInZip(const std::string& zipname,
                      const std::string& dir_in_zip,
                      Functor functor) {
    static const size_t kPageSize = getpagesize();
    int32_t err;
    ZipArchiveHandle zip = nullptr;
    if ((err = OpenArchive(zipname.c_str(), &zip)) != 0) {
        ALOGE("failed to open apk '%s': %d", zipname.c_str(), err);
        return;
    }
    std::string prefix(dir_in_zip + "/");
    void* iter_cookie = nullptr;
    if ((err = StartIteration(zip, &iter_cookie, prefix, "")) != 0) {
        ALOGE("failed to iterate entries in apk '%s': %d", zipname.c_str(),
              err);
        CloseArchive(zip);
        return;
    }
    ALOGD("searching for layers in '%s!/%s'", zipname.c_str(),
          dir_in_zip.c_str());
    ZipEntry entry;
    std::string name;
    while (Next(iter_cookie, &entry, &name) == 0) {
        std::string filename(name.substr(prefix.length()));
        // only enumerate direct entries of the directory, not subdirectories
        if (filename.find('/') != filename.npos)
            continue;
        // Check whether it *may* be possible to load the library directly from
        // the APK. Loading still may fail for other reasons, but this at least
        // lets us avoid failed-to-load log messages in the typical case of
        // compressed and/or unaligned libraries.
        if (entry.method != kCompressStored || entry.offset % kPageSize != 0)
            continue;
        functor(filename);
    }
    EndIteration(iter_cookie);
    CloseArchive(zip);
}

template <typename Functor>
void ForEachFileInPath(const std::string& path, Functor functor) {
    size_t zip_pos = path.find("!/");
    if (zip_pos == std::string::npos) {
        ForEachFileInDir(path, functor);
    } else {
        ForEachFileInZip(path.substr(0, zip_pos), path.substr(zip_pos + 2),
                         functor);
    }
}

void DiscoverLayersInPathList(const std::string& pathstr, LayerType type) {
    ATRACE_CALL();

    std::vector<std::string> paths = android::base::Split(pathstr, ":");
    for (const auto& path : paths) {
        ForEachFileInPath(path, [&](const std::string& filename) {
            if (android::base::StartsWith(filename, "libVkLayer") &&
                android::base::EndsWith(filename, ".so")) {

                // Check to ensure we haven't seen this layer already
                // Let the first instance of the shared object be enumerated
                // We're searching for layers in following order:
                // 1. system path
                // 2. libraryPermittedPath (if enabled)
                // 3. libraryPath

                bool duplicate = false;
                for (auto& layer : g_layer_libraries) {
                    if (layer.GetFilename() == filename) {
                        ALOGV("Skipping duplicate layer %s in %s",
                              filename.c_str(), path.c_str());
                        duplicate = true;
                    }
                }

                if (!duplicate)
                    AddLayerLibrary(path, filename, type);
            }
        });
    }
}

void DiscoverLayersFromProperty(const std::string& path,
                                const std::string& librariesprop,
                                LayerType type) {
    ATRACE_CALL();

    std::vector<std::string> libraries =
        android::base::Split(librariesprop, ":");
    for (const auto& filename : libraries) {
        if (android::base::StartsWith(filename, "libVkLayer") &&
            android::base::EndsWith(filename, ".so")) {
            // Check to ensure we haven't seen this layer already
            // (e.g. an IMPLICIT or EXPLICIT layer)

            bool duplicate = false;
            for (auto& layer : g_layer_libraries) {
                if (layer.GetFilename() == filename) {
                    ALOGV("Skipping duplicate layer %s in %s", filename.c_str(),
                          path.c_str());
                    duplicate = true;
                }
            }

            if (!duplicate)
                AddLayerLibrary(path, filename, type);
        }
    }
}

const VkExtensionProperties* FindExtension(
    const std::vector<VkExtensionProperties>& extensions,
    const char* name) {
    auto it = std::find_if(extensions.cbegin(), extensions.cend(),
                           [=](const VkExtensionProperties& ext) {
                               return (strcmp(ext.extensionName, name) == 0);
                           });
    return (it != extensions.cend()) ? &*it : nullptr;
}

void* GetLayerGetProcAddr(const Layer& layer,
                          const std::string_view gpa_name) {
    const LayerLibrary& library = g_layer_libraries[layer.library_idx];
    return library.GetGPA(layer, gpa_name);
}

}  // anonymous namespace

/* This function is used to discover all of the implicit, explicit, platform,
 * and OEM layers that should be used for the process (typically an application
 * APK, but potentially a system process such as SurfaceFlinger).
 *
 * Android's security model restricts usage of implicit layers (a.k.a. "debug
 * layers") to one of the following cases for the target app:
 *
 * - The target app is debuggable
 * - The target app is run on a userdebug build of the operating system which
 *   grants root access
 * - The target app's manifest file includes the following meta-data element
 *   (only applies to apps that target Android 11 (API level 30) or higher):
 *   <meta-data android:name="com.android.graphics.injectLayers.enable"
 *   android:value="true" />
 *
 * Implicit layers can be globally enabled until the next reboot, using the
 * following command:
 *
 * - adb shell setprop debug.vulkan.layers <layer1:layer2:layerN>
 *
 * Implicit layers can be enabled for a single target application, using the
 * "adb shell settings put global" command to configure the following settings
 * (that persist across reboots):
 *
 * - enable_gpu_debug_layers 1
 * - gpu_debug_app <package_name>
 * - gpu_debug_layers <layer1:layer2:layerN>
 * - gpu_debug_layer_app <package1:package2:packageN>
 */
void DiscoverLayers() {
    ATRACE_CALL();

    // Look in the original Android "implicit" layer (a.k.a. "debug layer") path
    // for implicit layers, configured by the following settings (as described
    // above): enable_gpu_debug_layers, gpu_debug_app, gpu_debug_layers
    if (android::GraphicsEnv::getInstance().isDebuggable()) {
        DiscoverLayersInPathList(kSystemDebugLayerLibraryDir,
                                 LayerType::IMPLICIT);
    }
    // Look in the application's APK for "explicit" layers.  Also look for
    // "implicit" layers living in another APK(s), configured by all of the
    // per-app settings described above.  If configured, both APKs are returned
    // by getLayerPaths().
    //
    // TODO (b/455899446): Split treatment of IMPLICIT and EXPLICIT layers,
    // which are currently treated the same in the code below.
    if (!android::GraphicsEnv::getInstance().getLayerPaths().empty())
        DiscoverLayersInPathList(
            android::GraphicsEnv::getInstance().getLayerPaths(),
            LayerType::EXPLICIT);
    // TODO: longer term, we may want to load/Open() OPLs in Zygote and
    // inherit them into this process (i.e. not Open() and Close() them for each
    // process).
    if (flags::oem_and_platform_layers()) {
        // The layer properties are colon-separated lists of layer filenames
        std::string platformLayerLibraryNames =
            VulkanProperties::platform_layers().value_or("");
        if (!platformLayerLibraryNames.empty()) {
            DiscoverLayersFromProperty(kSystemPlatformLayerLibraryDir,
                                       platformLayerLibraryNames,
                                       LayerType::PLATFORM);
        }
        std::string oemLayerLibraryNames =
            VulkanProperties::oem_layers().value_or("");
        if (!oemLayerLibraryNames.empty()) {
            DiscoverLayersFromProperty(kSystemOEMLayerLibraryDir,
                                       oemLayerLibraryNames, LayerType::OEM);
        }
    }
}

/* Return the number of IMPLICIT and EXPLICIT Layer's (not PLATFORM nor OEM
 * Layer's), that should be returned by vkEnumerateInstanceLayerProperties().
 *
 * NOTE: This relies on all IMPLICIT and EXPLICIT Layer's being added to
 * g_instance_layers before any PLATFORM or OEM Layer's.
 */
uint32_t GetEnumeratedLayerCount() {
    uint32_t count = 0;
    for (size_t i = 0; i < g_instance_layers.size(); i++) {
        LayerType type = g_instance_layers[i].type;
        if (type == LayerType::PLATFORM || type == LayerType::OEM) {
            break;
        }
        count++;
    }
    return count;
}

/* Return the number of PLATFORM and OEM Layer's (not IMPLICIT nor EXPLICIT
 * Layer's), that LayerChain::ActivateLayers() should activate.
 *
 * NOTE: This relies on all IMPLICIT and EXPLICIT Layer's being added to
 * g_instance_layers before any PLATFORM or OEM Layer's.
 */
uint32_t GetOemAndPlatformLayerCount() {
    uint32_t count = g_instance_layers.size() - GetEnumeratedLayerCount();
    return count;
}

const Layer& GetLayer(uint32_t index) {
    return g_instance_layers[index];
}

const Layer* FindLayer(const char* name) {
    auto layer =
        std::find_if(g_instance_layers.cbegin(), g_instance_layers.cend(),
                     [=](const Layer& entry) {
                         return strcmp(entry.properties.layerName, name) == 0;
                     });
    return (layer != g_instance_layers.cend()) ? &*layer : nullptr;
}

const VkLayerProperties& GetLayerProperties(const Layer& layer) {
    return layer.properties;
}

bool IsLayerGlobal(const Layer& layer) {
    return layer.is_global;
}

const VkExtensionProperties* GetLayerInstanceExtensions(const Layer& layer,
                                                        uint32_t& count) {
    count = static_cast<uint32_t>(layer.instance_extensions.size());
    return layer.instance_extensions.data();
}

const VkExtensionProperties* GetLayerDeviceExtensions(const Layer& layer,
                                                      uint32_t& count) {
    count = static_cast<uint32_t>(layer.device_extensions.size());
    return layer.device_extensions.data();
}

const VkExtensionProperties* FindLayerInstanceExtension(const Layer& layer,
                                                        const char* name) {
    return FindExtension(layer.instance_extensions, name);
}

const VkExtensionProperties* FindLayerDeviceExtension(const Layer& layer,
                                                      const char* name) {
    return FindExtension(layer.device_extensions, name);
}

LayerRef GetLayerRef(const Layer& layer) {
    LayerLibrary& library = g_layer_libraries[layer.library_idx];
    return LayerRef((library.Open()) ? &layer : nullptr);
}

LayerRef::LayerRef(const Layer* layer) : layer_(layer) {}

LayerRef::~LayerRef() {
    if (layer_) {
        LayerLibrary& library = g_layer_libraries[layer_->library_idx];
        library.Close();
    }
}

LayerRef::LayerRef(LayerRef&& other) noexcept : layer_(other.layer_) {
    other.layer_ = nullptr;
}

PFN_vkGetInstanceProcAddr LayerRef::GetGetInstanceProcAddr() const {
    return layer_ ? reinterpret_cast<PFN_vkGetInstanceProcAddr>(
                        GetLayerGetProcAddr(*layer_, "GetInstanceProcAddr"))
                  : nullptr;
}

PFN_vkGetDeviceProcAddr LayerRef::GetGetDeviceProcAddr() const {
    return layer_ ? reinterpret_cast<PFN_vkGetDeviceProcAddr>(
                        GetLayerGetProcAddr(*layer_, "GetDeviceProcAddr"))
                  : nullptr;
}

}  // namespace api
}  // namespace vulkan
