8 changed files with 1465 additions and 708 deletions
File diff suppressed because it is too large
@ -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
Loading…
Reference in new issue