blob: ac7db27e813ebe3d8afaaffa8470b6e666a13ff9 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "vulkan_proc_table.h"
#include "lib/ftl/logging.h"
#include <dlfcn.h>
namespace vulkan {
VulkanProcTable::VulkanProcTable() : valid_(false), handle_(nullptr) {
if (!OpenLibraryHandle()) {
return;
}
if (!AcquireProcs()) {
return;
}
valid_ = true;
}
VulkanProcTable::~VulkanProcTable() {
CloseLibraryHandle();
}
bool VulkanProcTable::IsValid() const {
return valid_;
}
bool VulkanProcTable::OpenLibraryHandle() {
dlerror(); // clear existing errors on thread.
handle_ = dlopen("libvulkan.so", RTLD_NOW);
if (handle_ == nullptr) {
FTL_DLOG(WARNING) << "Could not open the vulkan library: " << dlerror();
return false;
}
return true;
}
bool VulkanProcTable::CloseLibraryHandle() {
if (handle_ != nullptr) {
dlerror(); // clear existing errors on thread.
if (dlclose(handle_) != 0) {
FTL_DLOG(ERROR) << "Could not close the vulkan library handle. This "
"indicates a leak.";
FTL_DLOG(ERROR) << dlerror();
}
handle_ = nullptr;
}
return handle_ == nullptr;
}
bool VulkanProcTable::AcquireProcs() {
if (handle_ == nullptr) {
return false;
}
#define ACQUIRE_PROC(symbol, name) \
if (!(symbol = reinterpret_cast<decltype(symbol)::Proto>( \
dlsym(handle_, name)))) { \
FTL_DLOG(WARNING) << "Could not acquire proc for function " << name; \
return false; \
}
ACQUIRE_PROC(createInstance, "vkCreateInstance");
ACQUIRE_PROC(destroyInstance, "vkDestroyInstance");
ACQUIRE_PROC(enumeratePhysicalDevices, "vkEnumeratePhysicalDevices");
ACQUIRE_PROC(createDevice, "vkCreateDevice");
ACQUIRE_PROC(destroyDevice, "vkDestroyDevice");
ACQUIRE_PROC(getDeviceQueue, "vkGetDeviceQueue");
ACQUIRE_PROC(getPhysicalDeviceSurfaceCapabilitiesKHR,
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
ACQUIRE_PROC(getPhysicalDeviceSurfaceFormatsKHR,
"vkGetPhysicalDeviceSurfaceFormatsKHR");
ACQUIRE_PROC(createSwapchainKHR, "vkCreateSwapchainKHR");
ACQUIRE_PROC(getSwapchainImagesKHR, "vkGetSwapchainImagesKHR");
ACQUIRE_PROC(getPhysicalDeviceSurfacePresentModesKHR,
"vkGetPhysicalDeviceSurfacePresentModesKHR");
ACQUIRE_PROC(destroySurfaceKHR, "vkDestroySurfaceKHR");
ACQUIRE_PROC(createCommandPool, "vkCreateCommandPool");
ACQUIRE_PROC(destroyCommandPool, "vkDestroyCommandPool");
ACQUIRE_PROC(createSemaphore, "vkCreateSemaphore");
ACQUIRE_PROC(destroySemaphore, "vkDestroySemaphore");
ACQUIRE_PROC(allocateCommandBuffers, "vkAllocateCommandBuffers");
ACQUIRE_PROC(freeCommandBuffers, "vkFreeCommandBuffers");
ACQUIRE_PROC(createFence, "vkCreateFence");
ACQUIRE_PROC(destroyFence, "vkDestroyFence");
ACQUIRE_PROC(waitForFences, "vkWaitForFences");
#if OS_ANDROID
ACQUIRE_PROC(createAndroidSurfaceKHR, "vkCreateAndroidSurfaceKHR");
#endif // OS_ANDROID
#undef ACQUIRE_PROC
return true;
}
} // namespace vulkan