Refacto: Move basic setup to VulkanContext class.
This commit is contained in:
@@ -34,6 +34,7 @@ add_executable(vk_expe
|
|||||||
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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -83,5 +83,6 @@ void VkExpe::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_vulkan.draw_frame();
|
m_vulkan.draw_frame();
|
||||||
|
// m_running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1019
src/VulkanContext.cpp
Normal file
1019
src/VulkanContext.cpp
Normal file
File diff suppressed because it is too large
Load Diff
215
src/VulkanContext.h
Normal file
215
src/VulkanContext.h
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
|
class VulkanContext;
|
||||||
|
|
||||||
|
class VulkanContextSettings {
|
||||||
|
public:
|
||||||
|
struct QueueInfo {
|
||||||
|
uint32_t index;
|
||||||
|
VkQueueFlagBits flags;
|
||||||
|
bool use_swapchain_images;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
VulkanContextSettings();
|
||||||
|
~VulkanContextSettings();
|
||||||
|
|
||||||
|
bool debug() const;
|
||||||
|
VulkanContextSettings& with_debug(bool enabled=true);
|
||||||
|
|
||||||
|
const std::optional<Uuid>& physical_device() const;
|
||||||
|
VulkanContextSettings& with_physical_device(Uuid uuid);
|
||||||
|
|
||||||
|
const std::vector<QueueInfo>& queues() const;
|
||||||
|
VulkanContextSettings& with_queue(uint32_t index, VkQueueFlagBits flags, bool use_swapchain_images=false);
|
||||||
|
|
||||||
|
SDL_Window* window() const;
|
||||||
|
VulkanContextSettings& with_window(SDL_Window* window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_debug = false;
|
||||||
|
std::optional<Uuid> m_physical_device;
|
||||||
|
std::vector<QueueInfo> m_queues;
|
||||||
|
SDL_Window* m_window = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t INVALID_QUEUE_FAMILY = UINT32_MAX;
|
||||||
|
|
||||||
|
class VulkanContext {
|
||||||
|
public:
|
||||||
|
static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX;
|
||||||
|
static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
|
|
||||||
|
using SwapchainCreationCallback = std::function<void(uint32_t)>;
|
||||||
|
using SwapchainDestructionCallback = std::function<void()>;
|
||||||
|
using ContextDestructionCallback = std::function<void()>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VulkanContext();
|
||||||
|
VulkanContext(const VulkanContext&) = delete;
|
||||||
|
~VulkanContext();
|
||||||
|
|
||||||
|
VulkanContext& operator=(const VulkanContext&) = delete;
|
||||||
|
|
||||||
|
VkInstance instance();
|
||||||
|
VkPhysicalDevice physical_device();
|
||||||
|
VkDevice device();
|
||||||
|
uint32_t queue_family(size_t queue_index) const;
|
||||||
|
VkQueue queue(size_t queue_index);
|
||||||
|
|
||||||
|
VkSurfaceKHR surface();
|
||||||
|
VkSwapchainKHR swapchain();
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR surface_format() const;
|
||||||
|
VkPresentModeKHR present_mode() const;
|
||||||
|
VkExtent2D swapchain_extent() const;
|
||||||
|
size_t swapchain_image_count() const;
|
||||||
|
uint32_t current_image_index() const;
|
||||||
|
VkImage swapchain_image();
|
||||||
|
VkImage swapchain_image(size_t image_index);
|
||||||
|
VkImageView swapchain_image_view();
|
||||||
|
VkImageView swapchain_image_view(size_t image_index);
|
||||||
|
// VkFramebuffer framebuffer();
|
||||||
|
VkSemaphore ready_to_render();
|
||||||
|
VkFence render_done();
|
||||||
|
|
||||||
|
|
||||||
|
void initialize(const VulkanContextSettings& settings);
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
void begin_frame();
|
||||||
|
void swap_buffers(uint32_t semaphore_count, VkSemaphore* wait_semaphores);
|
||||||
|
|
||||||
|
void invalidate_swapchain();
|
||||||
|
|
||||||
|
void register_swapchain_creation_callback(SwapchainCreationCallback callback);
|
||||||
|
void register_swapchain_destruction_callback(SwapchainDestructionCallback callback);
|
||||||
|
void register_context_destruction_callback(ContextDestructionCallback callback);
|
||||||
|
|
||||||
|
|
||||||
|
static std::vector<VkExtensionProperties> available_extensions();
|
||||||
|
static std::vector<VkLayerProperties> available_layers();
|
||||||
|
|
||||||
|
std::vector<const char*> sdl_vulkan_extensions() const;
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> physical_devices() const;
|
||||||
|
std::vector<VkQueueFamilyProperties> queue_families(VkPhysicalDevice physical_device) const;
|
||||||
|
std::vector<VkExtensionProperties> device_extensions(VkPhysicalDevice physical_device) const;
|
||||||
|
std::vector<VkSurfaceFormatKHR> surface_formats(VkPhysicalDevice physical_device) const;
|
||||||
|
std::vector<VkPresentModeKHR> present_modes(VkPhysicalDevice physical_device) const;
|
||||||
|
|
||||||
|
|
||||||
|
void set_object_name(VkObjectType type, uint64_t object, const char* name);
|
||||||
|
void set_object_name(VkObjectType type, uint64_t object, const std::string& name);
|
||||||
|
|
||||||
|
|
||||||
|
void destroy_instance(VkInstance& instance);
|
||||||
|
void destroy_debug_messenger(VkDebugUtilsMessengerEXT& debug_messenger);
|
||||||
|
void destroy_surface(VkSurfaceKHR& surface);
|
||||||
|
void destroy_device(VkDevice& device);
|
||||||
|
void destroy_swapchain(VkSwapchainKHR& swapchain);
|
||||||
|
|
||||||
|
void destroy_image(VkImage& image);
|
||||||
|
void destroy_image_view(VkImageView& image_view);
|
||||||
|
void destroy_framebuffer(VkFramebuffer& framebuffer);
|
||||||
|
|
||||||
|
void destroy_buffer(VkBuffer& buffer);
|
||||||
|
|
||||||
|
void destroy_command_pool(VkCommandPool& command_pool);
|
||||||
|
|
||||||
|
void destroy_render_pass(VkRenderPass& render_pass);
|
||||||
|
void destroy_pipeline_layout(VkPipelineLayout& pipeline_layout);
|
||||||
|
void destroy_pipeline(VkPipeline& pipeline);
|
||||||
|
|
||||||
|
void destroy_semaphore(VkSemaphore& semaphore);
|
||||||
|
void destroy_fence(VkFence& fence);
|
||||||
|
|
||||||
|
void free_memory(VkDeviceMemory& memory);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ImageResources {
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
VkFence render_done = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FrameResources {
|
||||||
|
VkSemaphore ready_to_render = VK_NULL_HANDLE;
|
||||||
|
VkFence render_done = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void create_instance(const VulkanContextSettings& settings);
|
||||||
|
void create_surface(const VulkanContextSettings& settings);
|
||||||
|
void choose_physical_device(const VulkanContextSettings& settings);
|
||||||
|
bool select_physical_device(
|
||||||
|
VkPhysicalDevice physical_device,
|
||||||
|
const VulkanContextSettings& settings
|
||||||
|
);
|
||||||
|
void create_device(const VulkanContextSettings& settings);
|
||||||
|
void create_swapchain(const VulkanContextSettings& settings);
|
||||||
|
void create_swapchain();
|
||||||
|
|
||||||
|
void destroy_swapchain();
|
||||||
|
void recreate_swapchain();
|
||||||
|
|
||||||
|
void initialize_extension_functions();
|
||||||
|
|
||||||
|
static VKAPI_ATTR VkBool32 VKAPI_CALL log_debug_message(
|
||||||
|
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||||
|
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||||
|
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
||||||
|
void* user_data
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Window* m_window = nullptr;
|
||||||
|
|
||||||
|
VkInstance m_instance = nullptr;
|
||||||
|
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
|
||||||
|
VkPhysicalDevice m_physical_device = nullptr;
|
||||||
|
VkDevice m_device = nullptr;
|
||||||
|
|
||||||
|
std::vector<uint32_t> m_queue_families;
|
||||||
|
uint32_t m_presentation_queue_family = UINT32_MAX;
|
||||||
|
std::vector<VkQueue> m_queues;
|
||||||
|
VkQueue m_presentation_queue = nullptr;
|
||||||
|
|
||||||
|
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||||
|
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR m_surface_format;
|
||||||
|
VkPresentModeKHR m_present_mode;
|
||||||
|
VkExtent2D m_swapchain_extent;
|
||||||
|
std::vector<uint32_t> m_swapchain_queue_families;
|
||||||
|
std::vector<ImageResources> m_image_resources;
|
||||||
|
std::vector<FrameResources> m_frame_resources;
|
||||||
|
bool m_invalid_swapchain = false;
|
||||||
|
|
||||||
|
std::vector<SwapchainCreationCallback> m_swapchain_creation_callbacks;
|
||||||
|
std::vector<SwapchainDestructionCallback> m_swapchain_destruction_callbacks;
|
||||||
|
std::vector<ContextDestructionCallback> m_context_destruction_callbacks;
|
||||||
|
|
||||||
|
uint32_t m_current_image_index = CURRENT_IMAGE_INDEX;
|
||||||
|
size_t m_frame_index = 0;
|
||||||
|
size_t m_frame_resources_index = 0;
|
||||||
|
|
||||||
|
friend class VulkanContextSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
|
||||||
|
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
|
||||||
|
extern PFN_vkSetDebugUtilsObjectNameEXT vkeSetDebugUtilsObjectNameEXT;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VulkanContext.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
|
|
||||||
#define VKEXPE_VALIDATION true
|
|
||||||
#else
|
|
||||||
#define VKEXPE_VALIDATION false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
|
|
||||||
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
|
|
||||||
|
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
Eigen::Vector2f position;
|
Eigen::Vector2f position;
|
||||||
Eigen::Vector3f color;
|
Eigen::Vector3f color;
|
||||||
@@ -26,6 +18,11 @@ struct Vertex {
|
|||||||
|
|
||||||
|
|
||||||
class VulkanTutorial {
|
class VulkanTutorial {
|
||||||
|
public:
|
||||||
|
enum QueueIndex {
|
||||||
|
GRAPHIC_QUEUE,
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VulkanTutorial();
|
VulkanTutorial();
|
||||||
VulkanTutorial(const VulkanTutorial&) = delete;
|
VulkanTutorial(const VulkanTutorial&) = delete;
|
||||||
@@ -39,59 +36,27 @@ public:
|
|||||||
void draw_frame();
|
void draw_frame();
|
||||||
void invalidate_swapchain();
|
void invalidate_swapchain();
|
||||||
|
|
||||||
static std::vector<VkExtensionProperties> available_extensions();
|
|
||||||
static std::vector<VkLayerProperties> available_layers();
|
|
||||||
|
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL print_debug_message(
|
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
|
||||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
|
||||||
void* user_data
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create_instance();
|
void create_swapchain_objects(uint32_t image_count);
|
||||||
void create_surface();
|
void destroy_swapchain_objects();
|
||||||
void find_physical_device();
|
|
||||||
void create_device();
|
|
||||||
void create_swapchain();
|
|
||||||
void create_render_pass();
|
void create_render_pass();
|
||||||
void create_graphic_pipeline();
|
void create_graphic_pipeline();
|
||||||
void create_framebuffers();
|
void create_framebuffers();
|
||||||
void create_command_pool();
|
void create_command_pool();
|
||||||
void create_vertex_buffer();
|
void create_vertex_buffer();
|
||||||
void create_command_buffers();
|
void create_command_buffers();
|
||||||
void create_sync_objects();
|
|
||||||
|
|
||||||
void cleanup_swap_chain();
|
|
||||||
void recreate_swap_chain();
|
|
||||||
|
|
||||||
VkShaderModule create_shader_module(const std::vector<char> bytecode);
|
VkShaderModule create_shader_module(const std::vector<char> bytecode);
|
||||||
VkShaderModule create_shader_module_from_file(const char* path);
|
VkShaderModule create_shader_module_from_file(const char* path);
|
||||||
|
|
||||||
int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties);
|
int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties);
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> get_physical_devices() const;
|
|
||||||
std::vector<VkQueueFamilyProperties> get_queue_families(VkPhysicalDevice physical_device) const;
|
|
||||||
std::vector<VkExtensionProperties> get_device_extensions(VkPhysicalDevice physical_device) const;
|
|
||||||
std::vector<VkSurfaceFormatKHR> get_surface_formats(VkPhysicalDevice physical_device) const;
|
|
||||||
std::vector<VkPresentModeKHR> get_present_modes(VkPhysicalDevice physical_device) const;
|
|
||||||
|
|
||||||
void initialize_extension_functions();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Window* m_window = nullptr;
|
VulkanContext m_context;
|
||||||
|
|
||||||
VkInstance m_instance = nullptr;
|
|
||||||
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
|
|
||||||
VkSurfaceKHR m_surface;
|
|
||||||
VkPhysicalDevice m_physical_device = nullptr;
|
|
||||||
VkDevice m_device = nullptr;
|
|
||||||
VkQueue m_graphic_queue = nullptr;
|
VkQueue m_graphic_queue = nullptr;
|
||||||
VkQueue m_presentation_queue = nullptr;
|
VkQueue m_presentation_queue = nullptr;
|
||||||
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
|
||||||
std::vector<VkImage> m_swapchain_images;
|
|
||||||
std::vector<VkImageView> m_swapchain_image_views;
|
|
||||||
VkRenderPass m_render_pass = VK_NULL_HANDLE;
|
VkRenderPass m_render_pass = VK_NULL_HANDLE;
|
||||||
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
|
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
|
||||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||||
@@ -100,22 +65,5 @@ private:
|
|||||||
VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
|
VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE;
|
VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE;
|
||||||
std::vector<VkCommandBuffer> m_command_buffers;
|
std::vector<VkCommandBuffer> m_command_buffers;
|
||||||
std::vector<VkSemaphore> m_image_available_semaphores;
|
std::vector<VkSemaphore> m_render_done;
|
||||||
std::vector<VkSemaphore> m_render_finished_semaphores;
|
|
||||||
std::vector<VkFence> m_in_flight_fence;
|
|
||||||
std::vector<VkFence> m_images_in_flight;
|
|
||||||
|
|
||||||
uint32_t m_graphic_queue_family = -1;
|
|
||||||
uint32_t m_presentation_queue_family = -1;
|
|
||||||
VkSurfaceFormatKHR m_swapchain_format;
|
|
||||||
VkPresentModeKHR m_present_mode;
|
|
||||||
VkExtent2D m_swapchain_extent;
|
|
||||||
|
|
||||||
size_t m_frame_index = 0;
|
|
||||||
bool m_invalid_swapchain = true;
|
|
||||||
|
|
||||||
VkDebugUtilsMessengerCreateInfoEXT m_debug_info;
|
|
||||||
bool m_enableValidation = VKEXPE_VALIDATION;
|
|
||||||
|
|
||||||
static constexpr size_t MAX_FRAMES_IN_FLIGHT = 2;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
|
Uuid make_uuid(uint8_t const* bytes) {
|
||||||
|
Uuid uuid;
|
||||||
|
std::memcpy(uuid.data(), bytes, UUID_SIZE);
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<char> read_binary_file(const char* path) {
|
std::vector<char> read_binary_file(const char* path) {
|
||||||
std::ifstream istream(path, std::ios_base::ate | std::ios_base::binary);
|
std::ifstream istream(path, std::ios_base::ate | std::ios_base::binary);
|
||||||
if(!istream.is_open())
|
if(!istream.is_open())
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
|
||||||
|
constexpr size_t UUID_SIZE = 16;
|
||||||
|
using Uuid = std::array<uint8_t, UUID_SIZE>;
|
||||||
|
Uuid make_uuid(uint8_t const* bytes);
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
Reference in New Issue
Block a user