diff --git a/engine/modules/engine/render/include/render/graph/frame_graph_builder.inl b/engine/modules/engine/render/include/render/graph/frame_graph_builder.inl index 5271e1f..b03dd2f 100644 --- a/engine/modules/engine/render/include/render/graph/frame_graph_builder.inl +++ b/engine/modules/engine/render/include/render/graph/frame_graph_builder.inl @@ -8,6 +8,7 @@ namespace api { RenderPassBuilder(FrameGraph* graph, FrameGraphNodePtr& node) noexcept : graph(*graph) , node(node) {}; FrameGraph::RenderPassBuilder& Name(pmr::Name name); + FrameGraph::RenderPassBuilder& Type(RenderPassNodeType type,RenderPassNodeFlag flag = RenderPassNodeFlag::None); FrameGraph::RenderPassBuilder& Read(TextureDesc desc, ResourceState state); FrameGraph::RenderPassBuilder& Write(BufferDesc desc, ResourceState state); FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc, ResourceState state); diff --git a/engine/modules/engine/render/include/render/graph/type.h b/engine/modules/engine/render/include/render/graph/type.h index 1b851dd..99dc726 100644 --- a/engine/modules/engine/render/include/render/graph/type.h +++ b/engine/modules/engine/render/include/render/graph/type.h @@ -80,14 +80,29 @@ namespace api { } void ResolveView(FrameGraph* graph); }; + enum class RenderPassNodeType : uint16_t { + None, + Scene, + Imgui, + }; + enum class RenderPassNodeFlag : uint16_t + { + None = 0, + Input = 0x01, + Output = 0x02, + }; using RenderPassEdgeIterFn = std::function; struct RenderPassNode { Name name; size_t hash; + RenderPassNodeType type; + RenderPassNodeFlag flag; RenderPassNodeExecuteFn executor; pmr::vector inEdges{ FramePool() }; pmr::vector outEdges{ FramePool() }; void ForeachEdge(RenderPassEdgeIterFn fn); + bool IsInput() { return any(flag & RenderPassNodeFlag::Input); } + bool IsOutput() { return any(flag & RenderPassNodeFlag::Output); } FrameGraphEdgePtr GetInput(int i) { return inEdges[i]; }; FrameGraphEdgePtr GetOutput(int i) { return outEdges[i]; }; FrameGraphEdgePtr FindInput(Name name) diff --git a/engine/modules/engine/render/include/render/type.h b/engine/modules/engine/render/include/render/type.h index 795d918..38a0c1f 100644 --- a/engine/modules/engine/render/include/render/type.h +++ b/engine/modules/engine/render/include/render/type.h @@ -1,4 +1,5 @@ #pragma once +#include "meta/enum.h" #include "refl/pch.h" #include "tinyimageformat/tinyimageformat_base.h" #include diff --git a/engine/modules/engine/render/src/graph/frame_graph_builder.cpp b/engine/modules/engine/render/src/graph/frame_graph_builder.cpp index 1ca6d59..0ecfd0c 100644 --- a/engine/modules/engine/render/src/graph/frame_graph_builder.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph_builder.cpp @@ -1,12 +1,17 @@ #include "render/graph/frame_graph.h" #include "render/pass/render_pass.h" -#include "meta/enum.h" namespace api { FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Name(pmr::Name name) { node->name = name; return *this; } + FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Type(RenderPassNodeType type, RenderPassNodeFlag flag) + { + node->type = type; + node->flag = flag; + return *this; + } FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc, ResourceState state) { FrameGraphEdgePtr edge{}; diff --git a/engine/modules/engine/render/src/pass/demo_pass.cpp b/engine/modules/engine/render/src/pass/demo_pass.cpp index 83c95f9..54bb63f 100644 --- a/engine/modules/engine/render/src/pass/demo_pass.cpp +++ b/engine/modules/engine/render/src/pass/demo_pass.cpp @@ -20,6 +20,7 @@ namespace api { .Import(FrameGraph::NameSurface, surface, ResourceState::COLOR_ATTACHMENT) .Edge(); builder.Name("MiniPass") + .Type(RenderPassNodeType::Scene, RenderPassNodeFlag::Input | RenderPassNodeFlag::Output) .Write(edge, edge.targetState); } void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx) diff --git a/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp b/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp index 388dac0..75fddf8 100644 --- a/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp +++ b/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp @@ -2,7 +2,6 @@ #include "render/asset/ubo.h" #include "render/renderapi.h" #include "zlog.h" -#include "meta/enum.h" #include #include namespace api diff --git a/engine/modules/render/vulkan/include/vkn/type.h b/engine/modules/render/vulkan/include/vkn/type.h index 76b8700..eede67f 100644 --- a/engine/modules/render/vulkan/include/vkn/type.h +++ b/engine/modules/render/vulkan/include/vkn/type.h @@ -59,7 +59,7 @@ namespace vkn { uint8_t subpassMask;// 1 byte uint8_t initialColorLayoutMask;// 1 byte uint8_t needsResolveMask; // 1 byte - operator size_t() { + operator size_t() const{ return meta::MurmurHashFn(this); } }; diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index 0818c6a..9b4575e 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -18,6 +18,7 @@ namespace vkn { table MeshTable; table PipelineTable; table RenderPassCache; + table RenderPassNameCache; table FramebufferCache; public: VulkanAPI(); @@ -40,7 +41,8 @@ namespace vkn { void EndRenderPass(RenderPassNode* node) override; void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override; VkPipeline GetPipeline() { return nullptr; }; - const RenderPassInfo& GetRenderPassInfo(size_t hash, const RenderPassKey& config = {}); + RenderPassInfo* GetRenderPassInfo(Name name, size_t hash); + RenderPassInfo* GetRenderPassInfo(size_t& hash, const RenderPassKey& config); Backend& GetBackend() { return backend; } diff --git a/engine/modules/render/vulkan/src/vulkan_api.cpp b/engine/modules/render/vulkan/src/vulkan_api.cpp index 80cd427..d08c3ff 100644 --- a/engine/modules/render/vulkan/src/vulkan_api.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api.cpp @@ -7,7 +7,6 @@ #include "vkn/loader/vulkan_glsl_loader.h" #include "render/asset/mesh.h" #include "event/event_system.h" -#include "meta/enum.h" #include "tinyimageformat/tinyimageformat_apis.h" #include "zlog.h" namespace vkn { @@ -375,6 +374,7 @@ namespace vkn { } void VulkanAPI::BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) { + RenderPassInfo* passInfo = GetRenderPassInfo(node->name, node->hash); RenderPassKey config{}; FramebufferKey frameKey{.layers = 1}; VkClearValue clearValues[2 * MAX_SUPPORTED_RENDER_TARGET_COUNT + 1] = { 0 }; @@ -398,9 +398,10 @@ namespace vkn { } } frameKey.attachmentCount = i; - node->hash = config; - RenderPassInfo passInfo = GetRenderPassInfo(node->hash, config); - frameKey.pass = passInfo.Pass(); + if (!passInfo) { + passInfo = GetRenderPassInfo(node->hash, config); + } + frameKey.pass = passInfo->Pass(); auto it = FramebufferCache.find(frameKey); VkFramebuffer framebuffer = it->second; if (it == FramebufferCache.end()) { @@ -430,7 +431,7 @@ namespace vkn { .pClearValues = clearValues }; VulkanContext& ctx = *(VulkanContext*)&context; - CommandBuffer cmd = passInfo.commands[context.frame]; + CommandBuffer cmd = passInfo->commands[context.frame]; ctx.command = cmd.Ptr(); cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); if(callback) callback(node); @@ -439,41 +440,59 @@ namespace vkn { void VulkanAPI::EndRenderPass(RenderPassNode* node) { VulkanContext& ctx = *(VulkanContext*)&context; - RenderPassInfo passInfo = GetRenderPassInfo(node->hash); - CommandBuffer cmd = passInfo.commands[context.frame]; + RenderPassInfo* passInfo = GetRenderPassInfo(node->name, node->hash); + CommandBuffer cmd = passInfo->commands[context.frame]; vkCmdEndRenderPass(cmd.Ptr()); cmd.EndRecord(); VkSemaphore waitSemaphores[8]; VkPipelineStageFlags waitDstStageMasks[8]; uint32_t semaphoreCount = 0; - if (ctx.surfaceSemaphore) { + if (node->IsInput()) { waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore; - ctx.surfaceSemaphore = nullptr; + zlog::info("-----wait {:#x}", (uintptr_t)ctx.surfaceSemaphore); } for (auto& it : node->inEdges) { - RenderPassInfo inputInfo = GetRenderPassInfo(it->source->hash); + RenderPassInfo* inputInfo = GetRenderPassInfo(it->source->name ,it->source->hash); waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - waitSemaphores[semaphoreCount++] = inputInfo.semaphores[context.frame]; + waitSemaphores[semaphoreCount++] = inputInfo->semaphores[context.frame]; + zlog::info("-----wait {:#x}", (uintptr_t)inputInfo->semaphores[context.frame]); } VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmd.Ptr(); - submitInfo.pSignalSemaphores = &passInfo.semaphores[context.frame]; + submitInfo.pSignalSemaphores = &passInfo->semaphores[context.frame]; submitInfo.signalSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitDstStageMasks; submitInfo.waitSemaphoreCount = semaphoreCount; - if (!ctx.graphSemaphore) { - ctx.graphSemaphore = passInfo.semaphores[context.frame]; + if (node->IsOutput()) { + ctx.graphSemaphore = passInfo->semaphores[context.frame]; } + zlog::info("+++++sign {:#x}", (uintptr_t)passInfo->semaphores[context.frame]); vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, nullptr); } - const RenderPassInfo& VulkanAPI::GetRenderPassInfo(size_t hash, const RenderPassKey& config) { + RenderPassInfo* VulkanAPI::GetRenderPassInfo(Name name, size_t hash) { + if (hash) { + auto it = RenderPassCache.find(hash); + if (it != RenderPassCache.end()) { + return &it->second; + } + } + if (name) { + auto it = RenderPassNameCache.find(name); + if (it != RenderPassNameCache.end()) { + return &it->second; + } + } + return nullptr; + } + RenderPassInfo* VulkanAPI::GetRenderPassInfo(size_t& hash, const RenderPassKey& config) { + hash = config; auto it = RenderPassCache.find(hash); if (it != RenderPassCache.end()) { - return it->second; + return &it->second; } // Set up some const aliases for terseness. const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR; @@ -644,6 +663,6 @@ namespace vkn { backend.GetDevice().CreateSemaphores(info.semaphores, context.frameCount); Backend::RenderWorker->GetCommandPool().PopList(info.commands, context.frameCount); RenderPassCache.emplace(hash, info); - return RenderPassCache[hash]; + return &RenderPassCache[hash]; } } diff --git a/engine/modules/render/vulkan/src/vulkan_api_help.cpp b/engine/modules/render/vulkan/src/vulkan_api_help.cpp index 2e68c4c..bbfcb57 100644 --- a/engine/modules/render/vulkan/src/vulkan_api_help.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api_help.cpp @@ -1,6 +1,5 @@ #include #include "vkn/vulkan_api_help.h" -#include "meta/enum.h" namespace vkn { VkImageLayout vkApiGetAttachmentLayout(VkFormat format, bool includeStencilBit) { diff --git a/engine/modules/render/vulkan/src/vulkan_context.cpp b/engine/modules/render/vulkan/src/vulkan_context.cpp index 8cf5276..7f16b25 100644 --- a/engine/modules/render/vulkan/src/vulkan_context.cpp +++ b/engine/modules/render/vulkan/src/vulkan_context.cpp @@ -1,5 +1,6 @@ #include "vkn/vulkan_context.h" #include "vkn/backend.h" +#include "zlog.h" namespace vkn { void VulkanContext::SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { @@ -57,6 +58,7 @@ namespace vkn { }; vkBeginCommandBuffer(surfaceCommand, &beginInfo); } + void VulkanContext::EndRecord(VkQueue queue) { vkEndCommandBuffer(surfaceCommand); @@ -74,6 +76,8 @@ namespace vkn { submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; + zlog::info("-----wait {:#x}", (uintptr_t)waitSemaphores[0]); + zlog::info("+++++sign {:#x}", (uintptr_t)signalSemaphores[0]); vkQueueSubmit(queue, 1, &submitInfo, surfaceFence); graphSemaphore = nullptr; } diff --git a/engine/modules/render/vulkan/src/vulkan_window.cpp b/engine/modules/render/vulkan/src/vulkan_window.cpp index e237a2c..5dbf982 100644 --- a/engine/modules/render/vulkan/src/vulkan_window.cpp +++ b/engine/modules/render/vulkan/src/vulkan_window.cpp @@ -98,9 +98,11 @@ namespace vkn { vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame); vkResetFences(mDevice.Ptr(), 1, &surfaceFence); ctx.presentFrame = ctx.presentFrame % mFrames; + zlog::info("aquire------------:: {:#x}", (uintptr_t)surfaceSemaphore); } void VulkanSwapchain::Present(VulkanContext& ctx) { + zlog::info("present+++++++++++:: {:#x}", (uintptr_t)ctx.presentSemaphore); VkPresentInfoKHR presentInfo = {}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.pWaitSemaphores = &ctx.presentSemaphore;