Browse Source

Move Vulkan stuff in a separate directory.

master
Draklaw 4 years ago
parent
commit
dadbbc9ce8
  1. 6
      CMakeLists.txt
  2. 2
      src/Logger.cpp
  3. 6
      src/VkExpe.cpp
  4. 2
      src/VkExpe.h
  5. 207
      src/Vulkan/Context.cpp
  6. 61
      src/Vulkan/Context.h
  7. 8
      src/VulkanTutorial.cpp
  8. 4
      src/VulkanTutorial.h
  9. 4
      src/main.cpp
  10. 2
      src/utils.cpp

6
CMakeLists.txt

@ -30,11 +30,11 @@ function(add_shaders TARGET)
endfunction() endfunction()
add_executable(vk_expe add_executable(vk_expe
src/Vulkan/Context.cpp
src/main.cpp src/main.cpp
src/utils.cpp src/utils.cpp
src/Logger.cpp src/Logger.cpp
src/VkExpe.cpp src/VkExpe.cpp
src/VulkanContext.cpp
src/VulkanTutorial.cpp src/VulkanTutorial.cpp
) )
@ -43,6 +43,10 @@ add_shaders(vk_expe
shaders/shader.frag shaders/shader.frag
) )
target_include_directories(vk_expe
PRIVATE src
)
target_compile_features(vk_expe target_compile_features(vk_expe
PUBLIC cxx_std_17 PUBLIC cxx_std_17
) )

2
src/Logger.cpp

@ -1,4 +1,4 @@
#include "Logger.h" #include <Logger.h>
#include <iostream> #include <iostream>

6
src/VkExpe.cpp

@ -1,7 +1,7 @@
#include "VkExpe.h" #include <VkExpe.h>
#include "utils.h" #include <utils.h>
#include "Logger.h" #include <Logger.h>
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>

2
src/VkExpe.h

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "VulkanTutorial.h" #include <VulkanTutorial.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>

207
src/VulkanContext.cpp → src/Vulkan/Context.cpp

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

61
src/VulkanContext.h → src/Vulkan/Context.h

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "utils.h" #include <utils.h>
#include "Logger.h" #include <Logger.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
@ -12,9 +12,12 @@
#include <functional> #include <functional>
class VulkanContext; namespace Vulkan {
class VulkanContextSettings {
class Context;
class ContextSettings {
public: public:
struct QueueInfo { struct QueueInfo {
uint32_t index; uint32_t index;
@ -23,20 +26,20 @@ public:
}; };
public: public:
VulkanContextSettings(); ContextSettings();
~VulkanContextSettings(); ~ContextSettings();
bool debug() const; bool debug() const;
VulkanContextSettings& with_debug(bool enabled=true); ContextSettings& with_debug(bool enabled=true);
const std::optional<Uuid>& physical_device() const; const std::optional<Uuid>& physical_device() const;
VulkanContextSettings& with_physical_device(Uuid uuid); ContextSettings& with_physical_device(Uuid uuid);
const std::vector<QueueInfo>& queues() const; const std::vector<QueueInfo>& queues() const;
VulkanContextSettings& with_queue(uint32_t index, VkQueueFlagBits flags, bool use_swapchain_images=false); ContextSettings& with_queue(uint32_t index, VkQueueFlagBits flags, bool use_swapchain_images=false);
SDL_Window* window() const; SDL_Window* window() const;
VulkanContextSettings& with_window(SDL_Window* window); ContextSettings& with_window(SDL_Window* window);
private: private:
bool m_debug = false; bool m_debug = false;
@ -47,7 +50,7 @@ private:
constexpr uint32_t INVALID_QUEUE_FAMILY = UINT32_MAX; constexpr uint32_t INVALID_QUEUE_FAMILY = UINT32_MAX;
class VulkanContext { class Context {
public: public:
static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX; static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX;
static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2; static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2;
@ -57,11 +60,11 @@ public:
using ContextDestructionCallback = std::function<void()>; using ContextDestructionCallback = std::function<void()>;
public: public:
VulkanContext(); Context();
VulkanContext(const VulkanContext&) = delete; Context(const Context&) = delete;
~VulkanContext(); ~Context();
VulkanContext& operator=(const VulkanContext&) = delete; Context& operator=(const Context&) = delete;
VkInstance instance(); VkInstance instance();
VkPhysicalDevice physical_device(); VkPhysicalDevice physical_device();
@ -86,7 +89,7 @@ public:
VkFence render_done(); VkFence render_done();
void initialize(const VulkanContextSettings& settings); void initialize(const ContextSettings& settings);
void shutdown(); void shutdown();
void begin_frame(); void begin_frame();
@ -138,6 +141,10 @@ public:
void free_memory(VkDeviceMemory& memory); void free_memory(VkDeviceMemory& memory);
PFN_vkCreateDebugUtilsMessengerEXT createDebugUtilsMessenger = nullptr;
PFN_vkDestroyDebugUtilsMessengerEXT destroyDebugUtilsMessenger = nullptr;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName = nullptr;
private: private:
struct ImageResources { struct ImageResources {
VkImage image = VK_NULL_HANDLE; VkImage image = VK_NULL_HANDLE;
@ -151,15 +158,15 @@ private:
}; };
private: private:
void create_instance(const VulkanContextSettings& settings); void create_instance(const ContextSettings& settings);
void create_surface(const VulkanContextSettings& settings); void create_surface(const ContextSettings& settings);
void choose_physical_device(const VulkanContextSettings& settings); void choose_physical_device(const ContextSettings& settings);
bool select_physical_device( std::optional<VkPhysicalDeviceProperties> select_physical_device(
VkPhysicalDevice physical_device, VkPhysicalDevice physical_device,
const VulkanContextSettings& settings const ContextSettings& settings
); );
void create_device(const VulkanContextSettings& settings); void create_device(const ContextSettings& settings);
void create_swapchain(const VulkanContextSettings& settings); void create_swapchain(const ContextSettings& settings);
void create_swapchain(); void create_swapchain();
void destroy_swapchain(); void destroy_swapchain();
@ -181,6 +188,7 @@ private:
VkInstance m_instance = nullptr; VkInstance m_instance = nullptr;
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
VkPhysicalDevice m_physical_device = nullptr; VkPhysicalDevice m_physical_device = nullptr;
VkPhysicalDeviceProperties m_physical_device_properties;
VkDevice m_device = nullptr; VkDevice m_device = nullptr;
std::vector<uint32_t> m_queue_families; std::vector<uint32_t> m_queue_families;
@ -207,9 +215,8 @@ private:
size_t m_frame_index = 0; size_t m_frame_index = 0;
size_t m_frame_resources_index = 0; size_t m_frame_resources_index = 0;
friend class VulkanContextSettings; friend class ContextSettings;
}; };
extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT; }
extern PFN_vkSetDebugUtilsObjectNameEXT vkeSetDebugUtilsObjectNameEXT;

8
src/VulkanTutorial.cpp

@ -1,7 +1,7 @@
#include "VulkanTutorial.h" #include <VulkanTutorial.h>
#include "utils.h" #include <utils.h>
#include "Logger.h" #include <Logger.h>
#include <SDL2/SDL_vulkan.h> #include <SDL2/SDL_vulkan.h>
@ -58,7 +58,7 @@ VulkanTutorial::~VulkanTutorial() {
} }
void VulkanTutorial::initialize(SDL_Window* window) { void VulkanTutorial::initialize(SDL_Window* window) {
auto const settings = VulkanContextSettings() auto const settings = Vulkan::ContextSettings()
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG) #if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
.with_debug(true) .with_debug(true)
#endif #endif

4
src/VulkanTutorial.h

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "VulkanContext.h" #include <Vulkan/Context.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
@ -53,7 +53,7 @@ private:
int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties); int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties);
private: private:
VulkanContext m_context; Vulkan::Context m_context;
VkQueue m_graphic_queue = nullptr; VkQueue m_graphic_queue = nullptr;
VkQueue m_presentation_queue = nullptr; VkQueue m_presentation_queue = nullptr;

4
src/main.cpp

@ -1,5 +1,5 @@
#include "Logger.h" #include <Logger.h>
#include "VkExpe.h" #include <VkExpe.h>
#include <iostream> #include <iostream>

2
src/utils.cpp

@ -1,4 +1,4 @@
#include "utils.h" #include <utils.h>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>

Loading…
Cancel
Save