|
|
|
|
@@ -1,7 +1,7 @@
|
|
|
|
|
#include "VulkanContext.h"
|
|
|
|
|
#include <Vulkan/Context.h>
|
|
|
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
#include "Logger.h"
|
|
|
|
|
#include <utils.h>
|
|
|
|
|
#include <Logger.h>
|
|
|
|
|
|
|
|
|
|
#include <SDL2/SDL_vulkan.h>
|
|
|
|
|
|
|
|
|
|
@@ -11,137 +11,140 @@
|
|
|
|
|
#include <tuple>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings::VulkanContextSettings() {
|
|
|
|
|
namespace Vulkan {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ContextSettings::ContextSettings() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings::~VulkanContextSettings() {
|
|
|
|
|
ContextSettings::~ContextSettings() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VulkanContextSettings::debug() const {
|
|
|
|
|
bool ContextSettings::debug() const {
|
|
|
|
|
return m_debug;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings& VulkanContextSettings::with_debug(bool enabled) {
|
|
|
|
|
ContextSettings& ContextSettings::with_debug(bool enabled) {
|
|
|
|
|
m_debug = enabled;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::optional<Uuid>& VulkanContextSettings::physical_device() const {
|
|
|
|
|
const std::optional<Uuid>& ContextSettings::physical_device() const {
|
|
|
|
|
return m_physical_device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings& VulkanContextSettings::with_physical_device(Uuid uuid) {
|
|
|
|
|
ContextSettings& ContextSettings::with_physical_device(Uuid uuid) {
|
|
|
|
|
m_physical_device = uuid;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<VulkanContextSettings::QueueInfo>& VulkanContextSettings::queues() const {
|
|
|
|
|
const std::vector<ContextSettings::QueueInfo>& ContextSettings::queues() const {
|
|
|
|
|
return m_queues;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings& VulkanContextSettings::with_queue(
|
|
|
|
|
ContextSettings& ContextSettings::with_queue(
|
|
|
|
|
uint32_t index, VkQueueFlagBits flags, bool use_swapchain_images
|
|
|
|
|
) {
|
|
|
|
|
m_queues.emplace_back(QueueInfo { index, flags, use_swapchain_images });
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Window* VulkanContextSettings::window() const {
|
|
|
|
|
SDL_Window* ContextSettings::window() const {
|
|
|
|
|
return m_window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContextSettings& VulkanContextSettings::with_window(SDL_Window* window) {
|
|
|
|
|
ContextSettings& ContextSettings::with_window(SDL_Window* window) {
|
|
|
|
|
m_window = window;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// VulkanContext
|
|
|
|
|
// Context
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VulkanContext::VulkanContext() {
|
|
|
|
|
Context::Context() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContext::~VulkanContext() {
|
|
|
|
|
Context::~Context() {
|
|
|
|
|
shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkInstance VulkanContext::instance() {
|
|
|
|
|
VkInstance Context::instance() {
|
|
|
|
|
return m_instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDevice VulkanContext::physical_device() {
|
|
|
|
|
VkPhysicalDevice Context::physical_device() {
|
|
|
|
|
return m_physical_device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkDevice VulkanContext::device() {
|
|
|
|
|
VkDevice Context::device() {
|
|
|
|
|
return m_device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t VulkanContext::queue_family(size_t queue_index) const {
|
|
|
|
|
uint32_t Context::queue_family(size_t queue_index) const {
|
|
|
|
|
return m_queue_families[queue_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkQueue VulkanContext::queue(size_t queue_index) {
|
|
|
|
|
VkQueue Context::queue(size_t queue_index) {
|
|
|
|
|
return m_queues[queue_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSurfaceKHR VulkanContext::surface() {
|
|
|
|
|
VkSurfaceKHR Context::surface() {
|
|
|
|
|
return m_surface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSwapchainKHR VulkanContext::swapchain() {
|
|
|
|
|
VkSwapchainKHR Context::swapchain() {
|
|
|
|
|
return m_swapchain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSurfaceFormatKHR VulkanContext::surface_format() const {
|
|
|
|
|
VkSurfaceFormatKHR Context::surface_format() const {
|
|
|
|
|
return m_surface_format;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPresentModeKHR VulkanContext::present_mode() const {
|
|
|
|
|
VkPresentModeKHR Context::present_mode() const {
|
|
|
|
|
return m_present_mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkExtent2D VulkanContext::swapchain_extent() const {
|
|
|
|
|
VkExtent2D Context::swapchain_extent() const {
|
|
|
|
|
return m_swapchain_extent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t VulkanContext::swapchain_image_count() const {
|
|
|
|
|
size_t Context::swapchain_image_count() const {
|
|
|
|
|
return m_image_resources.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t VulkanContext::current_image_index() const {
|
|
|
|
|
uint32_t Context::current_image_index() const {
|
|
|
|
|
return m_current_image_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkImage VulkanContext::swapchain_image() {
|
|
|
|
|
VkImage Context::swapchain_image() {
|
|
|
|
|
assert(m_current_image_index != CURRENT_IMAGE_INDEX);
|
|
|
|
|
return m_image_resources[m_current_image_index].image;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkImage VulkanContext::swapchain_image(size_t image_index) {
|
|
|
|
|
VkImage Context::swapchain_image(size_t image_index) {
|
|
|
|
|
return m_image_resources[image_index].image;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkImageView VulkanContext::swapchain_image_view() {
|
|
|
|
|
VkImageView Context::swapchain_image_view() {
|
|
|
|
|
assert(m_current_image_index != CURRENT_IMAGE_INDEX);
|
|
|
|
|
return m_image_resources[m_current_image_index].view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkImageView VulkanContext::swapchain_image_view(size_t image_index) {
|
|
|
|
|
VkImageView Context::swapchain_image_view(size_t image_index) {
|
|
|
|
|
return m_image_resources[image_index].view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSemaphore VulkanContext::ready_to_render() {
|
|
|
|
|
VkSemaphore Context::ready_to_render() {
|
|
|
|
|
return m_frame_resources[m_frame_resources_index].ready_to_render;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFence VulkanContext::render_done() {
|
|
|
|
|
VkFence Context::render_done() {
|
|
|
|
|
return m_frame_resources[m_frame_resources_index].render_done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::initialize(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::initialize(const ContextSettings& settings) {
|
|
|
|
|
m_window = settings.window();
|
|
|
|
|
|
|
|
|
|
create_instance(settings);
|
|
|
|
|
@@ -151,7 +154,7 @@ void VulkanContext::initialize(const VulkanContextSettings& settings) {
|
|
|
|
|
create_swapchain(settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::shutdown() {
|
|
|
|
|
void Context::shutdown() {
|
|
|
|
|
if(!m_instance)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -168,7 +171,7 @@ void VulkanContext::shutdown() {
|
|
|
|
|
destroy_instance(m_instance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::begin_frame() {
|
|
|
|
|
void Context::begin_frame() {
|
|
|
|
|
assert(m_current_image_index == CURRENT_IMAGE_INDEX);
|
|
|
|
|
|
|
|
|
|
auto& frame_resources = m_frame_resources[m_frame_resources_index];
|
|
|
|
|
@@ -229,7 +232,7 @@ void VulkanContext::begin_frame() {
|
|
|
|
|
vkResetFences(m_device, 1, &frame_resources.render_done);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::swap_buffers(uint32_t semaphore_count, VkSemaphore* wait_semaphores) {
|
|
|
|
|
void Context::swap_buffers(uint32_t semaphore_count, VkSemaphore* wait_semaphores) {
|
|
|
|
|
assert(m_current_image_index != CURRENT_IMAGE_INDEX);
|
|
|
|
|
|
|
|
|
|
VkPresentInfoKHR present_info {
|
|
|
|
|
@@ -262,23 +265,23 @@ void VulkanContext::swap_buffers(uint32_t semaphore_count, VkSemaphore* wait_sem
|
|
|
|
|
m_current_image_index = CURRENT_IMAGE_INDEX;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::invalidate_swapchain() {
|
|
|
|
|
void Context::invalidate_swapchain() {
|
|
|
|
|
m_invalid_swapchain = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::register_swapchain_creation_callback(SwapchainCreationCallback callback) {
|
|
|
|
|
void Context::register_swapchain_creation_callback(SwapchainCreationCallback callback) {
|
|
|
|
|
m_swapchain_creation_callbacks.emplace_back(std::move(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::register_swapchain_destruction_callback(SwapchainDestructionCallback callback) {
|
|
|
|
|
void Context::register_swapchain_destruction_callback(SwapchainDestructionCallback callback) {
|
|
|
|
|
m_swapchain_destruction_callbacks.emplace_back(std::move(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::register_context_destruction_callback(ContextDestructionCallback callback) {
|
|
|
|
|
void Context::register_context_destruction_callback(ContextDestructionCallback callback) {
|
|
|
|
|
m_context_destruction_callbacks.emplace_back(std::move(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkExtensionProperties> VulkanContext::available_extensions() {
|
|
|
|
|
std::vector<VkExtensionProperties> Context::available_extensions() {
|
|
|
|
|
uint32_t count;
|
|
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -288,7 +291,7 @@ std::vector<VkExtensionProperties> VulkanContext::available_extensions() {
|
|
|
|
|
return extensions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkLayerProperties> VulkanContext::available_layers() {
|
|
|
|
|
std::vector<VkLayerProperties> Context::available_layers() {
|
|
|
|
|
uint32_t count;
|
|
|
|
|
vkEnumerateInstanceLayerProperties(&count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -298,7 +301,7 @@ std::vector<VkLayerProperties> VulkanContext::available_layers() {
|
|
|
|
|
return layers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<const char*> VulkanContext::sdl_vulkan_extensions() const {
|
|
|
|
|
std::vector<const char*> Context::sdl_vulkan_extensions() const {
|
|
|
|
|
unsigned count;
|
|
|
|
|
if(!SDL_Vulkan_GetInstanceExtensions(m_window, &count, nullptr))
|
|
|
|
|
throw std::runtime_error("failed to get window's vulkan extensions");
|
|
|
|
|
@@ -310,7 +313,7 @@ std::vector<const char*> VulkanContext::sdl_vulkan_extensions() const {
|
|
|
|
|
return extensions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkPhysicalDevice> VulkanContext::physical_devices() const {
|
|
|
|
|
std::vector<VkPhysicalDevice> Context::physical_devices() const {
|
|
|
|
|
uint32_t devices_count = 0;
|
|
|
|
|
vkEnumeratePhysicalDevices(m_instance, &devices_count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -320,7 +323,7 @@ std::vector<VkPhysicalDevice> VulkanContext::physical_devices() const {
|
|
|
|
|
return physical_devices;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkQueueFamilyProperties> VulkanContext::queue_families(VkPhysicalDevice physical_device) const {
|
|
|
|
|
std::vector<VkQueueFamilyProperties> Context::queue_families(VkPhysicalDevice physical_device) const {
|
|
|
|
|
uint32_t queue_families_count = 0;
|
|
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -330,7 +333,7 @@ std::vector<VkQueueFamilyProperties> VulkanContext::queue_families(VkPhysicalDev
|
|
|
|
|
return queue_families;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkExtensionProperties> VulkanContext::device_extensions(VkPhysicalDevice physical_device) const {
|
|
|
|
|
std::vector<VkExtensionProperties> Context::device_extensions(VkPhysicalDevice physical_device) const {
|
|
|
|
|
uint32_t extensions_count = 0;
|
|
|
|
|
vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &extensions_count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -340,7 +343,7 @@ std::vector<VkExtensionProperties> VulkanContext::device_extensions(VkPhysicalDe
|
|
|
|
|
return extensions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkSurfaceFormatKHR> VulkanContext::surface_formats(VkPhysicalDevice physical_device) const {
|
|
|
|
|
std::vector<VkSurfaceFormatKHR> Context::surface_formats(VkPhysicalDevice physical_device) const {
|
|
|
|
|
uint32_t surface_formats_count = 0;
|
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &surface_formats_count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -350,7 +353,7 @@ std::vector<VkSurfaceFormatKHR> VulkanContext::surface_formats(VkPhysicalDevice
|
|
|
|
|
return surface_formats;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<VkPresentModeKHR> VulkanContext::present_modes(VkPhysicalDevice physical_device) const {
|
|
|
|
|
std::vector<VkPresentModeKHR> Context::present_modes(VkPhysicalDevice physical_device) const {
|
|
|
|
|
uint32_t present_modes_count = 0;
|
|
|
|
|
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, m_surface, &present_modes_count, nullptr);
|
|
|
|
|
|
|
|
|
|
@@ -361,23 +364,23 @@ std::vector<VkPresentModeKHR> VulkanContext::present_modes(VkPhysicalDevice phys
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void VulkanContext::set_object_name(VkObjectType type, uint64_t object, const char* name) {
|
|
|
|
|
void Context::set_object_name(VkObjectType type, uint64_t object, const char* name) {
|
|
|
|
|
VkDebugUtilsObjectNameInfoEXT name_info {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
|
|
|
|
.objectType = type,
|
|
|
|
|
.objectHandle = object,
|
|
|
|
|
.pObjectName = name
|
|
|
|
|
};
|
|
|
|
|
if(vkeSetDebugUtilsObjectNameEXT(m_device, &name_info) != VK_SUCCESS)
|
|
|
|
|
if(setDebugUtilsObjectName(m_device, &name_info) != VK_SUCCESS)
|
|
|
|
|
throw std::runtime_error("failed to set debug name");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::set_object_name(VkObjectType type, uint64_t object, const std::string& name) {
|
|
|
|
|
void Context::set_object_name(VkObjectType type, uint64_t object, const std::string& name) {
|
|
|
|
|
set_object_name(type, object, name.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_instance(VkInstance& instance) {
|
|
|
|
|
void Context::destroy_instance(VkInstance& instance) {
|
|
|
|
|
if(instance == nullptr)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -385,15 +388,15 @@ void VulkanContext::destroy_instance(VkInstance& instance) {
|
|
|
|
|
instance = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_debug_messenger(VkDebugUtilsMessengerEXT& debug_messenger) {
|
|
|
|
|
void Context::destroy_debug_messenger(VkDebugUtilsMessengerEXT& debug_messenger) {
|
|
|
|
|
if(debug_messenger == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
vkeDestroyDebugUtilsMessengerEXT(m_instance, debug_messenger, nullptr);
|
|
|
|
|
destroyDebugUtilsMessenger(m_instance, debug_messenger, nullptr);
|
|
|
|
|
debug_messenger = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_surface(VkSurfaceKHR& surface) {
|
|
|
|
|
void Context::destroy_surface(VkSurfaceKHR& surface) {
|
|
|
|
|
if(surface == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -401,7 +404,7 @@ void VulkanContext::destroy_surface(VkSurfaceKHR& surface) {
|
|
|
|
|
surface = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_device(VkDevice& device) {
|
|
|
|
|
void Context::destroy_device(VkDevice& device) {
|
|
|
|
|
if(device == nullptr)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -409,7 +412,7 @@ void VulkanContext::destroy_device(VkDevice& device) {
|
|
|
|
|
device = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_swapchain(VkSwapchainKHR& swapchain) {
|
|
|
|
|
void Context::destroy_swapchain(VkSwapchainKHR& swapchain) {
|
|
|
|
|
if(swapchain == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -417,7 +420,7 @@ void VulkanContext::destroy_swapchain(VkSwapchainKHR& swapchain) {
|
|
|
|
|
swapchain = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_image(VkImage& image) {
|
|
|
|
|
void Context::destroy_image(VkImage& image) {
|
|
|
|
|
if(image == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -425,7 +428,7 @@ void VulkanContext::destroy_image(VkImage& image) {
|
|
|
|
|
image = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_image_view(VkImageView& image_view) {
|
|
|
|
|
void Context::destroy_image_view(VkImageView& image_view) {
|
|
|
|
|
if(image_view == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -433,7 +436,7 @@ void VulkanContext::destroy_image_view(VkImageView& image_view) {
|
|
|
|
|
image_view = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_framebuffer(VkFramebuffer& framebuffer) {
|
|
|
|
|
void Context::destroy_framebuffer(VkFramebuffer& framebuffer) {
|
|
|
|
|
if(framebuffer == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -441,7 +444,7 @@ void VulkanContext::destroy_framebuffer(VkFramebuffer& framebuffer) {
|
|
|
|
|
framebuffer = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_buffer(VkBuffer& buffer) {
|
|
|
|
|
void Context::destroy_buffer(VkBuffer& buffer) {
|
|
|
|
|
if(buffer == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -449,7 +452,7 @@ void VulkanContext::destroy_buffer(VkBuffer& buffer) {
|
|
|
|
|
buffer = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_command_pool(VkCommandPool& command_pool) {
|
|
|
|
|
void Context::destroy_command_pool(VkCommandPool& command_pool) {
|
|
|
|
|
if(command_pool == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -457,7 +460,7 @@ void VulkanContext::destroy_command_pool(VkCommandPool& command_pool) {
|
|
|
|
|
command_pool = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_render_pass(VkRenderPass& render_pass) {
|
|
|
|
|
void Context::destroy_render_pass(VkRenderPass& render_pass) {
|
|
|
|
|
if(render_pass == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -465,7 +468,7 @@ void VulkanContext::destroy_render_pass(VkRenderPass& render_pass) {
|
|
|
|
|
render_pass = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_pipeline_layout(VkPipelineLayout& pipeline_layout) {
|
|
|
|
|
void Context::destroy_pipeline_layout(VkPipelineLayout& pipeline_layout) {
|
|
|
|
|
if(pipeline_layout == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -473,7 +476,7 @@ void VulkanContext::destroy_pipeline_layout(VkPipelineLayout& pipeline_layout) {
|
|
|
|
|
pipeline_layout = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_pipeline(VkPipeline& pipeline) {
|
|
|
|
|
void Context::destroy_pipeline(VkPipeline& pipeline) {
|
|
|
|
|
if(pipeline == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -481,7 +484,7 @@ void VulkanContext::destroy_pipeline(VkPipeline& pipeline) {
|
|
|
|
|
pipeline = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_semaphore(VkSemaphore& semaphore) {
|
|
|
|
|
void Context::destroy_semaphore(VkSemaphore& semaphore) {
|
|
|
|
|
if(semaphore == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -489,7 +492,7 @@ void VulkanContext::destroy_semaphore(VkSemaphore& semaphore) {
|
|
|
|
|
semaphore = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_fence(VkFence& fence) {
|
|
|
|
|
void Context::destroy_fence(VkFence& fence) {
|
|
|
|
|
if(fence == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -497,7 +500,7 @@ void VulkanContext::destroy_fence(VkFence& fence) {
|
|
|
|
|
fence = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::free_memory(VkDeviceMemory& memory) {
|
|
|
|
|
void Context::free_memory(VkDeviceMemory& memory) {
|
|
|
|
|
if(memory == VK_NULL_HANDLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -505,7 +508,7 @@ void VulkanContext::free_memory(VkDeviceMemory& memory) {
|
|
|
|
|
memory = VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::create_instance(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::create_instance(const ContextSettings& settings) {
|
|
|
|
|
if(m_instance)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
@@ -527,7 +530,7 @@ void VulkanContext::create_instance(const VulkanContextSettings& settings) {
|
|
|
|
|
if(settings.debug()) {
|
|
|
|
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
|
|
|
|
|
|
|
|
|
auto const available_layers = VulkanContext::available_layers();
|
|
|
|
|
auto const available_layers = Context::available_layers();
|
|
|
|
|
|
|
|
|
|
auto add_layer_if_available = [&](const char* requested_layer) {
|
|
|
|
|
if(std::find_if(
|
|
|
|
|
@@ -587,17 +590,17 @@ void VulkanContext::create_instance(const VulkanContextSettings& settings) {
|
|
|
|
|
initialize_extension_functions();
|
|
|
|
|
|
|
|
|
|
if(settings.debug()) {
|
|
|
|
|
vkeCreateDebugUtilsMessengerEXT(
|
|
|
|
|
createDebugUtilsMessenger(
|
|
|
|
|
m_instance, &debug_info, nullptr, &m_debug_messenger);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::create_surface(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::create_surface(const ContextSettings& settings) {
|
|
|
|
|
if(!SDL_Vulkan_CreateSurface(m_window, m_instance, &m_surface))
|
|
|
|
|
throw std::runtime_error("failed to create surface");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::choose_physical_device(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::choose_physical_device(const ContextSettings& settings) {
|
|
|
|
|
auto physical_devices = this->physical_devices();
|
|
|
|
|
if(settings.physical_device()) {
|
|
|
|
|
auto const device_it = std::find_if(
|
|
|
|
|
@@ -617,8 +620,10 @@ void VulkanContext::choose_physical_device(const VulkanContextSettings& settings
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(auto const physical_device: physical_devices) {
|
|
|
|
|
if(select_physical_device(physical_device, settings)) {
|
|
|
|
|
auto maybe_properties = select_physical_device(physical_device, settings);
|
|
|
|
|
if(maybe_properties) {
|
|
|
|
|
m_physical_device = physical_device;
|
|
|
|
|
m_physical_device_properties = *maybe_properties;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -626,17 +631,14 @@ void VulkanContext::choose_physical_device(const VulkanContextSettings& settings
|
|
|
|
|
if(!m_physical_device)
|
|
|
|
|
throw std::runtime_error("failed to find suitable physical device");
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceProperties device_properties;
|
|
|
|
|
vkGetPhysicalDeviceProperties(m_physical_device, &device_properties);
|
|
|
|
|
|
|
|
|
|
logger.info() << "use suitable device: " << device_properties.deviceName;
|
|
|
|
|
logger.info() << "use suitable device: " << m_physical_device_properties.deviceName;
|
|
|
|
|
logger.debug() << "swapchain format: " << m_surface_format.format;
|
|
|
|
|
logger.debug() << "present mode: " << m_present_mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VulkanContext::select_physical_device(
|
|
|
|
|
std::optional<VkPhysicalDeviceProperties> Context::select_physical_device(
|
|
|
|
|
VkPhysicalDevice physical_device,
|
|
|
|
|
const VulkanContextSettings& settings
|
|
|
|
|
const ContextSettings& settings
|
|
|
|
|
) {
|
|
|
|
|
VkPhysicalDeviceProperties device_properties;
|
|
|
|
|
vkGetPhysicalDeviceProperties(physical_device, &device_properties);
|
|
|
|
|
@@ -675,7 +677,7 @@ bool VulkanContext::select_physical_device(
|
|
|
|
|
|
|
|
|
|
for(auto const queue_family: m_queue_families) {
|
|
|
|
|
if(queue_family == INVALID_QUEUE_FAMILY)
|
|
|
|
|
return false;
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto const available_extensions = this->device_extensions(physical_device);
|
|
|
|
|
@@ -691,15 +693,15 @@ bool VulkanContext::select_physical_device(
|
|
|
|
|
|
|
|
|
|
if(m_window) {
|
|
|
|
|
if(!has_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME))
|
|
|
|
|
return false;
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
|
|
auto const surface_formats = this->surface_formats(physical_device);
|
|
|
|
|
if(surface_formats.empty())
|
|
|
|
|
return false;
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
|
|
auto const present_modes = this->present_modes(physical_device);
|
|
|
|
|
if(present_modes.empty())
|
|
|
|
|
return false;
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
|
|
auto const surface_format_it = std::find_if(
|
|
|
|
|
surface_formats.begin(),
|
|
|
|
|
@@ -716,10 +718,10 @@ bool VulkanContext::select_physical_device(
|
|
|
|
|
m_present_mode = VK_PRESENT_MODE_FIFO_KHR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
return device_properties;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::create_device(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::create_device(const ContextSettings& settings) {
|
|
|
|
|
std::vector<uint32_t> queue_families = m_queue_families;
|
|
|
|
|
std::sort(queue_families.begin(), queue_families.end());
|
|
|
|
|
queue_families.erase(
|
|
|
|
|
@@ -776,7 +778,7 @@ void VulkanContext::create_device(const VulkanContextSettings& settings) {
|
|
|
|
|
vkGetDeviceQueue(m_device, m_presentation_queue_family, 0, &m_presentation_queue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::create_swapchain(const VulkanContextSettings& settings) {
|
|
|
|
|
void Context::create_swapchain(const ContextSettings& settings) {
|
|
|
|
|
m_swapchain_queue_families = {
|
|
|
|
|
m_presentation_queue_family,
|
|
|
|
|
};
|
|
|
|
|
@@ -793,7 +795,7 @@ void VulkanContext::create_swapchain(const VulkanContextSettings& settings) {
|
|
|
|
|
create_swapchain();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::create_swapchain() {
|
|
|
|
|
void Context::create_swapchain() {
|
|
|
|
|
VkSurfaceCapabilitiesKHR capabilities;
|
|
|
|
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physical_device, m_surface, &capabilities);
|
|
|
|
|
|
|
|
|
|
@@ -931,7 +933,7 @@ void VulkanContext::create_swapchain() {
|
|
|
|
|
callback(image_count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::destroy_swapchain() {
|
|
|
|
|
void Context::destroy_swapchain() {
|
|
|
|
|
for(auto& callback: m_swapchain_destruction_callbacks)
|
|
|
|
|
callback();
|
|
|
|
|
|
|
|
|
|
@@ -949,32 +951,32 @@ void VulkanContext::destroy_swapchain() {
|
|
|
|
|
destroy_swapchain(m_swapchain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::recreate_swapchain() {
|
|
|
|
|
void Context::recreate_swapchain() {
|
|
|
|
|
destroy_swapchain();
|
|
|
|
|
create_swapchain();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VulkanContext::initialize_extension_functions() {
|
|
|
|
|
void Context::initialize_extension_functions() {
|
|
|
|
|
uint32_t errors_count = 0;
|
|
|
|
|
|
|
|
|
|
#define GET_PROC_ADDR(func_name) \
|
|
|
|
|
vke ## func_name = (PFN_vk ## func_name)vkGetInstanceProcAddr( \
|
|
|
|
|
#define GET_PROC_ADDR(ptr_name, func_name) \
|
|
|
|
|
ptr_name = (PFN_vk ## func_name)vkGetInstanceProcAddr( \
|
|
|
|
|
m_instance, "vk" #func_name); \
|
|
|
|
|
if(vke ## func_name == nullptr) \
|
|
|
|
|
if(ptr_name == nullptr) \
|
|
|
|
|
{ \
|
|
|
|
|
logger.error() << "failed to load extension function 'vk" #func_name "'"; \
|
|
|
|
|
errors_count += 1; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GET_PROC_ADDR(CreateDebugUtilsMessengerEXT)
|
|
|
|
|
GET_PROC_ADDR(DestroyDebugUtilsMessengerEXT)
|
|
|
|
|
GET_PROC_ADDR(SetDebugUtilsObjectNameEXT)
|
|
|
|
|
GET_PROC_ADDR(createDebugUtilsMessenger, CreateDebugUtilsMessengerEXT)
|
|
|
|
|
GET_PROC_ADDR(destroyDebugUtilsMessenger, DestroyDebugUtilsMessengerEXT)
|
|
|
|
|
GET_PROC_ADDR(setDebugUtilsObjectName, SetDebugUtilsObjectNameEXT)
|
|
|
|
|
|
|
|
|
|
if(errors_count != 0)
|
|
|
|
|
throw std::runtime_error("failed to load extensions");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::log_debug_message(
|
|
|
|
|
VKAPI_ATTR VkBool32 VKAPI_CALL Context::log_debug_message(
|
|
|
|
|
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
|
|
|
|
VkDebugUtilsMessageTypeFlagsEXT type,
|
|
|
|
|
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
|
|
|
|
@@ -1014,6 +1016,5 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::log_debug_message(
|
|
|
|
|
return VK_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT = nullptr;
|
|
|
|
|
PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT = nullptr;
|
|
|
|
|
PFN_vkSetDebugUtilsObjectNameEXT vkeSetDebugUtilsObjectNameEXT = nullptr;
|
|
|
|
|
|
|
|
|
|
}
|