diff --git a/engine/include/nova/render/render_driver.h b/engine/include/nova/render/render_driver.h index 5ed9e03..136cddb 100644 --- a/engine/include/nova/render/render_driver.h +++ b/engine/include/nova/render/render_driver.h @@ -36,16 +36,17 @@ namespace Nova { [[nodiscard]] virtual SwapchainID create_swapchain(SurfaceID surface) = 0; virtual void resize_swapchain(SwapchainID swapchain) = 0; + [[nodiscard]] virtual RenderPassID get_swapchain_render_pass(SwapchainID swapchain) const = 0; virtual void destroy_swapchain(SwapchainID swapchain) = 0; [[nodiscard]] virtual ShaderID create_shader(const std::span bytes, ShaderStage stage) = 0; virtual void destroy_shader(ShaderID shader) = 0; + [[nodiscard]] virtual RenderPassID create_render_pass(RenderPassParams& params) = 0; + virtual void destroy_render_pass(RenderPassID render_pass) = 0; + [[nodiscard]] virtual PipelineID create_pipeline(GraphicsPipelineParams& params) = 0; [[nodiscard]] virtual PipelineID create_pipeline(ComputePipelineParams& params) = 0; virtual void destroy_pipeline(PipelineID pipeline) = 0; - - [[nodiscard]] virtual RenderPassID create_render_pass() = 0; - virtual void destroy_render_pass(RenderPassID render_pass) = 0; }; } // namespace Nova diff --git a/engine/include/nova/render/render_fwd.h b/engine/include/nova/render/render_fwd.h index 30bc9c1..4e63411 100644 --- a/engine/include/nova/render/render_fwd.h +++ b/engine/include/nova/render/render_fwd.h @@ -242,6 +242,7 @@ namespace Nova { struct VertexAttribute; struct VertexBinding; + struct RenderPassParams; struct GraphicsPipelineParams; struct ComputePipelineParams; diff --git a/engine/include/nova/render/render_params.h b/engine/include/nova/render/render_params.h index 2777b06..4e63242 100644 --- a/engine/include/nova/render/render_params.h +++ b/engine/include/nova/render/render_params.h @@ -25,6 +25,8 @@ namespace Nova { InputRate rate = InputRate::VERTEX; }; + struct RenderPassParams {}; + struct GraphicsPipelineParams { std::vector shaders; std::vector bindings; @@ -52,5 +54,6 @@ namespace Nova { RenderPassID render_pass = nullptr; u32 subpass = 0; }; + struct ComputePipelineParams {}; } // namespace Nova diff --git a/engine/src/drivers/vulkan/render_driver.cpp b/engine/src/drivers/vulkan/render_driver.cpp index 08541ce..2618b91 100644 --- a/engine/src/drivers/vulkan/render_driver.cpp +++ b/engine/src/drivers/vulkan/render_driver.cpp @@ -422,7 +422,39 @@ SwapchainID VulkanRenderDriver::create_swapchain(SurfaceID p_surface) { throw std::runtime_error("Failed to find a supported swapchain format"); } - // TODO: Create render pass + VkAttachmentDescription attachment {}; + attachment.format = swapchain->format; + attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference color_ref {}; + color_ref.attachment = 0; + color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_ref; + + VkRenderPassCreateInfo pass_create {}; + pass_create.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + pass_create.attachmentCount = 1; + pass_create.pAttachments = &attachment; + pass_create.subpassCount = 1; + pass_create.pSubpasses = &subpass; + + swapchain->render_pass = new RenderPass(); + if (vkCreateRenderPass(m_device, &pass_create, get_allocator(VK_OBJECT_TYPE_RENDER_PASS), &swapchain->render_pass->handle) + != VK_SUCCESS) { + throw std::runtime_error("Failed to create render pass"); + } + + // TODO: Change VkRenderPass to VkRenderPass2KHR (Vulkan 1.2+) return swapchain; } @@ -535,6 +567,11 @@ void VulkanRenderDriver::resize_swapchain(SwapchainID p_swapchain) { // TODO: Create framebuffers } +RenderPassID VulkanRenderDriver::get_swapchain_render_pass(SwapchainID p_swapchain) const { + NOVA_ASSERT(p_swapchain); + return p_swapchain->render_pass; +} + void VulkanRenderDriver::destroy_swapchain(SwapchainID p_swapchain) { NOVA_AUTO_TRACE(); NOVA_ASSERT(p_swapchain); @@ -548,7 +585,10 @@ void VulkanRenderDriver::destroy_swapchain(SwapchainID p_swapchain) { if (p_swapchain->handle) { vkDestroySwapchainKHR(m_device, p_swapchain->handle, get_allocator(VK_OBJECT_TYPE_SWAPCHAIN_KHR)); } - // TODO: Destroy render pass + if (p_swapchain->render_pass) { + destroy_render_pass(p_swapchain->render_pass); + p_swapchain->render_pass = nullptr; + } delete p_swapchain; } @@ -584,6 +624,23 @@ void VulkanRenderDriver::destroy_shader(ShaderID p_shader) { delete p_shader; } +RenderPassID VulkanRenderDriver::create_render_pass(RenderPassParams& p_params) { + NOVA_AUTO_TRACE(); + NOVA_WARN("{}() not implemented", NOVA_FUNC_NAME); + RenderPass* render_pass = new RenderPass(); + (void)p_params; + return render_pass; +} + +void VulkanRenderDriver::destroy_render_pass(RenderPassID p_render_pass) { + NOVA_AUTO_TRACE(); + NOVA_ASSERT(p_render_pass); + if (p_render_pass->handle) { + vkDestroyRenderPass(m_device, p_render_pass->handle, get_allocator(VK_OBJECT_TYPE_RENDER_PASS)); + } + delete p_render_pass; +} + PipelineID VulkanRenderDriver::create_pipeline(GraphicsPipelineParams& p_params) { NOVA_AUTO_TRACE(); NOVA_ASSERT(p_params.render_pass); @@ -747,19 +804,6 @@ void VulkanRenderDriver::destroy_pipeline(PipelineID p_pipeline) { delete p_pipeline; } -RenderPassID VulkanRenderDriver::create_render_pass() { - NOVA_AUTO_TRACE(); - NOVA_WARN("{}() not implemented", NOVA_FUNC_NAME); - RenderPass* render_pass = new RenderPass(); - return render_pass; -} - -void VulkanRenderDriver::destroy_render_pass(RenderPassID p_render_pass) { - NOVA_AUTO_TRACE(); - NOVA_ASSERT(p_render_pass); - delete p_render_pass; -} - VkInstance VulkanRenderDriver::get_instance() const { return m_instance; } diff --git a/engine/src/drivers/vulkan/render_driver.h b/engine/src/drivers/vulkan/render_driver.h index 1877bce..2aea364 100644 --- a/engine/src/drivers/vulkan/render_driver.h +++ b/engine/src/drivers/vulkan/render_driver.h @@ -45,6 +45,7 @@ namespace Nova { std::vector image_views; std::vector framebuffers; SurfaceID surface = nullptr; + RenderPassID render_pass = nullptr; }; class VulkanRenderDriver final : public RenderDriver { @@ -67,18 +68,19 @@ namespace Nova { [[nodiscard]] SwapchainID create_swapchain(SurfaceID surface) override; void resize_swapchain(SwapchainID swapchain) override; + [[nodiscard]] RenderPassID get_swapchain_render_pass(SwapchainID swapchain) const override; void destroy_swapchain(SwapchainID swapchain) override; [[nodiscard]] ShaderID create_shader(const std::span bytes, ShaderStage stage) override; void destroy_shader(ShaderID shader) override; + [[nodiscard]] RenderPassID create_render_pass(RenderPassParams& params) override; + void destroy_render_pass(RenderPassID render_pass) override; + [[nodiscard]] PipelineID create_pipeline(GraphicsPipelineParams& params) override; [[nodiscard]] PipelineID create_pipeline(ComputePipelineParams& params) override; void destroy_pipeline(PipelineID pipeline) override; - [[nodiscard]] RenderPassID create_render_pass() override; - void destroy_render_pass(RenderPassID render_pass) override; - [[nodiscard]] VkInstance get_instance() const; [[nodiscard]] VkAllocationCallbacks* get_allocator(VkObjectType type) const;