2025-12-03 00:11:15 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include <SDL3/SDL_video.h>
|
|
|
|
|
#include <VkBootstrap.h>
|
2025-12-04 18:26:27 +02:00
|
|
|
#include <smath.hpp>
|
2025-12-03 00:11:15 +02:00
|
|
|
#include <vk_mem_alloc.h>
|
|
|
|
|
#include <vulkan/vulkan_core.h>
|
|
|
|
|
|
|
|
|
|
#include "DeletionQueue.h"
|
2025-12-04 18:26:27 +02:00
|
|
|
#include "DescriptorAllocator.h"
|
2025-12-03 00:11:15 +02:00
|
|
|
#include "Logger.h"
|
|
|
|
|
|
|
|
|
|
namespace Lunar {
|
|
|
|
|
|
2025-12-04 18:26:27 +02:00
|
|
|
struct AllocatedImage {
|
|
|
|
|
VkImage image;
|
|
|
|
|
VkImageView image_view;
|
|
|
|
|
VmaAllocation allocation;
|
|
|
|
|
VkExtent3D extent;
|
|
|
|
|
VkFormat format;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct AllocatedBuffer {
|
|
|
|
|
VkBuffer buffer;
|
|
|
|
|
VmaAllocation allocation;
|
|
|
|
|
VmaAllocationInfo info;
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
struct FrameData {
|
|
|
|
|
VkCommandPool command_pool;
|
|
|
|
|
VkCommandBuffer main_command_buffer;
|
|
|
|
|
VkSemaphore swapchain_semaphore;
|
|
|
|
|
VkFence render_fence;
|
|
|
|
|
|
|
|
|
|
DeletionQueue deletion_queue;
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-04 18:26:27 +02:00
|
|
|
struct Vertex {
|
|
|
|
|
smath::Vec3 position;
|
|
|
|
|
float uv_x;
|
|
|
|
|
smath::Vec3 normal;
|
|
|
|
|
float uv_y;
|
|
|
|
|
smath::Vec4 color;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct GPUMeshBuffers {
|
|
|
|
|
AllocatedBuffer index_buffer, vertex_buffer;
|
|
|
|
|
VkDeviceAddress vertex_buffer_address;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct GPUDrawPushConstants {
|
|
|
|
|
smath::Mat4 world_matrix;
|
|
|
|
|
VkDeviceAddress vertex_buffer;
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
constexpr unsigned FRAME_OVERLAP = 2;
|
|
|
|
|
|
|
|
|
|
class VulkanRenderer {
|
|
|
|
|
public:
|
|
|
|
|
VulkanRenderer(SDL_Window *window, Logger &logger);
|
|
|
|
|
~VulkanRenderer();
|
|
|
|
|
|
|
|
|
|
auto render() -> void;
|
|
|
|
|
auto resize(uint32_t width, uint32_t height) -> void;
|
|
|
|
|
|
2025-12-03 02:31:38 +02:00
|
|
|
auto immediate_submit(std::function<void(VkCommandBuffer cmd)> &&function)
|
|
|
|
|
-> void;
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
private:
|
|
|
|
|
auto vk_init() -> void;
|
|
|
|
|
auto swapchain_init() -> void;
|
|
|
|
|
auto commands_init() -> void;
|
|
|
|
|
auto sync_init() -> void;
|
|
|
|
|
auto descriptors_init() -> void;
|
|
|
|
|
auto pipelines_init() -> void;
|
|
|
|
|
auto background_pipelines_init() -> void;
|
2025-12-04 13:31:00 +02:00
|
|
|
auto triangle_pipeline_init() -> void;
|
2025-12-04 18:26:27 +02:00
|
|
|
auto mesh_pipeline_init() -> void;
|
2025-12-03 02:31:38 +02:00
|
|
|
auto imgui_init() -> void;
|
2025-12-04 18:26:27 +02:00
|
|
|
auto default_data_init() -> void;
|
2025-12-03 00:11:15 +02:00
|
|
|
|
|
|
|
|
auto draw_background(VkCommandBuffer cmd) -> void;
|
2025-12-04 13:31:00 +02:00
|
|
|
auto draw_geometry(VkCommandBuffer cmd) -> void;
|
2025-12-03 02:31:38 +02:00
|
|
|
auto draw_imgui(VkCommandBuffer cmd, VkImageView target_image_view) -> void;
|
2025-12-03 00:11:15 +02:00
|
|
|
|
|
|
|
|
auto create_swapchain(uint32_t width, uint32_t height) -> void;
|
|
|
|
|
auto create_draw_image(uint32_t width, uint32_t height) -> void;
|
|
|
|
|
auto update_draw_image_descriptor() -> void;
|
|
|
|
|
auto destroy_draw_image() -> void;
|
|
|
|
|
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
|
|
|
|
|
auto destroy_swapchain() -> void;
|
|
|
|
|
|
2025-12-04 18:26:27 +02:00
|
|
|
auto create_buffer(size_t alloc_size, VkBufferUsageFlags usage,
|
|
|
|
|
VmaMemoryUsage memory_usage) -> AllocatedBuffer;
|
|
|
|
|
auto destroy_buffer(AllocatedBuffer &buffer) -> void;
|
|
|
|
|
auto upload_mesh(std::span<uint32_t> indices, std::span<Vertex> vertices)
|
|
|
|
|
-> GPUMeshBuffers;
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
struct {
|
|
|
|
|
vkb::Instance instance;
|
|
|
|
|
vkb::PhysicalDevice phys_dev;
|
|
|
|
|
vkb::Device dev;
|
|
|
|
|
vkb::Swapchain swapchain;
|
|
|
|
|
} m_vkb;
|
|
|
|
|
|
|
|
|
|
struct {
|
2025-12-03 02:31:38 +02:00
|
|
|
auto get_current_frame() -> FrameData &
|
|
|
|
|
{
|
|
|
|
|
return frames.at(frame_number % frames.size());
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
VkSwapchainKHR swapchain { VK_NULL_HANDLE };
|
|
|
|
|
VkSurfaceKHR surface { nullptr };
|
|
|
|
|
VkFormat swapchain_image_format;
|
|
|
|
|
|
|
|
|
|
uint32_t graphics_queue_family { 0 };
|
|
|
|
|
VkQueue graphics_queue { nullptr };
|
|
|
|
|
|
|
|
|
|
std::vector<VkImage> swapchain_images;
|
|
|
|
|
std::vector<VkImageView> swapchain_image_views;
|
|
|
|
|
std::vector<VkSemaphore> present_semaphores;
|
|
|
|
|
VkExtent2D swapchain_extent;
|
|
|
|
|
|
|
|
|
|
std::array<FrameData, FRAME_OVERLAP> frames;
|
|
|
|
|
AllocatedImage draw_image {};
|
|
|
|
|
VkExtent2D draw_extent {};
|
|
|
|
|
|
|
|
|
|
VmaAllocator allocator;
|
|
|
|
|
DescriptorAllocator descriptor_allocator;
|
|
|
|
|
|
|
|
|
|
VkDescriptorSet draw_image_descriptors;
|
|
|
|
|
VkDescriptorSetLayout draw_image_descriptor_layout;
|
|
|
|
|
|
|
|
|
|
VkPipeline gradient_pipeline {};
|
|
|
|
|
VkPipelineLayout gradient_pipeline_layout {};
|
|
|
|
|
|
2025-12-04 13:31:00 +02:00
|
|
|
VkPipeline triangle_pipeline {};
|
|
|
|
|
VkPipelineLayout triangle_pipeline_layout {};
|
|
|
|
|
|
2025-12-04 18:26:27 +02:00
|
|
|
VkPipeline mesh_pipeline {};
|
|
|
|
|
VkPipelineLayout mesh_pipeline_layout {};
|
|
|
|
|
|
|
|
|
|
GPUMeshBuffers rectangle;
|
|
|
|
|
|
2025-12-03 02:37:39 +02:00
|
|
|
VkDescriptorPool imgui_descriptor_pool { VK_NULL_HANDLE };
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
DeletionQueue deletion_queue;
|
|
|
|
|
|
2025-12-03 02:31:38 +02:00
|
|
|
VkFence imm_fence {};
|
|
|
|
|
VkCommandBuffer imm_command_buffer {};
|
|
|
|
|
VkCommandPool imm_command_pool {};
|
|
|
|
|
|
2025-12-03 00:11:15 +02:00
|
|
|
uint64_t frame_number { 0 };
|
|
|
|
|
} m_vk;
|
|
|
|
|
|
|
|
|
|
SDL_Window *m_window { nullptr };
|
|
|
|
|
Logger &m_logger;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace Lunar
|