From d814786d26d9d304bb6235b8f152e2daee4b014b Mon Sep 17 00:00:00 2001 From: ouczbs Date: Sun, 22 Sep 2024 20:26:49 +0800 Subject: [PATCH] update --- .../engine/render/impl/renderapi_impl.inl | 1 + .../render/asset/desc/attachment_desc.h | 3 +- .../render/include/render/asset/texture.h | 6 ++- .../render/include/render/graph/frame_graph.h | 8 +-- .../render/graph/frame_graph_builder.h | 6 +-- .../render/include/render/render_context.h | 5 +- .../engine/render/include/render/type.h | 5 +- .../engine/render/src/asset/texture.cpp | 3 ++ .../engine/render/src/graph/frame_graph.cpp | 7 +-- .../render/src/graph/frame_graph_builder.cpp | 18 ++++--- .../engine/render/src/pass/demo_pass.cpp | 25 ++-------- .../render/vulkan/include/vkn/thread/worker.h | 3 ++ .../render/vulkan/include/vkn/vulkan_api.h | 1 + .../vulkan/include/vkn/vulkan_api_help.h | 13 ++++- .../render/vulkan/include/vkn/vulkan_window.h | 4 +- .../modules/render/vulkan/src/vulkan_api.cpp | 8 ++- .../render/vulkan/src/vulkan_api_help.cpp | 49 ++++++++++++++++--- .../render/vulkan/src/vulkan_window.cpp | 11 ++++- 18 files changed, 123 insertions(+), 53 deletions(-) diff --git a/engine/modules/engine/render/impl/renderapi_impl.inl b/engine/modules/engine/render/impl/renderapi_impl.inl index e4bbe83..ab9ce17 100644 --- a/engine/modules/engine/render/impl/renderapi_impl.inl +++ b/engine/modules/engine/render/impl/renderapi_impl.inl @@ -10,6 +10,7 @@ namespace api { } void RenderAPI::Render() { + graph.mSurface = context.surface; for (auto view : context.views) { RenderView(view); } diff --git a/engine/modules/engine/render/include/render/asset/desc/attachment_desc.h b/engine/modules/engine/render/include/render/asset/desc/attachment_desc.h index 6ab6ff5..ffa8aae 100644 --- a/engine/modules/engine/render/include/render/asset/desc/attachment_desc.h +++ b/engine/modules/engine/render/include/render/asset/desc/attachment_desc.h @@ -2,6 +2,7 @@ #include "math/vector2.h" #include "render_enum.h" namespace api { + /* class Texture; struct Attachment { @@ -43,5 +44,5 @@ namespace api { static AttachmentDesc Make() { return {}; } - }; + };*/ } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/asset/texture.h b/engine/modules/engine/render/include/render/asset/texture.h index 8d96cc1..5f7e3d1 100644 --- a/engine/modules/engine/render/include/render/asset/texture.h +++ b/engine/modules/engine/render/include/render/asset/texture.h @@ -1,9 +1,13 @@ #pragma once #include "asset/asset.h" +#include "render/type.h" namespace api { class Texture : public Resource { public: - void* mPtr; + TextureDesc mDesc; + void* mPtr; + public: + Texture(TextureDesc& desc); }; } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/graph/frame_graph.h b/engine/modules/engine/render/include/render/graph/frame_graph.h index be7ec69..c2d058f 100644 --- a/engine/modules/engine/render/include/render/graph/frame_graph.h +++ b/engine/modules/engine/render/include/render/graph/frame_graph.h @@ -8,8 +8,8 @@ namespace api { class TextureBuilder; class RenderPassBuilder; public: - RscHandle mSurface; - table> mResourceTable; + TextureDesc mSurface; + table mResourceTable; lemon::ListGraph mGraph; pmr::vector mNodes{FramePool()}; public: @@ -23,7 +23,7 @@ namespace api { void Compile(); void Execute(FRenderView& view); void Clear(); - RscHandle Resource(Name name) { + TextureDesc Resource(Name name) { auto it = mResourceTable.find(name); if (it == mResourceTable.end()) { return {}; @@ -36,6 +36,6 @@ namespace api { void ExecuteComputePass(RenderPassNode* node, FRenderView& view); void ExecuteCopyPass(RenderPassNode* node, FRenderView& view); - void ExecuteResourceBarriers(RenderPassNode* node, RenderPassEdgeIterFn fn); + void ExecuteResourceBarriers(RenderPassNode* node); }; } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/graph/frame_graph_builder.h b/engine/modules/engine/render/include/render/graph/frame_graph_builder.h index ec50f7d..e239648 100644 --- a/engine/modules/engine/render/include/render/graph/frame_graph_builder.h +++ b/engine/modules/engine/render/include/render/graph/frame_graph_builder.h @@ -10,9 +10,9 @@ namespace api { : graph(*graph) , node(node) {}; FrameGraph::RenderPassBuilder& Name(pmr::Name name); FrameGraph::RenderPassBuilder& Pass(RenderPass* pass); - FrameGraph::RenderPassBuilder& Read(TextureDesc desc); - FrameGraph::RenderPassBuilder& Write(TextureDesc desc); - FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc); + FrameGraph::RenderPassBuilder& Read(TextureDesc desc, ResourceState state); + FrameGraph::RenderPassBuilder& Write(BufferDesc desc, ResourceState state); + FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc, ResourceState state); FrameGraph::RenderPassBuilder& Read(const FrameGraphEdgePtr& edge); }; struct FrameGraph::TextureBuilder { diff --git a/engine/modules/engine/render/include/render/render_context.h b/engine/modules/engine/render/include/render/render_context.h index c330243..8fae588 100644 --- a/engine/modules/engine/render/include/render/render_context.h +++ b/engine/modules/engine/render/include/render/render_context.h @@ -7,7 +7,8 @@ namespace api { }; struct RenderContext { pmr::vector views; - uint32_t frame{ 0 }; - uint32_t presentFrame{ 0 }; + TextureDesc surface; + uint32_t frame{ 0 }; + uint32_t presentFrame{ 0 }; }; } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/type.h b/engine/modules/engine/render/include/render/type.h index 0af0775..82f7dcf 100644 --- a/engine/modules/engine/render/include/render/type.h +++ b/engine/modules/engine/render/include/render/type.h @@ -13,12 +13,15 @@ namespace api { return {}; } }; + using ImagePtr = void*; struct TextureDesc { + ImagePtr image; static TextureDesc Make() { return {}; } }; struct AttachmentDesc { + ImagePtr image; TinyImageFormat colorFormat; static AttachmentDesc Make() { return {}; @@ -69,7 +72,7 @@ namespace api { }; struct TextureBarrier { - //Texture* pTexture; + TextureDesc mTexture; ResourceState mSrcState; ResourceState mDstState; uint8_t mBeginOnly : 1; diff --git a/engine/modules/engine/render/src/asset/texture.cpp b/engine/modules/engine/render/src/asset/texture.cpp index d8ba1f8..a845c0d 100644 --- a/engine/modules/engine/render/src/asset/texture.cpp +++ b/engine/modules/engine/render/src/asset/texture.cpp @@ -1,4 +1,7 @@ #include "render/asset/texture.h" namespace api { + Texture::Texture(TextureDesc& desc) + { + } } \ No newline at end of file diff --git a/engine/modules/engine/render/src/graph/frame_graph.cpp b/engine/modules/engine/render/src/graph/frame_graph.cpp index b2ae9b2..9e4e656 100644 --- a/engine/modules/engine/render/src/graph/frame_graph.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph.cpp @@ -27,7 +27,7 @@ namespace api { } return !degree; }); - mNodes.erase(end, mNodes.end()); + //mNodes.erase(end, mNodes.end()); } void FrameGraph::Execute(FRenderView& view) { @@ -55,6 +55,7 @@ namespace api { } void FrameGraph::ExecuteRenderPass(RenderPassNode* node, FRenderView& view) { + ExecuteResourceBarriers(node); RenderAPI::Ptr()->BeginRenderPass(node); RenderPassContext context{}; std::get(node->executor)(*this, context); @@ -75,7 +76,7 @@ namespace api { CopyPassContext context{}; std::get(node->executor)(*this, context); } - void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node, RenderPassEdgeIterFn fn) + void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node) { pmr::vector bufferBarrier{FramePool()}; pmr::vector textureBarrier{ FramePool() }; @@ -104,7 +105,7 @@ namespace api { desc.pBufferBarriers = bufferBarrier.data(); desc.textureBarriersCount = textureBarrier.size(); desc.pTextureBarriers = textureBarrier.data(); - + RenderAPI::Ptr()->ExecuteResourceBarriers(desc); } void RenderPassNode::ForeachEdge(RenderPassEdgeIterFn fn) { for (auto& edge : inEdges) { 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 48e0490..926d6dd 100644 --- a/engine/modules/engine/render/src/graph/frame_graph_builder.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph_builder.cpp @@ -11,10 +11,10 @@ namespace api { node->pass = pass; return *this; } - - FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc) + FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc, ResourceState state) { FrameGraphEdgePtr edge{}; + edge.targetState = state; resource = edge.Make(); resource->source = node; resource->resource = desc; @@ -22,9 +22,10 @@ namespace api { return *this; } - FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Write(TextureDesc desc) + FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Write(BufferDesc desc, ResourceState state) { FrameGraphEdgePtr edge{}; + edge.targetState = state; resource = edge.Make(); resource->source = node; resource->resource = desc; @@ -32,11 +33,14 @@ namespace api { return *this; } - FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Attach(AttachmentDesc desc) + FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Attach(AttachmentDesc desc, ResourceState state) { - if (resource) { - resource->resource = desc; - } + FrameGraphEdgePtr edge{}; + edge.targetState = state; + resource = edge.Make(); + resource->source = node; + resource->resource = desc; + node->outEdges.push_back(edge); return *this; } diff --git a/engine/modules/engine/render/src/pass/demo_pass.cpp b/engine/modules/engine/render/src/pass/demo_pass.cpp index eb8f313..4ba82c4 100644 --- a/engine/modules/engine/render/src/pass/demo_pass.cpp +++ b/engine/modules/engine/render/src/pass/demo_pass.cpp @@ -3,26 +3,11 @@ namespace api { void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) { - auto edge = graph.CreateTexture( - [=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) { - builder.Name("import") - .Import(graph.Resource("demo_input")); - }); - builder.Name("DemoPass") - .Read(TextureDesc::Make()) - .Read(edge) - .Write(TextureDesc::Make()) - .Attach(AttachmentDesc::Make()); - auto parent_node = builder.node; - graph.AddRenderPass( - [=](FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) { - builder.Name("DemoPassSub") - .Read(edge) - .Read(parent_node->GetOutput(0)); - }, - [](FrameGraph& graph, RenderPassContext& context) { - - }); + AttachmentDesc surface{}; + surface.image = graph.mSurface.image; + surface.colorFormat = TinyImageFormat_B8G8R8_UNORM; + builder.Name("MiniPass") + .Attach(surface, ResourceState::PRESENT); } void DemoPass::Execute(FrameGraph&, RenderPassContext&) { diff --git a/engine/modules/render/vulkan/include/vkn/thread/worker.h b/engine/modules/render/vulkan/include/vkn/thread/worker.h index 8522300..841a5ed 100644 --- a/engine/modules/render/vulkan/include/vkn/thread/worker.h +++ b/engine/modules/render/vulkan/include/vkn/thread/worker.h @@ -27,5 +27,8 @@ namespace vkn { Queue& GetQueue() { return mQueue; } + VkCommandBuffer AllocateBuffer(VkCommandBufferLevel level) { + return mCommandPool.AllocateBuffer(level); + } }; } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index b1771bc..dadc410 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -16,6 +16,7 @@ namespace vkn { struct VulkanContext : public api::RenderContext { VkSemaphore surfaceSemaphore; VkSemaphore presentSemaphore; + VkCommandBuffer command; }; class VULKAN_API VulkanAPI : public api::RenderAPI { private: diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h b/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h index c0f07a3..1f0802b 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h @@ -1,4 +1,15 @@ #include "type.h" namespace vkn { - + using api::ResourceState; + using api::TextureBarrier; + struct VkTextureTransitionDesc { + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkPipelineStageFlags srcStage; + VkPipelineStageFlags dstStage; + VkImageLayout mSrcState; + VkImageLayout mDstState; + }; + VkImageLayout GetVkLayout(ResourceState layout); + VkImageMemoryBarrier GetVkTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags mDstStage, const TextureBarrier& barrier); } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_window.h b/engine/modules/render/vulkan/include/vkn/vulkan_window.h index 4775c8b..9d87598 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_window.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_window.h @@ -5,6 +5,7 @@ namespace vkn { class Device; struct VulkanContext; + using api::TextureDesc; struct VULKAN_API VulkanWindowArgs { uint32_t frames; uint32_t width; @@ -22,7 +23,8 @@ namespace vkn { Device& mDevice; VkSwapchainKHR mPtr; int mFrames; - //pmr::vector mSurfaces{GlobalPool()}; + pmr::vector mSurfaces{GlobalPool()}; + pmr::vector mCommands{ GlobalPool() }; pmr::vector mFences{ GlobalPool() }; pmr::vector mSemaphores{ GlobalPool() }; public: diff --git a/engine/modules/render/vulkan/src/vulkan_api.cpp b/engine/modules/render/vulkan/src/vulkan_api.cpp index f927073..74a93f0 100644 --- a/engine/modules/render/vulkan/src/vulkan_api.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api.cpp @@ -1,5 +1,6 @@ #include "vkn/vulkan_api.h" #include "vkn/vulkan_window.h" +#include "vkn/vulkan_api_help.h" #include "vkn/wrapper/buffer.h" #include "vkn/wrapper/device.h" #include "vkn/thread/buffer_worker.h" @@ -7,6 +8,7 @@ #include "render/asset/mesh.h" #include "meta/enum.h" #include "tinyimageformat/tinyimageformat_apis.h" + namespace vkn { inline bool operator==(const RenderPassKey& k1, const RenderPassKey& k2) { if (k1.initialColorLayoutMask != k2.initialColorLayoutMask) return false; @@ -74,16 +76,20 @@ namespace vkn { window.Present(*(VulkanContext*)&context); } void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) { - VkCommandBuffer cmd; + VulkanContext& ctx = *(VulkanContext*)&context; pmr::vector bufferBarriers{ FramePool() }; bufferBarriers.reserve(desc.bufferBarriersCount); pmr::vector imageBarriers{ FramePool() }; imageBarriers.reserve(desc.textureBarriersCount); using api::ResourceState; + VkPipelineStageFlags srcStageMask, dstStageMask; for (uint32_t i = 0; i < desc.textureBarriersCount; i++) { auto& barrier = desc.pTextureBarriers[i]; + auto desc = GetVkTextureTransition(srcStageMask, dstStageMask, barrier); + imageBarriers.push_back(desc); } + vkCmdPipelineBarrier(ctx.command, srcStageMask, dstStageMask, 0, 0,NULL, 0, NULL, imageBarriers.size(), imageBarriers.data()); } void VulkanAPI::BeginRenderPass(RenderPassNode* node) { diff --git a/engine/modules/render/vulkan/src/vulkan_api_help.cpp b/engine/modules/render/vulkan/src/vulkan_api_help.cpp index a51f88b..9112cbc 100644 --- a/engine/modules/render/vulkan/src/vulkan_api_help.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api_help.cpp @@ -1,10 +1,35 @@ #include #include "vkn/vulkan_api_help.h" namespace vkn { - using api::ResourceState; - inline std::tuple - getVkTransition(const api::TextureBarrier& barrier) { + VkImageLayout GetVkLayout(ResourceState layout) { + switch (layout) { + case ResourceState::UNDEFINED: + return VK_IMAGE_LAYOUT_UNDEFINED; + case ResourceState::READ_WRITE: + return VK_IMAGE_LAYOUT_GENERAL; + case ResourceState::READ_ONLY: + return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + case ResourceState::TRANSFER_SRC: + return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case ResourceState::TRANSFER_DST: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case ResourceState::DEPTH_ATTACHMENT: + return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case ResourceState::DEPTH_SAMPLER: + return VK_IMAGE_LAYOUT_GENERAL; + case ResourceState::PRESENT: + return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + // Filament sometimes samples from one miplevel while writing to another level in the + // same texture (e.g. bloom does this). Moreover we'd like to avoid lots of expensive + // layout transitions. So, keep it simple and use GENERAL for all color-attachable + // textures. + case ResourceState::COLOR_ATTACHMENT: + return VK_IMAGE_LAYOUT_GENERAL; + case ResourceState::COLOR_ATTACHMENT_RESOLVE: + return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + } + VkImageMemoryBarrier GetVkTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags mDstStage, const TextureBarrier& barrier) { VkAccessFlags srcAccessMask, dstAccessMask; VkPipelineStageFlags srcStage, dstStage; @@ -96,8 +121,18 @@ namespace vkn { dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; break; } - - return std::make_tuple(srcAccessMask, dstAccessMask, srcStage, dstStage, - getVkLayout(transition.oldLayout), getVkLayout(transition.newLayout)); + mSrcStage |= srcStage; + mDstStage |= dstStage; + return VkImageMemoryBarrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = srcAccessMask, + .dstAccessMask = dstAccessMask, + .oldLayout = GetVkLayout(barrier.mSrcState), + .newLayout = GetVkLayout(barrier.mDstState), + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = (VkImage)barrier.mTexture.image, + //.subresourceRange = transition.subresources, + }; } } \ No newline at end of file diff --git a/engine/modules/render/vulkan/src/vulkan_window.cpp b/engine/modules/render/vulkan/src/vulkan_window.cpp index 8bcb606..80b397e 100644 --- a/engine/modules/render/vulkan/src/vulkan_window.cpp +++ b/engine/modules/render/vulkan/src/vulkan_window.cpp @@ -4,6 +4,8 @@ #include "vkn/vulkan_api.h" #include "vkn/backend.h" #include "vkn/thread/command_worker.h" +#include "render/asset/texture.h" +#include "asset/resource_system.h" #include "zlog.h" #include namespace vkn { @@ -58,11 +60,16 @@ namespace vkn { swapchain_images.resize(imageCount); vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data()); mFences.reserve(mFrames); + mSurfaces.reserve(mFrames); + mCommands.reserve(mFrames); mSemaphores.reserve(mFrames + mFrames); for (int i = 0; i < mFrames; i++) { - //mSurfaces.push_back(new Image(Creator.device, "swapchain" + to_string(i), swapchain_images[i], args)); + api::TextureDesc desc; + desc.image = swapchain_images[i]; + mSurfaces.push_back(desc); mSemaphores.push_back(mDevice.CreateSemaphore()); mSemaphores.push_back(mDevice.CreateSemaphore()); + mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)); mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT)); } } @@ -70,6 +77,8 @@ namespace vkn { { VkFence surfaceFence = mFences[ctx.frame]; VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame]; + ctx.surface = mSurfaces[ctx.frame]; + ctx.command = mCommands[ctx.frame]; ctx.surfaceSemaphore = surfaceSemaphore; ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames]; if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS)