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