This commit is contained in:
Kbz-8
2024-11-03 01:23:52 +01:00
parent 77f1a2d8f8
commit af70e2e354
36 changed files with 21446 additions and 13231 deletions

View File

@@ -153,8 +153,8 @@ namespace mlx
std::vector<VkImageView> attachment_views;
if(p_renderer)
{
attachments.push_back(kvfBuildSwapchainAttachmentDescription(p_renderer->GetSwapchain(), clear_attachments));
attachment_views.push_back(p_renderer->GetSwapchainImages()[0].GetImageView());
attachments.push_back(kvfBuildSwapchainAttachmentDescription(p_renderer->GetSwapchain().Get(), clear_attachments));
attachment_views.push_back(p_renderer->GetSwapchain().GetSwapchainImages()[0].GetImageView());
}
#pragma omp parallel for
@@ -171,7 +171,7 @@ namespace mlx
if(p_renderer)
{
for(const Image& image : p_renderer->GetSwapchainImages())
for(const Image& image : p_renderer->GetSwapchain().GetSwapchainImages())
{
attachment_views[0] = image.GetImageView();
m_framebuffers.push_back(kvfCreateFramebuffer(RenderCore::Get().GetDevice(), m_renderpass, attachment_views.data(), attachment_views.size(), { .width = image.GetWidth(), .height = image.GetHeight() }));

View File

@@ -1,4 +1,3 @@
#include <mlx_profile.h>
#include <PreCompiled.h>
#include <Renderer/RenderCore.h>
@@ -7,6 +6,8 @@
#define KVF_ENABLE_VALIDATION_LAYERS
#endif
#define KVF_ASSERT(x) mlx::Assert(x, #x)
#if defined(MLX_COMPILER_GCC) || defined(MLX_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
@@ -60,8 +61,6 @@ namespace mlx
kvfSetValidationErrorCallback(&ValidationErrorCallback);
kvfSetValidationWarningCallback(&WarningCallback);
//kvfAddLayer("VK_LAYER_MESA_overlay");
Window window(1, 1, "", true);
std::vector<const char*> instance_extensions = window.GetRequiredVulkanInstanceExtentions();
#ifdef MLX_PLAT_MACOS

View File

@@ -63,7 +63,7 @@ namespace mlx
p_set->SetImage(renderer.GetCurrentFrameIndex(), 0, render_target);
p_set->Update(renderer.GetCurrentFrameIndex(), cmd);
m_pipeline.BindPipeline(cmd, renderer.GetSwapchainImageIndex(), { 0.0f, 0.0f, 0.0f, 1.0f });
m_pipeline.BindPipeline(cmd, renderer.GetSwapchain().GetImageIndex(), { 0.0f, 0.0f, 0.0f, 1.0f });
VkDescriptorSet set = p_set->GetSet(renderer.GetCurrentFrameIndex());
RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, 1, &set, 0, nullptr);
RenderCore::Get().vkCmdDraw(cmd, 3, 1, 0, 0);

View File

@@ -14,7 +14,7 @@ namespace mlx
if(event.What() == Event::ResizeEventCode)
{
m_main_render_texture.Destroy();
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain().Get());
#ifdef DEBUG
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_renderpasses_target");
#else
@@ -24,7 +24,7 @@ namespace mlx
}
};
EventBus::RegisterListener({ functor, "__MlxRenderPasses" });
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain().Get());
#ifdef DEBUG
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_renderpasses_target");

View File

@@ -9,11 +9,6 @@ namespace mlx
{
namespace Internal
{
struct ResizeEventBroadcast : public EventBase
{
Event What() const override { return Event::ResizeEventCode; }
};
struct FrameBeginEventBroadcast : public EventBase
{
Event What() const override { return Event::FrameBeginEventCode; }
@@ -23,20 +18,8 @@ namespace mlx
void Renderer::Init(NonOwningPtr<Window> window)
{
MLX_PROFILE_FUNCTION();
func::function<void(const EventBase&)> functor = [this](const EventBase& event)
{
if(event.What() == Event::ResizeEventCode)
this->RequireFramebufferResize();
};
EventBus::RegisterListener({ functor, "__MlxRenderer" + std::to_string(reinterpret_cast<std::uintptr_t>(this)) });
p_window = window;
m_surface = p_window->CreateVulkanSurface(RenderCore::Get().GetInstance());
DebugLog("Vulkan: surface created");
CreateSwapchain();
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());
@@ -50,27 +33,16 @@ namespace mlx
}
}
bool Renderer::BeginFrame()
void Renderer::BeginFrame()
{
MLX_PROFILE_FUNCTION();
kvfWaitForFence(RenderCore::Get().GetDevice(), m_cmd_fences[m_current_frame_index]);
VkResult result = RenderCore::Get().vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, m_image_available_semaphores[m_current_frame_index], VK_NULL_HANDLE, &m_swapchain_image_index);
if(result == VK_ERROR_OUT_OF_DATE_KHR)
{
//DestroySwapchain();
//CreateSwapchain();
//EventBus::SendBroadcast(Internal::ResizeEventBroadcast{});
//return false;
}
else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
FatalError("Vulkan error: failed to acquire swapchain image, %", kvfVerbaliseVkResult(result));
m_swapchain.AquireFrame(m_image_available_semaphores[m_current_frame_index]);
RenderCore::Get().vkResetCommandBuffer(m_cmd_buffers[m_current_frame_index], 0);
kvfBeginCommandBuffer(m_cmd_buffers[m_current_frame_index], 0);
m_drawcalls = 0;
m_polygons_drawn = 0;
EventBus::SendBroadcast(Internal::FrameBeginEventBroadcast{});
return true;
}
void Renderer::EndFrame()
@@ -79,55 +51,14 @@ namespace mlx
VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
kvfEndCommandBuffer(m_cmd_buffers[m_current_frame_index]);
kvfSubmitCommandBuffer(RenderCore::Get().GetDevice(), m_cmd_buffers[m_current_frame_index], KVF_GRAPHICS_QUEUE, m_render_finished_semaphores[m_current_frame_index], m_image_available_semaphores[m_current_frame_index], m_cmd_fences[m_current_frame_index], wait_stages);
if(!kvfQueuePresentKHR(RenderCore::Get().GetDevice(), m_render_finished_semaphores[m_current_frame_index], m_swapchain, m_swapchain_image_index) || m_framebuffers_resize)
{
m_framebuffers_resize = false;
//DestroySwapchain();
//CreateSwapchain();
//EventBus::SendBroadcast(Internal::ResizeEventBroadcast{});
}
m_swapchain.Present(m_render_finished_semaphores[m_current_frame_index]);
m_current_frame_index = (m_current_frame_index + 1) % MAX_FRAMES_IN_FLIGHT;
}
void Renderer::CreateSwapchain()
{
MLX_PROFILE_FUNCTION();
Vec2ui drawable_size = p_window->GetVulkanDrawableSize();
VkExtent2D extent = { drawable_size.x, drawable_size.y };
m_swapchain = kvfCreateSwapchainKHR(RenderCore::Get().GetDevice(), RenderCore::Get().GetPhysicalDevice(), m_surface, extent, false);
std::uint32_t images_count = kvfGetSwapchainImagesCount(m_swapchain);
std::vector<VkImage> tmp(images_count);
m_swapchain_images.resize(images_count);
RenderCore::Get().vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &images_count, tmp.data());
for(std::size_t i = 0; i < images_count; i++)
{
#ifdef DEBUG
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, "mlx_swapchain_image_" + std::to_string(i));
#else
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, {});
#endif
m_swapchain_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
m_swapchain_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
}
DebugLog("Vulkan: swapchain created");
}
void Renderer::DestroySwapchain()
{
MLX_PROFILE_FUNCTION();
RenderCore::Get().WaitDeviceIdle();
for(Image& img : m_swapchain_images)
img.DestroyImageView();
kvfDestroySwapchainKHR(RenderCore::Get().GetDevice(), m_swapchain);
DebugLog("Vulkan: swapchain destroyed");
}
void Renderer::Destroy() noexcept
{
MLX_PROFILE_FUNCTION();
RenderCore::Get().WaitDeviceIdle();
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
{
kvfDestroySemaphore(RenderCore::Get().GetDevice(), m_image_available_semaphores[i]);
@@ -137,10 +68,6 @@ namespace mlx
kvfDestroyFence(RenderCore::Get().GetDevice(), m_cmd_fences[i]);
DebugLog("Vulkan: fence destroyed");
}
DestroySwapchain();
RenderCore::Get().vkDestroySurfaceKHR(RenderCore::Get().GetInstance(), m_surface, nullptr);
DebugLog("Vulkan: surface destroyed");
m_surface = VK_NULL_HANDLE;
m_swapchain.Destroy();
}
}

108
runtime/Sources/Renderer/Swapchain.cpp git.filemode.normal_file
View File

@@ -0,0 +1,108 @@
#include <PreCompiled.h>
#include <Platform/Window.h>
#include <Renderer/Swapchain.h>
#include <Renderer/RenderCore.h>
#include <Core/Logs.h>
#include <Core/EventBus.h>
namespace mlx
{
namespace Internal
{
struct ResizeEventBroadcast : public EventBase
{
Event What() const override { return Event::ResizeEventCode; }
};
}
void Swapchain::Init(NonOwningPtr<Window> window)
{
p_window = window;
m_surface = window->CreateVulkanSurface(RenderCore::Get().GetInstance());
DebugLog("Vulkan: surface created");
CreateSwapchain();
}
void Swapchain::AquireFrame(VkSemaphore signal)
{
if(m_resize)
{
RenderCore::Get().WaitDeviceIdle();
CreateSwapchain();
EventBus::SendBroadcast(Internal::ResizeEventBroadcast{});
}
VkResult result = RenderCore::Get().vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, signal, VK_NULL_HANDLE, &m_current_image_index);
if(result == VK_SUBOPTIMAL_KHR)
m_resize = true; // Recreate Swapchain next time
else if(result == VK_ERROR_OUT_OF_DATE_KHR)
{
m_resize = true;
AquireFrame(signal);
}
else if(result != VK_SUCCESS)
FatalError("Vulkan: failed to acquire swapchain image, %", kvfVerbaliseVkResult(result));
}
void Swapchain::Present(VkSemaphore wait) noexcept
{
if(!kvfQueuePresentKHR(RenderCore::Get().GetDevice(), wait, m_swapchain, m_current_image_index))
m_resize = true;
}
void Swapchain::Destroy()
{
RenderCore::Get().WaitDeviceIdle();
for(Image& img : m_swapchain_images)
img.DestroyImageView();
// kvfDestroySwapchainKHR(RenderCore::Get().GetDevice(), m_swapchain);
RenderCore::Get().vkDestroySurfaceKHR(RenderCore::Get().GetInstance(), m_surface, nullptr);
m_surface = VK_NULL_HANDLE;
DebugLog("Vulkan: surface destroyed");
}
void Swapchain::CreateSwapchain()
{
for(Image& img : m_swapchain_images)
img.DestroyImageView();
m_swapchain_images.clear();
VkExtent2D extent;
do
{
Vec2ui size = p_window->GetVulkanDrawableSize();
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);
m_images_count = kvfGetSwapchainImagesCount(m_swapchain);
m_min_images_count = kvfGetSwapchainMinImagesCount(m_swapchain);
std::vector<VkImage> tmp(m_images_count);
m_swapchain_images.resize(m_images_count);
RenderCore::Get().vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &m_images_count, tmp.data());
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
for(std::size_t i = 0; i < m_images_count; i++)
{
#ifdef DEBUG
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, "mlx_swapchain_image_" + std::to_string(i));
#else
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, {});
#endif
m_swapchain_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, cmd);
m_swapchain_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
}
kvfEndCommandBuffer(cmd);
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
DebugLog("Vulkan: swapchain created");
}
}