mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 14:43:34 +00:00
working on swapchains
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#ifndef __MLX_RENDER_CORE__
|
||||
#define __MLX_RENDER_CORE__
|
||||
|
||||
constexpr const int MAX_FRAMES_IN_FLIGHT = 3;
|
||||
constexpr const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
#include <Renderer/Memory.h>
|
||||
#include <Renderer/Descriptor.h>
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace mlx
|
||||
Renderer() = default;
|
||||
|
||||
void Init(NonOwningPtr<Window> window);
|
||||
void Init(NonOwningPtr<Texture> render_target);
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
@@ -28,6 +29,7 @@ namespace mlx
|
||||
[[nodiscard]] inline std::size_t& GetPolygonDrawnCounterRef() noexcept { return m_polygons_drawn; }
|
||||
[[nodiscard]] inline std::size_t GetCurrentFrameIndex() const noexcept { return m_current_frame_index; }
|
||||
[[nodiscard]] inline NonOwningPtr<Window> GetWindow() const noexcept { return p_window; }
|
||||
[[nodiscard]] inline NonOwningPtr<Texture> GetRenderTarget() const noexcept { return p_render_target; }
|
||||
[[nodiscard]] inline const Swapchain& GetSwapchain() const noexcept { return m_swapchain; }
|
||||
|
||||
void Destroy() noexcept;
|
||||
@@ -41,6 +43,7 @@ namespace mlx
|
||||
std::array<VkCommandBuffer, MAX_FRAMES_IN_FLIGHT> m_cmd_buffers;
|
||||
std::array<VkFence, MAX_FRAMES_IN_FLIGHT> m_cmd_fences;
|
||||
NonOwningPtr<Window> p_window;
|
||||
NonOwningPtr<Texture> p_render_target;
|
||||
std::uint32_t m_current_frame_index = 0;
|
||||
std::size_t m_polygons_drawn = 0;
|
||||
std::size_t m_drawcalls = 0;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace mlx
|
||||
m_has_window(false)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
m_renderer.Init(nullptr);
|
||||
m_renderer.Init(render_target);
|
||||
m_scene_renderer.Init(render_target);
|
||||
p_scene = std::make_unique<Scene>();
|
||||
}
|
||||
|
||||
@@ -9,11 +9,18 @@ namespace mlx
|
||||
{
|
||||
Verify((bool)p_renderer, "invalid renderer pointer");
|
||||
|
||||
VkExtent2D swapchain_extent = kvfGetSwapchainImagesSize(p_renderer->GetSwapchain().Get());
|
||||
VkExtent2D extent;
|
||||
if(p_renderer->GetWindow())
|
||||
extent = kvfGetSwapchainImagesSize(p_renderer->GetSwapchain().Get());
|
||||
else if(p_renderer->GetRenderTarget())
|
||||
extent = VkExtent2D{ .width = p_renderer->GetRenderTarget()->GetWidth(), .height = p_renderer->GetRenderTarget()->GetHeight() };
|
||||
else
|
||||
FatalError("a renderer was created without window nor render target attached (wtf)");
|
||||
|
||||
#ifdef DEBUG
|
||||
auto res = m_textures.try_emplace(draw_layer, CPUBuffer{}, swapchain_extent.width, swapchain_extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_put_pixel_layer_" + std::to_string(draw_layer));
|
||||
auto res = m_textures.try_emplace(draw_layer, CPUBuffer{}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_put_pixel_layer_" + std::to_string(draw_layer));
|
||||
#else
|
||||
auto res = m_textures.try_emplace(draw_layer, CPUBuffer{}, swapchain_extent.width, swapchain_extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, std::string_view{});
|
||||
auto res = m_textures.try_emplace(draw_layer, CPUBuffer{}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, std::string_view{});
|
||||
#endif
|
||||
if(res.second)
|
||||
res.first->second.Clear(VK_NULL_HANDLE, Vec4f{ 0.0f });
|
||||
|
||||
@@ -132,6 +132,7 @@ namespace mlx
|
||||
kvfDestroyFramebuffer(RenderCore::Get().GetDevice(), fb);
|
||||
DebugLog("Vulkan: framebuffer destroyed");
|
||||
}
|
||||
m_framebuffers.clear();
|
||||
|
||||
kvfDestroyPipelineLayout(RenderCore::Get().GetDevice(), m_pipeline_layout);
|
||||
m_pipeline_layout = VK_NULL_HANDLE;
|
||||
@@ -148,7 +149,6 @@ namespace mlx
|
||||
p_renderer = nullptr;
|
||||
m_clears.clear();
|
||||
m_attachments.clear();
|
||||
m_framebuffers.clear();
|
||||
}
|
||||
|
||||
void GraphicPipeline::CreateFramebuffers(const std::vector<NonOwningPtr<Texture>>& render_targets, bool clear_attachments)
|
||||
@@ -156,6 +156,8 @@ namespace mlx
|
||||
MLX_PROFILE_FUNCTION();
|
||||
std::vector<VkAttachmentDescription> attachments;
|
||||
std::vector<VkImageView> attachment_views;
|
||||
std::vector<VkSubpassDependency> dependencies;
|
||||
|
||||
if(p_renderer)
|
||||
{
|
||||
attachments.push_back(kvfBuildSwapchainAttachmentDescription(p_renderer->GetSwapchain().Get(), clear_attachments));
|
||||
@@ -164,11 +166,30 @@ namespace mlx
|
||||
|
||||
for(NonOwningPtr<Texture> image : render_targets)
|
||||
{
|
||||
attachments.push_back(kvfBuildAttachmentDescription((kvfIsDepthFormat(image->GetFormat()) ? KVF_IMAGE_DEPTH : KVF_IMAGE_COLOR), image->GetFormat(), image->GetLayout(), image->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT));
|
||||
attachments.push_back(kvfBuildAttachmentDescription(KVF_IMAGE_COLOR, image->GetFormat(), image->GetLayout(), image->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT));
|
||||
attachment_views.push_back(image->GetImageView());
|
||||
#if 0
|
||||
VkSubpassDependency& first_dependency = dependencies.emplace_back();
|
||||
first_dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
first_dependency.dstSubpass = 0;
|
||||
first_dependency.srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
first_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
first_dependency.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
first_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
first_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
|
||||
VkSubpassDependency& second_dependency = dependencies.emplace_back();
|
||||
second_dependency.srcSubpass = 0;
|
||||
second_dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
second_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
second_dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
second_dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
second_dependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
second_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
m_renderpass = kvfCreateRenderPass(RenderCore::Get().GetDevice(), attachments.data(), attachments.size(), GetPipelineBindPoint());
|
||||
m_renderpass = kvfCreateRenderPassWithSubpassDependencies(RenderCore::Get().GetDevice(), attachments.data(), attachments.size(), GetPipelineBindPoint(), dependencies.data(), dependencies.size());
|
||||
m_clears.clear();
|
||||
m_clears.resize(attachments.size());
|
||||
DebugLog("Vulkan: renderpass created");
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace mlx
|
||||
if(event.What() == Event::ResizeEventCode)
|
||||
m_pipeline.Destroy();
|
||||
};
|
||||
EventBus::RegisterListener({ functor, "__MlxRender2DPass" });
|
||||
EventBus::RegisterListener({ functor, "mlx_2d_render_pass" });
|
||||
|
||||
p_viewer_data_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_vertex_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Vertex);
|
||||
p_texture_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace mlx
|
||||
if(event.What() == Event::ResizeEventCode)
|
||||
m_pipeline.Destroy();
|
||||
};
|
||||
EventBus::RegisterListener({ functor, "__MlxFinalPass" });
|
||||
EventBus::RegisterListener({ functor, "mlx_final_pass" });
|
||||
|
||||
p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace mlx
|
||||
if(event.What() == Event::ResizeEventCode)
|
||||
m_main_render_texture.Destroy();
|
||||
};
|
||||
EventBus::RegisterListener({ functor, "__MlxRenderPasses" });
|
||||
EventBus::RegisterListener({ functor, "mlx_render_passes" });
|
||||
}
|
||||
|
||||
void RenderPasses::Pass(Scene& scene, Renderer& renderer, const Vec4f& clear_color)
|
||||
|
||||
@@ -19,8 +19,24 @@ namespace mlx
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
p_window = window;
|
||||
if(p_window)
|
||||
m_swapchain.Init(p_window);
|
||||
m_swapchain.Init(p_window);
|
||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
{
|
||||
m_image_available_semaphores[i] = kvfCreateSemaphore(RenderCore::Get().GetDevice());
|
||||
DebugLog("Vulkan: image available semaphore created");
|
||||
m_render_finished_semaphores[i] = kvfCreateSemaphore(RenderCore::Get().GetDevice());
|
||||
DebugLog("Vulkan: render finished semaphore created");
|
||||
m_cmd_buffers[i] = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||
DebugLog("Vulkan: command buffer created");
|
||||
m_cmd_fences[i] = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
DebugLog("Vulkan: fence created");
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::Init(NonOwningPtr<Texture> render_target)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
p_render_target = render_target;
|
||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
{
|
||||
m_image_available_semaphores[i] = kvfCreateSemaphore(RenderCore::Get().GetDevice());
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace mlx
|
||||
void Swapchain::Init(NonOwningPtr<Window> window)
|
||||
{
|
||||
p_window = window;
|
||||
m_surface = window->CreateVulkanSurface(RenderCore::Get().GetInstance());
|
||||
DebugLog("Vulkan: surface created");
|
||||
CreateSwapchain();
|
||||
}
|
||||
|
||||
@@ -53,11 +51,16 @@ namespace mlx
|
||||
|
||||
void Swapchain::Destroy()
|
||||
{
|
||||
if(m_swapchain == VK_NULL_HANDLE)
|
||||
return;
|
||||
RenderCore::Get().WaitDeviceIdle();
|
||||
|
||||
for(Image& img : m_swapchain_images)
|
||||
img.DestroyImageView();
|
||||
m_swapchain_images.clear();
|
||||
kvfDestroySwapchainKHR(RenderCore::Get().GetDevice(), m_swapchain);
|
||||
m_swapchain = VK_NULL_HANDLE;
|
||||
DebugLog("Vulkan: swapchain destroyed");
|
||||
|
||||
RenderCore::Get().vkDestroySurfaceKHR(RenderCore::Get().GetInstance(), m_surface, nullptr);
|
||||
m_surface = VK_NULL_HANDLE;
|
||||
@@ -66,10 +69,6 @@ namespace mlx
|
||||
|
||||
void Swapchain::CreateSwapchain()
|
||||
{
|
||||
for(Image& img : m_swapchain_images)
|
||||
img.DestroyImageView();
|
||||
m_swapchain_images.clear();
|
||||
|
||||
VkExtent2D extent;
|
||||
do
|
||||
{
|
||||
@@ -77,10 +76,11 @@ namespace mlx
|
||||
extent = { size.x, size.y };
|
||||
} while(extent.width == 0 || extent.height == 0);
|
||||
|
||||
VkSwapchainKHR old_swapchain = m_swapchain;
|
||||
m_swapchain = kvfCreateSwapchainKHR(RenderCore::Get().GetDevice(), RenderCore::Get().GetPhysicalDevice(), m_surface, extent, VK_NULL_HANDLE, true);
|
||||
if(old_swapchain != VK_NULL_HANDLE)
|
||||
kvfDestroySwapchainKHR(RenderCore::Get().GetDevice(), old_swapchain);
|
||||
Destroy();
|
||||
|
||||
m_surface = p_window->CreateVulkanSurface(RenderCore::Get().GetInstance());
|
||||
DebugLog("Vulkan: surface created");
|
||||
m_swapchain = kvfCreateSwapchainKHR(RenderCore::Get().GetDevice(), RenderCore::Get().GetPhysicalDevice(), m_surface, extent, VK_NULL_HANDLE, false);
|
||||
|
||||
m_images_count = kvfGetSwapchainImagesCount(m_swapchain);
|
||||
m_min_images_count = kvfGetSwapchainMinImagesCount(m_swapchain);
|
||||
|
||||
Reference in New Issue
Block a user