diff --git a/engine/include/editor/api.h b/engine/include/editor/api.h index ccba8af..7b9637e 100644 --- a/engine/include/editor/api.h +++ b/engine/include/editor/api.h @@ -1,2 +1 @@ -#pragma once -EDITOR_API extern int editor_v; \ No newline at end of file +#pragma once \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/graph/type.h b/engine/modules/engine/render/include/render/graph/type.h index 6d77aa0..87fb30f 100644 --- a/engine/modules/engine/render/include/render/graph/type.h +++ b/engine/modules/engine/render/include/render/graph/type.h @@ -4,14 +4,17 @@ #include "lemon/list_graph.h" #include namespace api { + struct RenderPassNode; struct RenderContext; struct ComputePassContext {}; struct RenderPassContext { RenderContext* parent; - RenderPassContext(RenderContext* parent) : parent(parent) {}; + RenderPassNode* node; + RenderPassContext(RenderContext* parent, RenderPassNode* node) : parent(parent),node(node) {}; RenderContext* operator->() { return parent; } + size_t PassKey(); }; struct CopyPassContext {}; @@ -88,7 +91,8 @@ namespace api { }; using RenderPassEdgeIterFn = std::function; struct RenderPassNode { - Name name; + Name name; + size_t hash; RenderPassNodeExecuteFn executor; pmr::vector inEdges{ FramePool() }; pmr::vector outEdges{ FramePool() }; @@ -120,4 +124,8 @@ namespace api { node = new (FramePool()) RenderPassNode(); node->executor = executor; } + inline size_t RenderPassContext::PassKey() + { + return node->hash; + } } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/renderapi.h b/engine/modules/engine/render/include/render/renderapi.h index 60f7916..2b139a5 100644 --- a/engine/modules/engine/render/include/render/renderapi.h +++ b/engine/modules/engine/render/include/render/renderapi.h @@ -27,7 +27,7 @@ namespace api { virtual void SetStaticMesh(Mesh& mesh) = 0; virtual void DrawStaticMesh(Mesh& mesh) = 0; - virtual void LoadShader(Shader& shader) = 0; + virtual void LoadShader(Shader& shader, size_t passKey) = 0; virtual ImagePtr CreateTexture(TextureDesc desc) = 0; virtual ImageViewPtr CreateTextureView(TextureViewDesc desc) = 0; diff --git a/engine/modules/engine/render/src/graph/frame_graph.cpp b/engine/modules/engine/render/src/graph/frame_graph.cpp index ea4b6ca..b6d24da 100644 --- a/engine/modules/engine/render/src/graph/frame_graph.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph.cpp @@ -88,7 +88,7 @@ namespace api { { ExecuteResourceBarriers(node); RenderAPI::Ptr()->BeginRenderPass(node); - RenderPassContext context{view.context}; + RenderPassContext context{view.context, node}; std::get(node->executor)(*this, context); RenderAPI::Ptr()->EndRenderPass(node); } diff --git a/engine/modules/engine/render/src/pass/demo_pass.cpp b/engine/modules/engine/render/src/pass/demo_pass.cpp index 7e2259f..b438344 100644 --- a/engine/modules/engine/render/src/pass/demo_pass.cpp +++ b/engine/modules/engine/render/src/pass/demo_pass.cpp @@ -11,25 +11,6 @@ namespace api { static RscHandle mesh; bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) { - if (!shader) { - shader = ResourceSystem::Ptr()->LoadEmplaceResource(); - shader->Name("api::PosVertex"); - auto vert = ResourceSystem::Ptr()->Load("/engine/assets/shader/simple.vert"); - auto frag = ResourceSystem::Ptr()->Load("/engine/assets/shader/simple.frag"); - shader->SetVertHandle(vert); - shader->SetFragHandle(frag); - RenderAPI::Ptr()->LoadShader(*shader); - vector vertices = { - {.Position = { 0.0f, -0.5f, 0.f}}, // 底部顶点,红色 - {.Position = { 0.5f, 0.5f, 0.f}}, // 右上顶点,绿色 - {.Position = {-0.5f, 0.5f, 0.f}} // 左上顶点,蓝色 - }; - vector indices = {0, 1, 2}; - mesh = ResourceSystem::Ptr()->LoadEmplaceResource(vertices, indices); - material = ResourceSystem::Ptr()->LoadEmplaceResource(shader); - mesh->SetMaterial(material); - RenderAPI::Ptr()->SetStaticMesh(*mesh); - } AttachmentDesc surface{}; surface.FromTexture(graph.mSurface); surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB; @@ -45,6 +26,25 @@ namespace api { } void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx) { + if (!shader) { + shader = ResourceSystem::Ptr()->LoadEmplaceResource(); + shader->Name("api::PosVertex"); + auto vert = ResourceSystem::Ptr()->Load("/engine/assets/shader/simple.vert"); + auto frag = ResourceSystem::Ptr()->Load("/engine/assets/shader/simple.frag"); + shader->SetVertHandle(vert); + shader->SetFragHandle(frag); + RenderAPI::Ptr()->LoadShader(*shader, ctx.PassKey()); + vector vertices = { + {.Position = { 0.0f, -0.5f, 0.f}}, // 底部顶点,红色 + {.Position = { 0.5f, 0.5f, 0.f}}, // 右上顶点,绿色 + {.Position = {-0.5f, 0.5f, 0.f}} // 左上顶点,蓝色 + }; + vector indices = { 0, 1, 2 }; + mesh = ResourceSystem::Ptr()->LoadEmplaceResource(vertices, indices); + material = ResourceSystem::Ptr()->LoadEmplaceResource(shader); + mesh->SetMaterial(material); + RenderAPI::Ptr()->SetStaticMesh(*mesh); + } auto& surface = graph.mSurface; ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f); ctx->SetScissor(0, 0, surface.width, surface.height); diff --git a/engine/modules/engine/zlib/include/refl/detail/uclass.inl b/engine/modules/engine/zlib/include/refl/detail/uclass.inl index bc90c83..aad47ec 100644 --- a/engine/modules/engine/zlib/include/refl/detail/uclass.inl +++ b/engine/modules/engine/zlib/include/refl/detail/uclass.inl @@ -341,4 +341,11 @@ namespace refl { } meta_info(); } + inline const UClass* find_meta(Name name, size_t hash) { + auto it = find_info(name); + if (it) { + return it->GetMeta(hash); + } + return nullptr; + } } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/type.h b/engine/modules/render/vulkan/include/vkn/type.h index 1806676..b68f528 100644 --- a/engine/modules/render/vulkan/include/vkn/type.h +++ b/engine/modules/render/vulkan/include/vkn/type.h @@ -38,6 +38,7 @@ namespace vkn { bool inUse = false; }; struct RenderPassKey { + VkRenderPass pass; VkFormat colorFormat[8]; VkFormat depthFormat; VkSampleCountFlagBits samples; @@ -47,6 +48,9 @@ namespace vkn { uint8_t subpassMask;// 1 byte uint8_t initialColorLayoutMask;// 1 byte uint8_t needsResolveMask; // 1 byte + operator size_t() { + return meta::MurmurHashFn(this); + } }; struct FramebufferKey { VkRenderPass pass; @@ -100,14 +104,6 @@ namespace vkn { }; } namespace std { - template<> - struct hash - { - size_t operator()(const vkn::RenderPassKey& key) const noexcept - { - return meta::MurmurHashFn(key); - } - }; template<> struct hash { diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index 5ff5e2d..dbecb7d 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -3,10 +3,7 @@ #include "asset/res/guid.h" #include "backend.h" namespace vkn { - class Backend; class VulkanWindow; - struct MeshVAO; - struct RenderPassKey; using api::Guid; using api::Mesh; using api::Shader; @@ -17,7 +14,7 @@ namespace vkn { Backend backend; table MeshTable; table PipelineTable; - table RenderPassCache; + table RenderPassCache; table FramebufferCache; public: VulkanAPI(); @@ -27,7 +24,7 @@ namespace vkn { void SetStaticMesh(Mesh& mesh)override; void DrawStaticMesh(Mesh& mesh)override; - void LoadShader(Shader& shader)override; + void LoadShader(Shader& shader, size_t passKey)override; ImagePtr CreateTexture(TextureDesc desc)override; ImageViewPtr CreateTextureView(TextureViewDesc desc)override; @@ -38,8 +35,7 @@ namespace vkn { void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override; VkPipeline GetPipeline() { return nullptr; }; - VkRenderPass GetRenderPass(RenderPassKey& config); - + VkRenderPass GetRenderPass(size_t hash, 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 3998b7d..148ab99 100644 --- a/engine/modules/render/vulkan/src/vulkan_api.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api.cpp @@ -11,20 +11,6 @@ #include "tinyimageformat/tinyimageformat_apis.h" #include "zlog.h" namespace vkn { - inline bool operator==(const RenderPassKey& k1, const RenderPassKey& k2) { - if (k1.initialColorLayoutMask != k2.initialColorLayoutMask) return false; - for (int i = 0; i < MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) { - if (k1.colorFormat[i] != k2.colorFormat[i]) return false; - } - if (k1.depthFormat != k2.depthFormat) return false; - if (k1.clear != k2.clear) return false; - if (k1.discardStart != k2.discardStart) return false; - if (k1.discardEnd != k2.discardEnd) return false; - if (k1.samples != k2.samples) return false; - if (k1.needsResolveMask != k2.needsResolveMask) return false; - if (k1.subpassMask != k2.subpassMask) return false; - return true; - } inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) { if (k1.pass != k2.pass) return false; if (k1.attachmentCount != k2.attachmentCount) return false; @@ -90,8 +76,13 @@ namespace vkn { vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE); vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0); } - void VulkanAPI::LoadShader(Shader& shader) + void VulkanAPI::LoadShader(Shader& shader, size_t passKey) { + auto itPass = RenderPassCache.find(passKey); + if (itPass == RenderPassCache.end()) { + return; + } + VkRenderPass renderpass = itPass->second.pass; pmr::vector shaderStages; std::map shaderModules; auto& device = backend.GetDevice(); @@ -108,8 +99,7 @@ namespace vkn { shaderStageInfo.pName = "main"; shaderStages.push_back(shaderStageInfo); } - auto it = refl::find_info(shader.Name()); - auto meta = it->GetMeta(string_hash("vkMeta")); + auto meta = refl::find_meta(shader.Name(),string_hash("vkMeta")); // 设置顶点输入格式 VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; VkVertexInputBindingDescription bindingDescription = {}; @@ -185,11 +175,6 @@ namespace vkn { multisampleInfo.pSampleMask = VK_NULL_HANDLE; multisampleInfo.alphaToCoverageEnable = VK_FALSE; multisampleInfo.alphaToOneEnable = VK_FALSE; - - RenderPassKey config{}; - config.colorFormat[0] = VK_FORMAT_B8G8R8A8_SRGB; - config.samples = vkApiGetSmpleCountFlag(api::SAMPLE_COUNT_1); - VkRenderPass renderpass = GetRenderPass(config); // Color Blend VkPipelineColorBlendAttachmentState colorBlendAttachment{}; colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -376,7 +361,8 @@ namespace vkn { } } frameKey.attachmentCount = i; - VkRenderPass pass = GetRenderPass(config); + node->hash = config; + VkRenderPass pass = GetRenderPass(node->hash, config); frameKey.pass = pass; auto it = FramebufferCache.find(frameKey); VkFramebuffer framebuffer = it->second; @@ -414,10 +400,10 @@ namespace vkn { VulkanContext& ctx = *(VulkanContext*)&context; vkCmdEndRenderPass(ctx.command); } - VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) { - auto it = RenderPassCache.find(config); + VkRenderPass VulkanAPI::GetRenderPass(size_t hash, RenderPassKey& config) { + auto it = RenderPassCache.find(hash); if (it != RenderPassCache.end()) { - return it->second; + return it->second.pass; } // Set up some const aliases for terseness. const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR; @@ -581,9 +567,8 @@ namespace vkn { }; } renderPassInfo.attachmentCount = attachmentIndex; - VkRenderPass renderPass; - VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &renderPass); - RenderPassCache.emplace(config, renderPass); - return renderPass; + VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &config.pass); + RenderPassCache.emplace(hash, config); + return config.pass; } } diff --git a/engine/src/editor/api.cpp b/engine/src/editor/api.cpp index faf0887..bfa6e39 100644 --- a/engine/src/editor/api.cpp +++ b/engine/src/editor/api.cpp @@ -1,2 +1 @@ -#include "api.h" -int editor_v; \ No newline at end of file +#include "api.h" \ No newline at end of file