diff --git a/engine/include/editor/editor_system.h b/engine/include/editor/editor_system.h index 775732c..4749b1b 100644 --- a/engine/include/editor/editor_system.h +++ b/engine/include/editor/editor_system.h @@ -44,6 +44,7 @@ namespace api { mWindows.push_back(ptr); return ptr; } + virtual void Render(FrameGraph& graph, RenderPassContext& ctx) = 0; ImTextureID AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler sampler); virtual ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) = 0; }; diff --git a/engine/modules/engine/ui/impl/ui_render_system_impl.inl b/engine/modules/engine/ui/impl/ui_render_system_impl.inl index 6f9cbba..88f0a11 100644 --- a/engine/modules/engine/ui/impl/ui_render_system_impl.inl +++ b/engine/modules/engine/ui/impl/ui_render_system_impl.inl @@ -84,6 +84,11 @@ namespace api { UITexture* uiTex = (UITexture*)texture; TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data}; Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST); + for (auto& barrier : mTextureBarriers) { + if (barrier.mTexture.image == uiTex->desc.image) { + return; + } + } mTextureBarriers.push_back(uiTex->desc.ToBarrier(ResourceState::TRANSFER_DST, ResourceState::READ_ONLY)); } void UIRenderDevice::BeginOffscreenRender() diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index f92b8f7..65c5cd2 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -3,7 +3,7 @@ #include "asset/res/guid.h" #include "backend.h" #ifdef API_DEBUG - #define gLogSemaphore(...) zlog::error(__VA_ARGS__) + #define gLogSemaphore(...) //zlog::info(__VA_ARGS__) #else #define gLogSemaphore(...) #endif diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_imgui_editor.h b/engine/modules/render/vulkan/include/vkn/vulkan_imgui_editor.h index 80f6598..a6a6e00 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_imgui_editor.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_imgui_editor.h @@ -6,20 +6,15 @@ namespace vkn { using api::FrameGraph; using api::RenderPassContext; using api::RenderPassBuilder; - using api::RenderEditorContext; class VulkanImguiEditor : public api::EditorSystem { public: void Initialize() override; void Finalize() override; - + void Render(FrameGraph& graph, RenderPassContext& ctx) override; ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) override; - void Render(FrameGraph& graph, RenderEditorContext& ctx); - void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame); static VulkanImguiEditor* Ptr() { return (VulkanImguiEditor*)api::EditorSystem::Ptr(); }; - static void Setup(FrameGraph& graph, RenderPassBuilder& builder); - static void Execute(FrameGraph&, RenderPassContext&); }; } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_ui_system.h b/engine/modules/render/vulkan/include/vkn/vulkan_ui_system.h index 1197dd9..970a705 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_ui_system.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_ui_system.h @@ -2,10 +2,16 @@ #include "vkn/vulkan_api.h" #include "vkn/wrapper/device.h" #include "ui/ui_render_system.h" +#include "editor/editor_system.h" +#include "render/graph/frame_graph.h" #include namespace vkn { using Noesis::BaseVector; using api::UITexture; + using api::FrameGraph; + using api::RenderPassContext; + using api::RenderPassBuilder; + using api::RenderEditorContext; struct Layout { uint32_t signature; @@ -52,9 +58,14 @@ namespace vkn { VkShaderModule mPixelShaders[Noesis::Shader::Count]; Layout mLayouts[Noesis::Shader::Count]; public: + inline static Name UIPassName{ "UIPass" }; void InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount)override; void BeginRender(api::RenderContext* context) override; void DrawBatch(const Noesis::Batch& batch) override; + public: + void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame); + static void Setup(FrameGraph& graph, RenderPassBuilder& builder); + static void Execute(FrameGraph&, RenderPassContext&); public: void SetBuffers(const Noesis::Batch& batch); void BindDescriptors(const Noesis::Batch& batch, const Layout& layout); diff --git a/engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp b/engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp index a257fa2..2111590 100644 --- a/engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp +++ b/engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp @@ -5,6 +5,7 @@ #include "vkn/wrapper/device.h" #include "vkn/wrapper/instance.h" #include "vkn/wrapper/queue.h" +#include "vkn/vulkan_ui_system.h" #include "imgui/imgui_impl_vulkan.h" #include "imgui/imgui_impl_sdl2.h" #include "data/global.h" @@ -40,59 +41,6 @@ namespace vkn { vkCreateDescriptorPool(device, &pool_info, VK_NULL_HANDLE, &descriptorPool); return descriptorPool; } - VkRenderPass CreateRenderPass(TinyImageFormat format, VkDevice device) { - VkAttachmentDescription colorAttachment = {}; - colorAttachment.format = (VkFormat)TinyImageFormat_ToVkFormat(format); - colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentDescription stencilAttachment = {}; - stencilAttachment.format = VK_FORMAT_S8_UINT; - stencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - stencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - stencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - stencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - stencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - stencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - stencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference colorAttachmentRef = {}; - colorAttachmentRef.attachment = 0; - colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorAttachmentRef; - - VkSubpassDependency dependency = {}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - VkAttachmentDescription attachmentList[2] = { colorAttachment , stencilAttachment }; - VkRenderPassCreateInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.attachmentCount = 2; - info.pAttachments = attachmentList; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 1; - info.pDependencies = &dependency; - VkRenderPass renderPass; - if (vkCreateRenderPass(device, &info, VK_NULL_HANDLE, &renderPass) != VK_SUCCESS) - throw std::runtime_error("Could not create Dear ImGui's render pass"); - return renderPass; - } void VulkanImguiEditor::Initialize() { VulkanAPI* API = VulkanAPI::Ptr(); @@ -101,7 +49,8 @@ namespace vkn { Queue* pQueue = backend.GetDevice().GetQueue(Queue::RenderQueue); VkDescriptorPool descriptorPool = CreateDescriptorPool(backend.GetDevice().Ptr()); TextureDesc surface = API->context.surface; - VkRenderPass renderPass = CreateRenderPass(surface.format, backend.GetDevice().Ptr()); + auto renderInfo = API->GetRenderPassInfo(VulkanUISystem::UIPassName, 0); + VkRenderPass renderPass = renderInfo->pass; ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = backend.GetInstance().Ptr(); @@ -118,8 +67,6 @@ namespace vkn { init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; init_info.Allocator = VK_NULL_HANDLE; ImGui_ImplVulkan_Init(&init_info); - API->SetRenderPassInfo(ImguiPassName, renderPass); - EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanImguiEditor::OnBeginRenderFrame, this); } void VulkanImguiEditor::Finalize() { @@ -130,52 +77,17 @@ namespace vkn { VkDescriptorSet descriptorSet = ImGui_ImplVulkan_AddTexture((VkSampler)sampler, (VkImageView)imageview, vkApiGetImageLayout(state)); return reinterpret_cast(descriptorSet); } - void VulkanImguiEditor::Render(FrameGraph& graph, RenderEditorContext& ctx) + void VulkanImguiEditor::Render(FrameGraph& graph, RenderPassContext& context) { - for (auto win : mWindows) - { - win->Draw(graph, ctx); - } - } - void VulkanImguiEditor::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame) - { - graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface; - if (gEngineConfig.IsRenderEditorSurface) { - graph.mEditorSurfaceID = graph.mSurfaceID; - graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame); - } - graph.AddRenderPass(); - } - void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder) - { - TextureDesc stencil = graph.GetRenderSurface(); - stencil.id = 0; - stencil.format = TinyImageFormat_S8_UINT; - stencil.image = nullptr; - stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT; - graph.AcquireTexture(stencil); - builder.Name(ImguiPassName) - .Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output) - .Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT) - .Write(stencil, ResourceState::DEPTH_ATTACHMENT); - if (gEngineConfig.IsRenderEditorSurface) { - builder.Read(graph.GetSurface(), ResourceState::READ_ONLY); - } - } - void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context) - { - auto& surface = graph.GetRenderSurface(); - context->SetViewport(0.0f, 0.0f, (float)surface.width, (float)surface.height, 0.f, 1.f); - context->SetScissor(0, 0, surface.width, surface.height); - - graph.GetRenderSurface().state = ResourceState::PRESENT; ImGui_ImplVulkan_NewFrame(); ImGui_ImplSDL2_NewFrame(); ImGui::NewFrame(); - VulkanImguiEditor* editor = VulkanImguiEditor::Ptr(); - RenderEditorContext editorContext{.editor = editor, .frame = context->frame, .frameCount = context->frameCount }; - editor->Render(graph, editorContext); + RenderEditorContext editorContext{ .editor = this, .frame = context->frame, .frameCount = context->frameCount }; + for (auto win : mWindows) + { + win->Draw(graph, editorContext); + } ImGui::Render(); VulkanContext& ctx = *(VulkanContext*)context.parent; diff --git a/engine/modules/render/vulkan/src/vulkan_module.cpp b/engine/modules/render/vulkan/src/vulkan_module.cpp index 0b9a1ee..f371016 100644 --- a/engine/modules/render/vulkan/src/vulkan_module.cpp +++ b/engine/modules/render/vulkan/src/vulkan_module.cpp @@ -10,10 +10,10 @@ using namespace vkn; void VulkanModule::OnLoad(int argc, char** argv) { VulkanGlslLoader::Init(); + AddSystem(); #ifdef WITH_EDITOR AddSystem(); #endif // WITH_EDITOR - AddSystem(); } void VulkanModule::OnUnload() diff --git a/engine/modules/render/vulkan/src/vulkan_ui_system.cpp b/engine/modules/render/vulkan/src/vulkan_ui_system.cpp index f18cec7..8275f0a 100644 --- a/engine/modules/render/vulkan/src/vulkan_ui_system.cpp +++ b/engine/modules/render/vulkan/src/vulkan_ui_system.cpp @@ -1,29 +1,71 @@ #include "vkn/vulkan_ui_system.h" -#include "noesis/vulkan_noesis_help.h" #include "vkn/vulkan_api_help.h" +#include "vkn/vulkan_api.h" +#ifdef WTIH_EDITOR +#include "editor/editor_system.h" +#endif // WTIH_EDITOR #include "ui/utils/fast_lz.h" +#include "event/event_system.h" +#include "data/global.h" +#include "noesis/vulkan_noesis_help.h" #define DESCRIPTOR_POOL_MAX_SETS 128 namespace vkn { - using api::FastLZ; - using api::DynamicBuffer; - using api::UITexture; + using namespace api; + void vkn::VulkanUISystem::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame) + { +#ifdef WITH_EDITOR + graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface; + if (gEngineConfig.IsRenderEditorSurface) { + graph.mEditorSurfaceID = graph.mSurfaceID; + graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame); + } +#endif // WITH_EDITOR + graph.AddRenderPass(); + } + void VulkanUISystem::Setup(FrameGraph& graph, RenderPassBuilder& builder) + { + TextureDesc stencil = graph.GetRenderSurface(); + stencil.id = 0; + stencil.format = TinyImageFormat_S8_UINT; + stencil.image = nullptr; + stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT; + graph.AcquireTexture(stencil); + builder.Name(UIPassName) + .Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output) + .Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT) + .Write(stencil, ResourceState::DEPTH_ATTACHMENT); + if (gEngineConfig.IsRenderEditorSurface) { + builder.Read(graph.GetSurface(), ResourceState::READ_ONLY); + } + } + void VulkanUISystem::Execute(FrameGraph& graph, RenderPassContext& context) + { + auto& surface = graph.GetRenderSurface(); + context->SetViewport(0.0f, 0.0f, (float)surface.width, (float)surface.height, 0.f, 1.f); + context->SetScissor(0, 0, surface.width, surface.height); + graph.GetRenderSurface().state = ResourceState::PRESENT; +#ifdef WITH_EDITOR + EditorSystem::Ptr()->Render(graph, context); +#endif // WITH_EDITOR + } void VulkanUISystem::InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount_) { - mDevice = &VulkanAPI::Ptr()->GetBackend().GetDevice(); - auto info = VulkanAPI::Ptr()->GetRenderPassInfo("ImguiPass", 0); - mRenderPass = info->pass; + VulkanAPI* API = VulkanAPI::Ptr(); + mDevice = &API->GetBackend().GetDevice(); mHasExtendedDynamicState = false; mIsLinearRendering = linearRendering; VkPhysicalDeviceProperties mDeviceProperties; vkGetPhysicalDeviceProperties(mDevice->GetPhysical(), &mDeviceProperties); mMinUniformBufferOffsetAlignment = mDeviceProperties.limits.minUniformBufferOffsetAlignment; VkSampleCountFlagBits sampleCount = vkApiGetSmpleCountFlag(sampleCount_); - //CreateRenderPass(sampleCount); + CreateRenderPass(sampleCount); CreateLayouts(); LoadShaders(stereoSupport); CreatePipelines(sampleCount); CreateSamplers(); CreateDescriptorPool(); + EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanUISystem::OnBeginRenderFrame, this); + API->SetRenderPassInfo(UIPassName, mRenderPass); } void VulkanUISystem::BeginRender(api::RenderContext* context) { VulkanContext* ctx = (VulkanContext*)context; @@ -31,6 +73,8 @@ namespace vkn { mFrameNumber = ctx->frameNumber; mSafeFrameNumber = ctx->frameNumber - ctx->frameCount; mWaitTransferCount = 0; + mCachedIndexBuffer = nullptr; + mCachedPipeline = nullptr; } void VulkanUISystem::DrawBatch(const Noesis::Batch& batch) {