blob: 34908420199b9d6e5071d034b3826fed773ca2d3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_
#define SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_
#include <list>
#include <set>
#include <string>
#include "src/lib/fxl/memory/ref_counted.h"
#include <vulkan/vulkan.hpp>
namespace escher {
class VulkanInstance;
using VulkanInstancePtr = fxl::RefPtr<VulkanInstance>;
using VkDebugReportCallbackFn =
std::function<VkBool32(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
uint64_t object, size_t location, int32_t messageCode,
const char* pLayerPrefix, const char* pMessage, void* pUserData)>;
// Convenient wrapper for creating and managing the lifecycle of a VkInstance
// that is suitable for use by Escher.
class VulkanInstance : public fxl::RefCountedThreadSafe<VulkanInstance> {
public:
// Parameters used to construct a new Vulkan Instance.
struct Params {
std::set<std::string> layer_names;
std::set<std::string> extension_names;
bool requires_surface = true;
};
// Contains dynamically-obtained addresses of instance-specific functions.
struct ProcAddrs {
ProcAddrs(vk::Instance instance, bool requires_surface);
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
};
// Contains debug report callback function and the user data pointer the
// callback function binds to.
struct DebugReportCallback {
VkDebugReportCallbackFn function = nullptr;
void* user_data = nullptr;
DebugReportCallback(VkDebugReportCallbackFn function_, void* user_data_)
: function(std::move(function_)), user_data(user_data_) {}
};
using DebugReportCallbackList = std::list<DebugReportCallback>;
using DebugReportCallbackHandle = DebugReportCallbackList::iterator;
// Constructor.
static fxl::RefPtr<VulkanInstance> New(Params params);
~VulkanInstance();
// Get the name of Vulkan validation layer. On platforms with Vulkan API
// < 1.1.106 only VK_LAYER_LUNARG_standard_validation is supported, while it
// is deprecated and we need to use VK_LAYER_KHRONOS_validation instead if
// possible.
static std::optional<std::string> GetValidationLayerName();
// Enumerate the available instance layers. Return true if all required
// layers are present, and false otherwise.
static bool ValidateLayers(const std::set<std::string>& required_layer_names);
// Enumerate the available instance extensions. Return true if all required
// extensions are present, and false otherwise. NOTE: if an extension isn't
// found at first, we look in all required layers to see if it is implemented
// there.
static bool ValidateExtensions(const std::set<std::string>& required_extension_names,
const std::set<std::string>& required_layer_names);
// Register debug report callback |function| to list of callbacks, which will
// be invoked by |DebugReportCallbackEntrance| when validation error occurs.
// The returned handle will be required when deregistering the callback.
DebugReportCallbackHandle RegisterDebugReportCallback(VkDebugReportCallbackFn function,
void* user_data = nullptr);
// Remove debug report callback pointed by |handle| from |callbacks_|, the list
// of callback functions.
void DeregisterDebugReportCallback(const DebugReportCallbackHandle& handle);
vk::Instance vk_instance() const { return instance_; }
// Return the parameterss that were used to create this instance.
const Params& params() const { return params_; }
// Return per-instance functions that were dynamically looked up.
const ProcAddrs& proc_addrs() const { return proc_addrs_; }
// Return Vulkan API Version of the instance.
uint32_t api_version() const { return api_version_; }
private:
VulkanInstance(vk::Instance instance, Params params, uint32_t api_version);
// The "entrance" handler for all Vulkan instances. When validation error
// occurs, this function will invoke all debug report callback functions
// stored in vector |callbacks_|. This function always return VK_FALSE.
static VkBool32 DebugReportCallbackEntrance(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object, size_t location, int32_t messageCode,
const char* pLayerPrefix, const char* pMessage,
void* pUserData);
bool HasDebugReportExt() const {
return std::find(params_.extension_names.begin(), params_.extension_names.end(),
VK_EXT_DEBUG_REPORT_EXTENSION_NAME) != params_.extension_names.end();
}
vk::Instance instance_;
Params params_;
ProcAddrs proc_addrs_;
std::list<DebugReportCallback> callbacks_;
vk::DebugReportCallbackEXT vk_callback_entrance_handle_;
uint32_t api_version_;
};
}; // namespace escher
#endif // SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_