From a0446d945156000a4c299a070ab51ac2c61fae8f Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 10 Sep 2024 14:43:07 +0800 Subject: [PATCH 1/3] fix trivial --- native/cocos/renderer/pipeline/custom/LayoutGraphTypes.h | 6 +++--- native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp | 6 +++--- native/cocos/renderer/pipeline/custom/RenderGraphTypes.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/LayoutGraphTypes.h b/native/cocos/renderer/pipeline/custom/LayoutGraphTypes.h index b966b47b176..ea518ded3e3 100644 --- a/native/cocos/renderer/pipeline/custom/LayoutGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/LayoutGraphTypes.h @@ -314,14 +314,14 @@ inline bool operator<(const NameLocalID& lhs, const NameLocalID& rhs) noexcept { struct DescriptorData { DescriptorData() = default; - DescriptorData(NameLocalID descriptorIDIn, gfx::Type typeIn, uint32_t countIn) noexcept + DescriptorData(const NameLocalID& descriptorIDIn, gfx::Type typeIn, uint32_t countIn) noexcept : descriptorID(descriptorIDIn), type(typeIn), count(countIn) {} - DescriptorData(NameLocalID descriptorIDIn, gfx::Type typeIn) noexcept + DescriptorData(const NameLocalID& descriptorIDIn, gfx::Type typeIn) noexcept : descriptorID(descriptorIDIn), type(typeIn) {} - DescriptorData(NameLocalID descriptorIDIn) noexcept // NOLINT + DescriptorData(const NameLocalID& descriptorIDIn) noexcept // NOLINT : descriptorID(descriptorIDIn) {} NameLocalID descriptorID; diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp index fccfe23a326..b080af58e3a 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp @@ -38,7 +38,7 @@ RasterView::RasterView(const allocator_type& alloc) noexcept : slotName(alloc), slotName1(alloc) {} -RasterView::RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT +RasterView::RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT : slotName(std::move(slotNameIn), alloc), slotName1(alloc), accessType(accessTypeIn), @@ -49,7 +49,7 @@ RasterView::RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, A clearColor(clearColorIn), shaderStageFlags(shaderStageFlagsIn) {} -RasterView::RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT +RasterView::RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT : slotName(std::move(slotNameIn), alloc), slotName1(std::move(slotName1In), alloc), accessType(accessTypeIn), @@ -378,7 +378,7 @@ RaytracePass::RaytracePass(RaytracePass const& rhs, const allocator_type& alloc) ClearView::ClearView(const allocator_type& alloc) noexcept : slotName(alloc) {} -ClearView::ClearView(ccstd::pmr::string slotNameIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, const allocator_type& alloc) noexcept +ClearView::ClearView(ccstd::pmr::string slotNameIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, const allocator_type& alloc) noexcept : slotName(std::move(slotNameIn), alloc), clearFlags(clearFlagsIn), clearColor(clearColorIn) {} diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index 7f7ee8197d3..524b5ad0367 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -85,8 +85,8 @@ struct RasterView { } RasterView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT - RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; - RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; RasterView(RasterView&& rhs, const allocator_type& alloc); RasterView(RasterView const& rhs, const allocator_type& alloc); @@ -843,7 +843,7 @@ struct ClearView { } ClearView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT - ClearView(ccstd::pmr::string slotNameIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + ClearView(ccstd::pmr::string slotNameIn, gfx::ClearFlagBit clearFlagsIn, const gfx::Color& clearColorIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; ClearView(ClearView&& rhs, const allocator_type& alloc); ClearView(ClearView const& rhs, const allocator_type& alloc); From 522cdc078199c62a01ffeb99cb4dbd7e67ba0b64 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 10 Sep 2024 18:50:57 +0800 Subject: [PATCH 2/3] merge fill render queue --- .../pipeline/custom/NativeExecutor.cpp | 4 +- .../pipeline/custom/NativePipelineFwd.h | 13 +- .../pipeline/custom/NativePipelineTypes.cpp | 17 +-- .../pipeline/custom/NativePipelineTypes.h | 56 ++++++-- .../pipeline/custom/NativeRenderQueue.cpp | 23 +-- .../pipeline/custom/NativeSceneCulling.cpp | 131 +++++++++++------- 6 files changed, 161 insertions(+), 83 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 0f43bc27342..df4f4e8069a 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -667,10 +667,10 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { tryBindLeafOverwritePerPassDescriptorSet(sceneID); } const auto* scene = camera->getScene(); - const auto& queueDesc = ctx.context.sceneCulling.renderQueueIndex.at(sceneID); + const auto& queueDesc = ctx.context.sceneCulling.renderQueueQueryIndex.at(sceneID); const auto& queue = ctx.context.sceneCulling.renderQueues[queueDesc.renderQueueTarget.value]; - queue.recordCommands(ctx.cmdBuff, ctx.currentPass, 0); + queue.recordCommands(ctx.cmdBuff, ctx.currentPass, 0, sceneData.flags); #if CC_USE_GEOMETRY_RENDERER if (any(sceneData.flags & SceneFlags::GEOMETRY) && diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h index 62729d3ae84..ffb1d497f3d 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h @@ -93,7 +93,8 @@ struct LightBoundsCullingID; struct LightBoundsCullingKey; struct LightBoundsCulling; struct NativeRenderQueueID; -struct NativeRenderQueueDesc; +struct NativeRenderQueueKey; +struct NativeRenderQueueQuery; struct LightBoundsCullingResult; struct SceneCulling; struct LightResource; @@ -123,11 +124,21 @@ struct hash { hash_t operator()(const cc::render::FrustumCullingID& val) const noexcept; }; +template <> +struct hash { + hash_t operator()(const cc::render::LightBoundsCullingID& val) const noexcept; +}; + template <> struct hash { hash_t operator()(const cc::render::LightBoundsCullingKey& val) const noexcept; }; +template <> +struct hash { + hash_t operator()(const cc::render::NativeRenderQueueKey& val) const noexcept; +}; + } // namespace ccstd // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp index 1e75b7d1b8f..ad67cf7679a 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp @@ -74,23 +74,14 @@ NativeRenderQueue::NativeRenderQueue(const allocator_type& alloc) noexcept opaqueInstancingQueue(alloc), transparentInstancingQueue(alloc) {} -NativeRenderQueue::NativeRenderQueue(SceneFlags sceneFlagsIn, uint32_t subpassOrPassLayoutIDIn, const allocator_type& alloc) noexcept -: opaqueQueue(alloc), - transparentQueue(alloc), - probeQueue(alloc), - opaqueInstancingQueue(alloc), - transparentInstancingQueue(alloc), - sceneFlags(sceneFlagsIn), - subpassOrPassLayoutID(subpassOrPassLayoutIDIn) {} - NativeRenderQueue::NativeRenderQueue(NativeRenderQueue&& rhs, const allocator_type& alloc) : opaqueQueue(std::move(rhs.opaqueQueue), alloc), transparentQueue(std::move(rhs.transparentQueue), alloc), probeQueue(std::move(rhs.probeQueue), alloc), opaqueInstancingQueue(std::move(rhs.opaqueInstancingQueue), alloc), transparentInstancingQueue(std::move(rhs.transparentInstancingQueue), alloc), + camera(rhs.camera), sceneFlags(rhs.sceneFlags), - subpassOrPassLayoutID(rhs.subpassOrPassLayoutID), lightByteOffset(rhs.lightByteOffset) {} ResourceGroup::ResourceGroup(const allocator_type& alloc) noexcept @@ -195,16 +186,18 @@ SceneCulling::SceneCulling(const allocator_type& alloc) noexcept frustumCullingResults(alloc), lightBoundsCullings(alloc), lightBoundsCullingResults(alloc), + renderQueueIndex(alloc), renderQueues(alloc), - renderQueueIndex(alloc) {} + renderQueueQueryIndex(alloc) {} SceneCulling::SceneCulling(SceneCulling&& rhs, const allocator_type& alloc) : frustumCullings(std::move(rhs.frustumCullings), alloc), frustumCullingResults(std::move(rhs.frustumCullingResults), alloc), lightBoundsCullings(std::move(rhs.lightBoundsCullings), alloc), lightBoundsCullingResults(std::move(rhs.lightBoundsCullingResults), alloc), - renderQueues(std::move(rhs.renderQueues), alloc), renderQueueIndex(std::move(rhs.renderQueueIndex), alloc), + renderQueues(std::move(rhs.renderQueues), alloc), + renderQueueQueryIndex(std::move(rhs.renderQueueQueryIndex), alloc), numFrustumCulling(rhs.numFrustumCulling), numLightBoundsCulling(rhs.numLightBoundsCulling), numRenderQueues(rhs.numRenderQueues), diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index bddd3632c1f..920d5f0b125 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -1083,7 +1083,6 @@ struct NativeRenderQueue { } NativeRenderQueue(const allocator_type& alloc) noexcept; // NOLINT - NativeRenderQueue(SceneFlags sceneFlagsIn, uint32_t subpassOrPassLayoutIDIn, const allocator_type& alloc) noexcept; NativeRenderQueue(NativeRenderQueue&& rhs, const allocator_type& alloc); NativeRenderQueue(NativeRenderQueue&& rhs) noexcept = default; @@ -1095,15 +1094,15 @@ struct NativeRenderQueue { void clear() noexcept; bool empty() const noexcept; void recordCommands( - gfx::CommandBuffer *cmdBuffer, gfx::RenderPass *renderPass, uint32_t subpassIndex) const; + gfx::CommandBuffer *cmdBuffer, gfx::RenderPass *renderPass, uint32_t subpassIndex, SceneFlags sceneFlags) const; RenderDrawQueue opaqueQueue; RenderDrawQueue transparentQueue; ProbeHelperQueue probeQueue; RenderInstancingQueue opaqueInstancingQueue; RenderInstancingQueue transparentInstancingQueue; + const scene::Camera* camera{nullptr}; SceneFlags sceneFlags{SceneFlags::NONE}; - uint32_t subpassOrPassLayoutID{0xFFFFFFFF}; uint32_t lightByteOffset{0xFFFFFFFF}; }; @@ -1332,6 +1331,15 @@ struct LightBoundsCullingID { uint32_t value{0xFFFFFFFF}; }; +inline bool operator==(const LightBoundsCullingID& lhs, const LightBoundsCullingID& rhs) noexcept { + return std::forward_as_tuple(lhs.value) == + std::forward_as_tuple(rhs.value); +} + +inline bool operator!=(const LightBoundsCullingID& lhs, const LightBoundsCullingID& rhs) noexcept { + return !(lhs == rhs); +} + struct LightBoundsCullingKey { FrustumCullingID frustumCullingID; const scene::Camera* camera{nullptr}; @@ -1374,11 +1382,25 @@ struct NativeRenderQueueID { uint32_t value{0xFFFFFFFF}; }; -struct NativeRenderQueueDesc { +struct NativeRenderQueueKey { + FrustumCullingID frustumCulledResultID; + LightBoundsCullingID lightBoundsCulledResultID; + uint32_t queueLayoutID{0xFFFFFFFF}; +}; + +inline bool operator==(const NativeRenderQueueKey& lhs, const NativeRenderQueueKey& rhs) noexcept { + return std::forward_as_tuple(lhs.frustumCulledResultID, lhs.lightBoundsCulledResultID, lhs.queueLayoutID) == + std::forward_as_tuple(rhs.frustumCulledResultID, rhs.lightBoundsCulledResultID, rhs.queueLayoutID); +} + +inline bool operator!=(const NativeRenderQueueKey& lhs, const NativeRenderQueueKey& rhs) noexcept { + return !(lhs == rhs); +} + +struct NativeRenderQueueQuery { FrustumCullingID frustumCulledResultID; LightBoundsCullingID lightBoundsCulledResultID; NativeRenderQueueID renderQueueTarget; - scene::LightType lightType{scene::LightType::UNKNOWN}; }; struct LightBoundsCullingResult { @@ -1405,18 +1427,20 @@ struct SceneCulling { private: FrustumCullingID getOrCreateFrustumCulling(const SceneData& sceneData); LightBoundsCullingID getOrCreateLightBoundsCulling(const SceneData& sceneData, FrustumCullingID frustumCullingID); - NativeRenderQueueID createRenderQueue(SceneFlags sceneFlags, LayoutGraphData::vertex_descriptor subpassOrPassLayoutID); - void collectCullingQueries(const RenderGraph& rg, const LayoutGraphData& lg); + NativeRenderQueueID getOrCreateRenderQueue( + const NativeRenderQueueKey& renderQueueKey, SceneFlags sceneFlags, const scene::Camera* camera); + void collectCullingQueries(const RenderGraph& rg); void batchFrustumCulling(const NativePipeline& ppl); void batchLightBoundsCulling(); - void fillRenderQueues(const RenderGraph& rg, const pipeline::PipelineSceneData& pplSceneData); + void fillRenderQueues(const pipeline::PipelineSceneData& pplSceneData); public: ccstd::pmr::unordered_map frustumCullings; ccstd::pmr::vector> frustumCullingResults; ccstd::pmr::unordered_map lightBoundsCullings; ccstd::pmr::vector lightBoundsCullingResults; + ccstd::pmr::unordered_map renderQueueIndex; ccstd::pmr::vector renderQueues; - PmrFlatMap renderQueueIndex; + PmrFlatMap renderQueueQueryIndex; uint32_t numFrustumCulling{0}; uint32_t numLightBoundsCulling{0}; uint32_t numRenderQueues{0}; @@ -1754,6 +1778,12 @@ inline hash_t hash::operator()(const cc::render::F return seed; } +inline hash_t hash::operator()(const cc::render::LightBoundsCullingID& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.value); + return seed; +} + inline hash_t hash::operator()(const cc::render::LightBoundsCullingKey& val) const noexcept { hash_t seed = 0; hash_combine(seed, val.frustumCullingID); @@ -1763,6 +1793,14 @@ inline hash_t hash::operator()(const cc::rend return seed; } +inline hash_t hash::operator()(const cc::render::NativeRenderQueueKey& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.frustumCulledResultID); + hash_combine(seed, val.lightBoundsCulledResultID); + hash_combine(seed, val.queueLayoutID); + return seed; +} + } // namespace ccstd // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderQueue.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderQueue.cpp index 9dbf4a81641..effaae9952e 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderQueue.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderQueue.cpp @@ -254,15 +254,20 @@ void NativeRenderQueue::sort() { void NativeRenderQueue::recordCommands( gfx::CommandBuffer *cmdBuffer, gfx::RenderPass *renderPass, - uint32_t subpassIndex) const { - opaqueQueue.recordCommandBuffer( - renderPass, subpassIndex, cmdBuffer, lightByteOffset); - opaqueInstancingQueue.recordCommandBuffer( - renderPass, subpassIndex, cmdBuffer, lightByteOffset); - transparentQueue.recordCommandBuffer( - renderPass, subpassIndex, cmdBuffer, lightByteOffset); - transparentInstancingQueue.recordCommandBuffer( - renderPass, subpassIndex, cmdBuffer, lightByteOffset); + uint32_t subpassIndex, + SceneFlags sceneFlags) const { + if (any(sceneFlags & (SceneFlags::OPAQUE | SceneFlags::MASK))) { + opaqueQueue.recordCommandBuffer( + renderPass, subpassIndex, cmdBuffer, lightByteOffset); + opaqueInstancingQueue.recordCommandBuffer( + renderPass, subpassIndex, cmdBuffer, lightByteOffset); + } + if (any(sceneFlags & SceneFlags::BLEND)) { + transparentQueue.recordCommandBuffer( + renderPass, subpassIndex, cmdBuffer, lightByteOffset); + transparentInstancingQueue.recordCommandBuffer( + renderPass, subpassIndex, cmdBuffer, lightByteOffset); + } } } // namespace render diff --git a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp index 0e4a7aacba0..36e4a09c979 100644 --- a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp @@ -2,7 +2,7 @@ #include "cocos/renderer/pipeline/custom/LayoutGraphUtils.h" #include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h" #include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" -#include "cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" #include "cocos/renderer/pipeline/custom/details/GslUtils.h" #include "cocos/renderer/pipeline/custom/details/Range.h" #include "cocos/scene/Octree.h" @@ -31,8 +31,9 @@ void NativeRenderQueue::clear() noexcept { transparentQueue.instances.clear(); opaqueInstancingQueue.clear(); transparentInstancingQueue.clear(); + camera = nullptr; sceneFlags = SceneFlags::NONE; - subpassOrPassLayoutID = 0xFFFFFFFF; + lightByteOffset = 0xFFFFFFFF; } bool NativeRenderQueue::empty() const noexcept { @@ -127,25 +128,47 @@ LightBoundsCullingID SceneCulling::getOrCreateLightBoundsCulling( return iter->second; } -NativeRenderQueueID SceneCulling::createRenderQueue( - SceneFlags sceneFlags, LayoutGraphData::vertex_descriptor subpassOrPassLayoutID) { +NativeRenderQueueID SceneCulling::getOrCreateRenderQueue( + const NativeRenderQueueKey& renderQueueKey, SceneFlags sceneFlags, const scene::Camera* camera) { + constexpr auto categoryMask = SceneFlags::SHADOW_CASTER | SceneFlags::REFLECTION_PROBE; + constexpr auto drawMask = SceneFlags::OPAQUE | SceneFlags::MASK | SceneFlags::BLEND; + constexpr auto allMask = categoryMask | drawMask; + + auto iter = renderQueueIndex.find(renderQueueKey); + if (iter != renderQueueIndex.end()) { + auto& rq = renderQueues[iter->second.value]; + CC_EXPECTS(rq.camera == camera); + CC_EXPECTS((sceneFlags & categoryMask) == (rq.sceneFlags & categoryMask)); + // merge scene flags + rq.sceneFlags |= sceneFlags & drawMask; + return iter->second; + } + const auto targetID = numRenderQueues++; + + // renderQueues are not cleared, so we can reuse the space + // this->renderQueues.size() is more like a capacity if (numRenderQueues > renderQueues.size()) { CC_EXPECTS(numRenderQueues == renderQueues.size() + 1); renderQueues.emplace_back(); } + + // Update render queue index + auto res = renderQueueIndex.emplace(renderQueueKey, NativeRenderQueueID{targetID}); + CC_ENSURES(res.second); + CC_ENSURES(targetID < renderQueues.size()); auto& rq = renderQueues[targetID]; CC_EXPECTS(rq.empty()); + CC_EXPECTS(rq.camera == nullptr); CC_EXPECTS(rq.sceneFlags == SceneFlags::NONE); - CC_EXPECTS(rq.subpassOrPassLayoutID == 0xFFFFFFFF); - rq.sceneFlags = sceneFlags; - rq.subpassOrPassLayoutID = subpassOrPassLayoutID; + + rq.camera = camera; + rq.sceneFlags = sceneFlags & allMask; return NativeRenderQueueID{targetID}; } -void SceneCulling::collectCullingQueries( - const RenderGraph& rg, const LayoutGraphData& lg) { +void SceneCulling::collectCullingQueries(const RenderGraph& rg) { for (const auto vertID : makeRange(vertices(rg))) { if (!holds(vertID, rg)) { continue; @@ -157,21 +180,33 @@ void SceneCulling::collectCullingQueries( } const auto frustomCulledResultID = getOrCreateFrustumCulling(sceneData); const auto lightBoundsCullingID = getOrCreateLightBoundsCulling(sceneData, frustomCulledResultID); - const auto layoutID = getSubpassOrPassID(vertID, rg, lg); - const auto targetID = createRenderQueue(sceneData.flags, layoutID); - const auto lightType = sceneData.light.light - ? sceneData.light.light->getType() - : scene::LightType::UNKNOWN; - - // add render queue to query source - renderQueueIndex.emplace( + + // Get render queue phaseLayoutID + const auto queueID = parent(vertID, rg); + CC_ENSURES(queueID != RenderGraph::null_vertex()); + CC_EXPECTS(holds(queueID, rg)); + const auto& renderQueue = get(QueueTag{}, queueID, rg); + const auto phaseLayoutID = renderQueue.phaseID; + CC_EXPECTS(phaseLayoutID != LayoutGraphData::null_vertex()); + + // Make render queue key + NativeRenderQueueKey renderQueueKey{ + frustomCulledResultID, + lightBoundsCullingID, + phaseLayoutID, + }; + + // Get or create render queue + const auto renderQueueID = getOrCreateRenderQueue(renderQueueKey, sceneData.flags, sceneData.camera); + + // add render queue query + auto res = renderQueueQueryIndex.emplace( vertID, - NativeRenderQueueDesc{ + NativeRenderQueueQuery{ frustomCulledResultID, lightBoundsCullingID, - targetID, - lightType, - }); + renderQueueID}); + CC_ENSURES(res.second); } } @@ -582,31 +617,29 @@ void addRenderObject( } // namespace -void SceneCulling::fillRenderQueues( - const RenderGraph& rg, const pipeline::PipelineSceneData& pplSceneData) { +void SceneCulling::fillRenderQueues(const pipeline::PipelineSceneData& pplSceneData) { const auto* const skybox = pplSceneData.getSkybox(); - for (auto&& [sceneID, desc] : renderQueueIndex) { - CC_EXPECTS(holds(sceneID, rg)); - const auto frustomCulledResultID = desc.frustumCulledResultID; - const auto lightBoundsCullingID = desc.lightBoundsCulledResultID; - const auto targetID = desc.renderQueueTarget; - const auto& sceneData = get(SceneTag{}, sceneID, rg); + for (const auto& [key, targetID] : renderQueueIndex) { + // native queue target + CC_EXPECTS(targetID.value < renderQueues.size()); + auto& nativeQueue = renderQueues[targetID.value]; + CC_EXPECTS(nativeQueue.empty()); + + const auto frustomCulledResultID = key.frustumCulledResultID; + const auto lightBoundsCullingID = key.lightBoundsCulledResultID; // check scene flags - const bool bDrawBlend = any(sceneData.flags & SceneFlags::TRANSPARENT_OBJECT); - const bool bDrawOpaqueOrMask = any(sceneData.flags & (SceneFlags::OPAQUE_OBJECT | SceneFlags::CUTOUT_OBJECT)); - const bool bDrawShadowCaster = any(sceneData.flags & SceneFlags::SHADOW_CASTER); - const bool bDrawProbe = any(sceneData.flags & SceneFlags::REFLECTION_PROBE); + const bool bDrawBlend = any(nativeQueue.sceneFlags & SceneFlags::BLEND); + const bool bDrawOpaqueOrMask = any(nativeQueue.sceneFlags & (SceneFlags::OPAQUE | SceneFlags::MASK)); + const bool bDrawShadowCaster = any(nativeQueue.sceneFlags & SceneFlags::SHADOW_CASTER); + const bool bDrawProbe = any(nativeQueue.sceneFlags & SceneFlags::REFLECTION_PROBE); if (!bDrawShadowCaster && !bDrawBlend && !bDrawOpaqueOrMask && !bDrawProbe) { // nothing to draw continue; } // render queue info - const auto renderQueueID = parent(sceneID, rg); - CC_EXPECTS(holds(renderQueueID, rg)); - const auto& renderQueue = get(QueueTag{}, renderQueueID, rg); - const auto phaseLayoutID = renderQueue.phaseID; + const auto phaseLayoutID = key.queueLayoutID; CC_EXPECTS(phaseLayoutID != LayoutGraphData::null_vertex()); // culling source @@ -621,20 +654,15 @@ void SceneCulling::fillRenderQueues( return frustumCullingResults.at(frustomCulledResultID.value); }(); - // native queue target - CC_EXPECTS(targetID.value < renderQueues.size()); - auto& nativeQueue = renderQueues[targetID.value]; - CC_EXPECTS(nativeQueue.empty()); - // skybox - const auto* camera = sceneData.camera; + const auto* camera = nativeQueue.camera; CC_EXPECTS(camera); // fill native queue for (const auto* const model : sourceModels) { addRenderObject( phaseLayoutID, bDrawOpaqueOrMask, bDrawBlend, - bDrawProbe, *sceneData.camera, *model, nativeQueue); + bDrawProbe, *camera, *model, nativeQueue); } // post-processing @@ -647,10 +675,10 @@ void SceneCulling::buildRenderQueues( const NativePipeline& ppl) { kPipelineSceneData = ppl.pipelineSceneData; kLayoutGraph = ≶ - collectCullingQueries(rg, lg); + collectCullingQueries(rg); batchFrustumCulling(ppl); batchLightBoundsCulling(); // cull frustum-culling's results by light bounds - fillRenderQueues(rg, *ppl.pipelineSceneData); + fillRenderQueues(*ppl.pipelineSceneData); } void SceneCulling::clear() noexcept { @@ -670,10 +698,13 @@ void SceneCulling::clear() noexcept { q.clear(); } - // clear render graph scene vertex query index + // clear render queue index renderQueueIndex.clear(); // do not clear this->renderQueues, it is reused to avoid memory allocation + // clear render graph scene vertex query index + renderQueueQueryIndex.clear(); + // reset all counters numFrustumCulling = 0; numLightBoundsCulling = 0; @@ -780,12 +811,12 @@ void LightResource::buildLights( } // assign light byte offset to each queue - for (const auto& [sceneID, desc] : sceneCulling.renderQueueIndex) { + for (const auto& [sceneID, desc] : sceneCulling.renderQueueQueryIndex) { if (desc.lightBoundsCulledResultID.value == 0xFFFFFFFF) { continue; } - const auto lightByteOffset = sceneCulling.lightBoundsCullingResults.at( - desc.lightBoundsCulledResultID.value) + const auto lightByteOffset = sceneCulling.lightBoundsCullingResults + .at(desc.lightBoundsCulledResultID.value) .lightByteOffset; sceneCulling.renderQueues.at(desc.renderQueueTarget.value).lightByteOffset = lightByteOffset; From 67f182b69281c2337d9f386a3e5b9a2a3701dcc2 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 10 Sep 2024 19:09:37 +0800 Subject: [PATCH 3/3] simplify code --- native/cocos/renderer/pipeline/custom/NativePipelineTypes.h | 2 +- native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index 920d5f0b125..fbe1bbc7024 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -1432,7 +1432,7 @@ struct SceneCulling { void collectCullingQueries(const RenderGraph& rg); void batchFrustumCulling(const NativePipeline& ppl); void batchLightBoundsCulling(); - void fillRenderQueues(const pipeline::PipelineSceneData& pplSceneData); + void fillRenderQueues(); public: ccstd::pmr::unordered_map frustumCullings; ccstd::pmr::vector> frustumCullingResults; diff --git a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp index 36e4a09c979..ebb54197adb 100644 --- a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp @@ -617,8 +617,7 @@ void addRenderObject( } // namespace -void SceneCulling::fillRenderQueues(const pipeline::PipelineSceneData& pplSceneData) { - const auto* const skybox = pplSceneData.getSkybox(); +void SceneCulling::fillRenderQueues() { for (const auto& [key, targetID] : renderQueueIndex) { // native queue target CC_EXPECTS(targetID.value < renderQueues.size()); @@ -678,7 +677,7 @@ void SceneCulling::buildRenderQueues( collectCullingQueries(rg); batchFrustumCulling(ppl); batchLightBoundsCulling(); // cull frustum-culling's results by light bounds - fillRenderQueues(*ppl.pipelineSceneData); + fillRenderQueues(); } void SceneCulling::clear() noexcept {