no message
This commit is contained in:
45
cocos/renderer/pipeline/custom/ArchiveFwd.h
Normal file
45
cocos/renderer/pipeline/custom/ArchiveFwd.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class OutputArchive;
|
||||
class InputArchive;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
41
cocos/renderer/pipeline/custom/ArchiveTypes.cpp
Normal file
41
cocos/renderer/pipeline/custom/ArchiveTypes.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "ArchiveTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
74
cocos/renderer/pipeline/custom/ArchiveTypes.h
Normal file
74
cocos/renderer/pipeline/custom/ArchiveTypes.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <string_view>
|
||||
#include "cocos/renderer/pipeline/custom/ArchiveFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class OutputArchive {
|
||||
public:
|
||||
OutputArchive() noexcept = default;
|
||||
OutputArchive(OutputArchive&& rhs) = delete;
|
||||
OutputArchive(OutputArchive const& rhs) = delete;
|
||||
OutputArchive& operator=(OutputArchive&& rhs) = delete;
|
||||
OutputArchive& operator=(OutputArchive const& rhs) = delete;
|
||||
virtual ~OutputArchive() noexcept = default;
|
||||
|
||||
virtual void writeBool(bool value) = 0;
|
||||
virtual void writeNumber(double value) = 0;
|
||||
virtual void writeString(std::string_view value) = 0;
|
||||
virtual boost::container::pmr::memory_resource *scratch() const noexcept = 0;
|
||||
};
|
||||
|
||||
class InputArchive {
|
||||
public:
|
||||
InputArchive() noexcept = default;
|
||||
InputArchive(InputArchive&& rhs) = delete;
|
||||
InputArchive(InputArchive const& rhs) = delete;
|
||||
InputArchive& operator=(InputArchive&& rhs) = delete;
|
||||
InputArchive& operator=(InputArchive const& rhs) = delete;
|
||||
virtual ~InputArchive() noexcept = default;
|
||||
|
||||
virtual bool readBool() = 0;
|
||||
virtual double readNumber() = 0;
|
||||
virtual std::string_view readString() = 0;
|
||||
virtual boost::container::pmr::memory_resource *scratch() const noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
93
cocos/renderer/pipeline/custom/BinaryArchive.h
Normal file
93
cocos/renderer/pipeline/custom/BinaryArchive.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/renderer/pipeline/custom/ArchiveTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class BinaryOutputArchive final : public OutputArchive {
|
||||
public:
|
||||
BinaryOutputArchive(std::ostream& os, boost::container::pmr::memory_resource* scratch)
|
||||
: _os(os), _scratch(scratch) {}
|
||||
|
||||
void writeBool(bool value) override {
|
||||
uint8_t v = value ? 1 : 0;
|
||||
_os.write(reinterpret_cast<const char*>(&v), sizeof(v));
|
||||
}
|
||||
void writeNumber(double value) override {
|
||||
_os.write(reinterpret_cast<const char*>(&value), sizeof(value));
|
||||
}
|
||||
void writeString(std::string_view value) override {
|
||||
writeNumber(static_cast<double>(value.size()));
|
||||
_os.write(value.data(), static_cast<std::streamsize>(value.size()));
|
||||
}
|
||||
boost::container::pmr::memory_resource* scratch() const noexcept override {
|
||||
return _scratch;
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& _os;
|
||||
boost::container::pmr::memory_resource* _scratch;
|
||||
};
|
||||
|
||||
class BinaryInputArchive final : public InputArchive {
|
||||
public:
|
||||
BinaryInputArchive(std::istream& is, boost::container::pmr::memory_resource* scratch)
|
||||
: _is(is), _temp(scratch) {}
|
||||
|
||||
bool readBool() override {
|
||||
uint8_t v;
|
||||
_is.read(reinterpret_cast<char*>(&v), sizeof(v));
|
||||
return v != 0;
|
||||
}
|
||||
double readNumber() override {
|
||||
double v;
|
||||
_is.read(reinterpret_cast<char*>(&v), sizeof(v));
|
||||
return v;
|
||||
}
|
||||
std::string_view readString() override {
|
||||
double size = readNumber();
|
||||
_temp.resize(static_cast<size_t>(size));
|
||||
_is.read(_temp.data(), static_cast<std::streamsize>(size));
|
||||
return _temp;
|
||||
}
|
||||
boost::container::pmr::memory_resource* scratch() const noexcept override {
|
||||
return _temp.get_allocator().resource();
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream& _is;
|
||||
ccstd::pmr::string _temp;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
53
cocos/renderer/pipeline/custom/CustomFwd.h
Normal file
53
cocos/renderer/pipeline/custom/CustomFwd.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class Customization;
|
||||
class CustomPipelineContext;
|
||||
struct CustomRenderGraphContext;
|
||||
class CustomRenderPass;
|
||||
class CustomRenderSubpass;
|
||||
class CustomComputeSubpass;
|
||||
class CustomComputePass;
|
||||
class CustomRenderQueue;
|
||||
class CustomRenderCommand;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
41
cocos/renderer/pipeline/custom/CustomTypes.cpp
Normal file
41
cocos/renderer/pipeline/custom/CustomTypes.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "CustomTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
130
cocos/renderer/pipeline/custom/CustomTypes.h
Normal file
130
cocos/renderer/pipeline/custom/CustomTypes.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/renderer/pipeline/custom/CustomFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class Customization {
|
||||
public:
|
||||
Customization() noexcept = default;
|
||||
Customization(Customization&& rhs) = delete;
|
||||
Customization(Customization const& rhs) = delete;
|
||||
Customization& operator=(Customization&& rhs) = delete;
|
||||
Customization& operator=(Customization const& rhs) = delete;
|
||||
virtual ~Customization() noexcept = default;
|
||||
|
||||
virtual std::string_view getName() const noexcept = 0;
|
||||
};
|
||||
|
||||
class CustomPipelineContext : public Customization {
|
||||
public:
|
||||
CustomPipelineContext() noexcept = default;
|
||||
|
||||
virtual IntrusivePtr<gfx::Buffer> createCustomBuffer(std::string_view type, const gfx::BufferInfo &info) = 0;
|
||||
virtual IntrusivePtr<gfx::Texture> createCustomTexture(std::string_view type, const gfx::TextureInfo &info) = 0;
|
||||
virtual void destroy() noexcept = 0;
|
||||
};
|
||||
|
||||
struct CustomRenderGraphContext {
|
||||
std::shared_ptr<CustomPipelineContext> pipelineContext;
|
||||
const RenderGraph* renderGraph{nullptr};
|
||||
const ResourceGraph* resourceGraph{nullptr};
|
||||
gfx::CommandBuffer* primaryCommandBuffer{nullptr};
|
||||
};
|
||||
|
||||
class CustomRenderPass : public Customization {
|
||||
public:
|
||||
CustomRenderPass() noexcept = default;
|
||||
|
||||
virtual void beginRenderPass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endRenderPass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
class CustomRenderSubpass : public Customization {
|
||||
public:
|
||||
CustomRenderSubpass() noexcept = default;
|
||||
|
||||
virtual void beginRenderSubpass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endRenderSubpass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
class CustomComputeSubpass : public Customization {
|
||||
public:
|
||||
CustomComputeSubpass() noexcept = default;
|
||||
|
||||
virtual void beginComputeSubpass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endComputeSubpass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
class CustomComputePass : public Customization {
|
||||
public:
|
||||
CustomComputePass() noexcept = default;
|
||||
|
||||
virtual void beginComputePass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endComputePass(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
class CustomRenderQueue {
|
||||
public:
|
||||
CustomRenderQueue() noexcept = default;
|
||||
CustomRenderQueue(CustomRenderQueue&& rhs) = delete;
|
||||
CustomRenderQueue(CustomRenderQueue const& rhs) = delete;
|
||||
CustomRenderQueue& operator=(CustomRenderQueue&& rhs) = delete;
|
||||
CustomRenderQueue& operator=(CustomRenderQueue const& rhs) = delete;
|
||||
virtual ~CustomRenderQueue() noexcept = default;
|
||||
|
||||
virtual void beginRenderQueue(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endRenderQueue(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
class CustomRenderCommand {
|
||||
public:
|
||||
CustomRenderCommand() noexcept = default;
|
||||
CustomRenderCommand(CustomRenderCommand&& rhs) = delete;
|
||||
CustomRenderCommand(CustomRenderCommand const& rhs) = delete;
|
||||
CustomRenderCommand& operator=(CustomRenderCommand&& rhs) = delete;
|
||||
CustomRenderCommand& operator=(CustomRenderCommand const& rhs) = delete;
|
||||
virtual ~CustomRenderCommand() noexcept = default;
|
||||
|
||||
virtual void beginRenderCommand(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
virtual void endRenderCommand(const CustomRenderGraphContext &rg, RenderGraph::vertex_descriptor passID) = 0;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
962
cocos/renderer/pipeline/custom/FGDispatcherGraphs.h
Normal file
962
cocos/renderer/pipeline/custom/FGDispatcherGraphs.h
Normal file
@@ -0,0 +1,962 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include "cocos/renderer/pipeline/custom/FGDispatcherTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphImpl.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Overload.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/PathUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
// IncidenceGraph
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
source(const ResourceAccessGraph::edge_descriptor& e, const ResourceAccessGraph& /*g*/) noexcept {
|
||||
return e.source;
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
target(const ResourceAccessGraph::edge_descriptor& e, const ResourceAccessGraph& /*g*/) noexcept {
|
||||
return e.target;
|
||||
}
|
||||
|
||||
inline std::pair<ResourceAccessGraph::out_edge_iterator, ResourceAccessGraph::out_edge_iterator>
|
||||
out_edges(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
return std::make_pair(
|
||||
ResourceAccessGraph::out_edge_iterator(const_cast<ResourceAccessGraph&>(g).getOutEdgeList(u).begin(), u),
|
||||
ResourceAccessGraph::out_edge_iterator(const_cast<ResourceAccessGraph&>(g).getOutEdgeList(u).end(), u));
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::degree_size_type
|
||||
out_degree(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<ResourceAccessGraph::degree_size_type>(g.getOutEdgeList(u).size());
|
||||
}
|
||||
|
||||
inline std::pair<ResourceAccessGraph::edge_descriptor, bool>
|
||||
edge(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph::vertex_descriptor v, const ResourceAccessGraph& g) noexcept {
|
||||
const auto& outEdgeList = g.getOutEdgeList(u);
|
||||
auto iter = std::find(outEdgeList.begin(), outEdgeList.end(), ResourceAccessGraph::OutEdge(v));
|
||||
bool hasEdge = (iter != outEdgeList.end());
|
||||
return {ResourceAccessGraph::edge_descriptor(u, v), hasEdge};
|
||||
}
|
||||
|
||||
// BidirectionalGraph(Directed)
|
||||
inline std::pair<ResourceAccessGraph::in_edge_iterator, ResourceAccessGraph::in_edge_iterator>
|
||||
in_edges(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
return std::make_pair(
|
||||
ResourceAccessGraph::in_edge_iterator(const_cast<ResourceAccessGraph&>(g).getInEdgeList(u).begin(), u),
|
||||
ResourceAccessGraph::in_edge_iterator(const_cast<ResourceAccessGraph&>(g).getInEdgeList(u).end(), u));
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::degree_size_type
|
||||
in_degree(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<ResourceAccessGraph::degree_size_type>(g.getInEdgeList(u).size());
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::degree_size_type
|
||||
degree(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept {
|
||||
return in_degree(u, g) + out_degree(u, g);
|
||||
}
|
||||
|
||||
// AdjacencyGraph
|
||||
inline std::pair<ResourceAccessGraph::adjacency_iterator, ResourceAccessGraph::adjacency_iterator>
|
||||
adjacent_vertices(ResourceAccessGraph::vertex_descriptor u, const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
auto edges = out_edges(u, g);
|
||||
return std::make_pair(ResourceAccessGraph::adjacency_iterator(edges.first, &g), ResourceAccessGraph::adjacency_iterator(edges.second, &g));
|
||||
}
|
||||
|
||||
// VertexListGraph
|
||||
inline std::pair<ResourceAccessGraph::vertex_iterator, ResourceAccessGraph::vertex_iterator>
|
||||
vertices(const ResourceAccessGraph& g) noexcept {
|
||||
return std::make_pair(const_cast<ResourceAccessGraph&>(g).getVertexList().begin(), const_cast<ResourceAccessGraph&>(g).getVertexList().end());
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::vertices_size_type
|
||||
num_vertices(const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<ResourceAccessGraph::vertices_size_type>(g.getVertexList().size());
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
inline std::pair<ResourceAccessGraph::edge_iterator, ResourceAccessGraph::edge_iterator>
|
||||
edges(const ResourceAccessGraph& g0) noexcept {
|
||||
auto& g = const_cast<ResourceAccessGraph&>(g0);
|
||||
return std::make_pair(
|
||||
ResourceAccessGraph::edge_iterator(g.getVertexList().begin(), g.getVertexList().begin(), g.getVertexList().end(), g),
|
||||
ResourceAccessGraph::edge_iterator(g.getVertexList().begin(), g.getVertexList().end(), g.getVertexList().end(), g));
|
||||
}
|
||||
|
||||
inline ResourceAccessGraph::edges_size_type
|
||||
num_edges(const ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
ResourceAccessGraph::edges_size_type numEdges = 0;
|
||||
|
||||
auto range = vertices(g);
|
||||
for (auto iter = range.first; iter != range.second; ++iter) {
|
||||
numEdges += out_degree(*iter, g);
|
||||
}
|
||||
return numEdges;
|
||||
}
|
||||
|
||||
// MutableGraph(Edge)
|
||||
inline std::pair<ResourceAccessGraph::edge_descriptor, bool>
|
||||
add_edge( // NOLINT
|
||||
ResourceAccessGraph::vertex_descriptor u,
|
||||
ResourceAccessGraph::vertex_descriptor v, ResourceAccessGraph& g) {
|
||||
auto& outEdgeList = g.getOutEdgeList(u);
|
||||
outEdgeList.emplace_back(v);
|
||||
|
||||
auto& inEdgeList = g.getInEdgeList(v);
|
||||
inEdgeList.emplace_back(u);
|
||||
|
||||
return std::make_pair(ResourceAccessGraph::edge_descriptor(u, v), true);
|
||||
}
|
||||
|
||||
inline void remove_edge(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph::vertex_descriptor v, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
auto& s = g._vertices[u];
|
||||
auto& t = g._vertices[v];
|
||||
s.outEdges.erase(std::remove(s.outEdges.begin(), s.outEdges.end(), ResourceAccessGraph::OutEdge(v)), s.outEdges.end());
|
||||
t.inEdges.erase(std::remove(t.inEdges.begin(), t.inEdges.end(), ResourceAccessGraph::InEdge(u)), t.inEdges.end());
|
||||
}
|
||||
|
||||
inline void remove_edge(ResourceAccessGraph::out_edge_iterator outIter, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
auto e = *outIter;
|
||||
const auto u = source(e, g);
|
||||
const auto v = target(e, g);
|
||||
auto& s = g._vertices[u];
|
||||
auto& t = g._vertices[v];
|
||||
auto inIter = std::find(t.inEdges.begin(), t.inEdges.end(), ResourceAccessGraph::InEdge(u));
|
||||
CC_EXPECTS(inIter != t.inEdges.end());
|
||||
t.inEdges.erase(inIter);
|
||||
s.outEdges.erase(outIter.base());
|
||||
}
|
||||
|
||||
inline void remove_edge(ResourceAccessGraph::edge_descriptor e, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
const auto u = source(e, g);
|
||||
const auto v = target(e, g);
|
||||
auto& s = g._vertices[u];
|
||||
auto outIter = std::find(s.outEdges.begin(), s.outEdges.end(), ResourceAccessGraph::OutEdge(v));
|
||||
CC_EXPECTS(outIter != s.outEdges.end());
|
||||
remove_edge(ResourceAccessGraph::out_edge_iterator(outIter, u), g);
|
||||
}
|
||||
|
||||
// MutableGraph(Vertex)
|
||||
inline void clear_out_edges(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
// Bidirectional (OutEdges)
|
||||
auto& outEdgeList = g.getOutEdgeList(u);
|
||||
auto outEnd = outEdgeList.end();
|
||||
for (auto iter = outEdgeList.begin(); iter != outEnd; ++iter) {
|
||||
auto& inEdgeList = g.getInEdgeList((*iter).get_target());
|
||||
// eraseFromIncidenceList
|
||||
impl::sequenceEraseIf(inEdgeList, [u](const auto& e) {
|
||||
return e.get_target() == u;
|
||||
});
|
||||
}
|
||||
outEdgeList.clear();
|
||||
}
|
||||
|
||||
inline void clear_in_edges(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
// Bidirectional (InEdges)
|
||||
auto& inEdgeList = g.getInEdgeList(u);
|
||||
auto inEnd = inEdgeList.end();
|
||||
for (auto iter = inEdgeList.begin(); iter != inEnd; ++iter) {
|
||||
auto& outEdgeList = g.getOutEdgeList((*iter).get_target());
|
||||
// eraseFromIncidenceList
|
||||
impl::sequenceEraseIf(outEdgeList, [u](const auto& e) {
|
||||
return e.get_target() == u;
|
||||
});
|
||||
}
|
||||
inEdgeList.clear();
|
||||
}
|
||||
|
||||
inline void clear_vertex(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
clear_out_edges(u, g);
|
||||
clear_in_edges(u, g);
|
||||
}
|
||||
|
||||
inline void remove_vertex(ResourceAccessGraph::vertex_descriptor u, ResourceAccessGraph& g) noexcept { // NOLINT
|
||||
{ // UuidGraph
|
||||
const auto& key = g.passID[u];
|
||||
auto num = g.passIndex.erase(key);
|
||||
CC_ENSURES(num == 1);
|
||||
for (auto&& pair : g.passIndex) {
|
||||
auto& v = pair.second;
|
||||
if (v > u) {
|
||||
--v;
|
||||
}
|
||||
}
|
||||
}
|
||||
impl::removeVectorVertex(const_cast<ResourceAccessGraph&>(g), u, ResourceAccessGraph::directed_category{});
|
||||
|
||||
// remove components
|
||||
g.passID.erase(g.passID.begin() + static_cast<std::ptrdiff_t>(u));
|
||||
g.passResource.erase(g.passResource.begin() + static_cast<std::ptrdiff_t>(u));
|
||||
g.rpInfo.erase(g.rpInfo.begin() + static_cast<std::ptrdiff_t>(u));
|
||||
g.barrier.erase(g.barrier.begin() + static_cast<std::ptrdiff_t>(u));
|
||||
}
|
||||
|
||||
// MutablePropertyGraph(Vertex)
|
||||
template <class Component0, class Component1, class Component2, class Component3>
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
addVertex(Component0&& c0, Component1&& c1, Component2&& c2, Component3&& c3, ResourceAccessGraph& g) {
|
||||
auto v = gsl::narrow_cast<ResourceAccessGraph::vertex_descriptor>(g._vertices.size());
|
||||
|
||||
g._vertices.emplace_back();
|
||||
|
||||
{ // UuidGraph
|
||||
const auto& uuid = c0;
|
||||
auto res = g.passIndex.emplace(uuid, v);
|
||||
CC_ENSURES(res.second);
|
||||
}
|
||||
g.passID.emplace_back(std::forward<Component0>(c0));
|
||||
g.passResource.emplace_back(std::forward<Component1>(c1));
|
||||
g.rpInfo.emplace_back(std::forward<Component2>(c2));
|
||||
g.barrier.emplace_back(std::forward<Component3>(c3));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class Component0, class Component1, class Component2, class Component3>
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
addVertex(std::piecewise_construct_t /*tag*/, Component0&& c0, Component1&& c1, Component2&& c2, Component3&& c3, ResourceAccessGraph& g) {
|
||||
auto v = gsl::narrow_cast<ResourceAccessGraph::vertex_descriptor>(g._vertices.size());
|
||||
|
||||
g._vertices.emplace_back();
|
||||
|
||||
{ // UuidGraph
|
||||
std::apply(
|
||||
[&](const auto&... args) {
|
||||
auto res = g.passIndex.emplace(std::piecewise_construct, std::forward_as_tuple(args...), std::forward_as_tuple(v));
|
||||
CC_ENSURES(res.second);
|
||||
},
|
||||
c0);
|
||||
}
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... args) {
|
||||
g.passID.emplace_back(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::forward<Component0>(c0));
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... args) {
|
||||
g.passResource.emplace_back(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::forward<Component1>(c1));
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... args) {
|
||||
g.rpInfo.emplace_back(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::forward<Component2>(c2));
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... args) {
|
||||
g.barrier.emplace_back(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::forward<Component3>(c3));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
inline RelationGraph::vertex_descriptor
|
||||
source(const RelationGraph::edge_descriptor& e, const RelationGraph& /*g*/) noexcept {
|
||||
return e.source;
|
||||
}
|
||||
|
||||
inline RelationGraph::vertex_descriptor
|
||||
target(const RelationGraph::edge_descriptor& e, const RelationGraph& /*g*/) noexcept {
|
||||
return e.target;
|
||||
}
|
||||
|
||||
inline std::pair<RelationGraph::out_edge_iterator, RelationGraph::out_edge_iterator>
|
||||
out_edges(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept { // NOLINT
|
||||
return std::make_pair(
|
||||
RelationGraph::out_edge_iterator(const_cast<RelationGraph&>(g).getOutEdgeList(u).begin(), u),
|
||||
RelationGraph::out_edge_iterator(const_cast<RelationGraph&>(g).getOutEdgeList(u).end(), u));
|
||||
}
|
||||
|
||||
inline RelationGraph::degree_size_type
|
||||
out_degree(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<RelationGraph::degree_size_type>(g.getOutEdgeList(u).size());
|
||||
}
|
||||
|
||||
inline std::pair<RelationGraph::edge_descriptor, bool>
|
||||
edge(RelationGraph::vertex_descriptor u, RelationGraph::vertex_descriptor v, const RelationGraph& g) noexcept {
|
||||
const auto& outEdgeList = g.getOutEdgeList(u);
|
||||
auto iter = std::find(outEdgeList.begin(), outEdgeList.end(), RelationGraph::OutEdge(v));
|
||||
bool hasEdge = (iter != outEdgeList.end());
|
||||
return {RelationGraph::edge_descriptor(u, v), hasEdge};
|
||||
}
|
||||
|
||||
// BidirectionalGraph(Directed)
|
||||
inline std::pair<RelationGraph::in_edge_iterator, RelationGraph::in_edge_iterator>
|
||||
in_edges(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept { // NOLINT
|
||||
return std::make_pair(
|
||||
RelationGraph::in_edge_iterator(const_cast<RelationGraph&>(g).getInEdgeList(u).begin(), u),
|
||||
RelationGraph::in_edge_iterator(const_cast<RelationGraph&>(g).getInEdgeList(u).end(), u));
|
||||
}
|
||||
|
||||
inline RelationGraph::degree_size_type
|
||||
in_degree(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<RelationGraph::degree_size_type>(g.getInEdgeList(u).size());
|
||||
}
|
||||
|
||||
inline RelationGraph::degree_size_type
|
||||
degree(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept {
|
||||
return in_degree(u, g) + out_degree(u, g);
|
||||
}
|
||||
|
||||
// AdjacencyGraph
|
||||
inline std::pair<RelationGraph::adjacency_iterator, RelationGraph::adjacency_iterator>
|
||||
adjacent_vertices(RelationGraph::vertex_descriptor u, const RelationGraph& g) noexcept { // NOLINT
|
||||
auto edges = out_edges(u, g);
|
||||
return std::make_pair(RelationGraph::adjacency_iterator(edges.first, &g), RelationGraph::adjacency_iterator(edges.second, &g));
|
||||
}
|
||||
|
||||
// VertexListGraph
|
||||
inline std::pair<RelationGraph::vertex_iterator, RelationGraph::vertex_iterator>
|
||||
vertices(const RelationGraph& g) noexcept {
|
||||
return std::make_pair(const_cast<RelationGraph&>(g).getVertexList().begin(), const_cast<RelationGraph&>(g).getVertexList().end());
|
||||
}
|
||||
|
||||
inline RelationGraph::vertices_size_type
|
||||
num_vertices(const RelationGraph& g) noexcept { // NOLINT
|
||||
return gsl::narrow_cast<RelationGraph::vertices_size_type>(g.getVertexList().size());
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
inline std::pair<RelationGraph::edge_iterator, RelationGraph::edge_iterator>
|
||||
edges(const RelationGraph& g0) noexcept {
|
||||
auto& g = const_cast<RelationGraph&>(g0);
|
||||
return std::make_pair(
|
||||
RelationGraph::edge_iterator(g.getVertexList().begin(), g.getVertexList().begin(), g.getVertexList().end(), g),
|
||||
RelationGraph::edge_iterator(g.getVertexList().begin(), g.getVertexList().end(), g.getVertexList().end(), g));
|
||||
}
|
||||
|
||||
inline RelationGraph::edges_size_type
|
||||
num_edges(const RelationGraph& g) noexcept { // NOLINT
|
||||
RelationGraph::edges_size_type numEdges = 0;
|
||||
|
||||
auto range = vertices(g);
|
||||
for (auto iter = range.first; iter != range.second; ++iter) {
|
||||
numEdges += out_degree(*iter, g);
|
||||
}
|
||||
return numEdges;
|
||||
}
|
||||
|
||||
// MutableGraph(Edge)
|
||||
inline std::pair<RelationGraph::edge_descriptor, bool>
|
||||
add_edge( // NOLINT
|
||||
RelationGraph::vertex_descriptor u,
|
||||
RelationGraph::vertex_descriptor v, RelationGraph& g) {
|
||||
auto& outEdgeList = g.getOutEdgeList(u);
|
||||
outEdgeList.emplace_back(v);
|
||||
|
||||
auto& inEdgeList = g.getInEdgeList(v);
|
||||
inEdgeList.emplace_back(u);
|
||||
|
||||
return std::make_pair(RelationGraph::edge_descriptor(u, v), true);
|
||||
}
|
||||
|
||||
inline void remove_edge(RelationGraph::vertex_descriptor u, RelationGraph::vertex_descriptor v, RelationGraph& g) noexcept { // NOLINT
|
||||
auto& s = g._vertices[u];
|
||||
auto& t = g._vertices[v];
|
||||
s.outEdges.erase(std::remove(s.outEdges.begin(), s.outEdges.end(), RelationGraph::OutEdge(v)), s.outEdges.end());
|
||||
t.inEdges.erase(std::remove(t.inEdges.begin(), t.inEdges.end(), RelationGraph::InEdge(u)), t.inEdges.end());
|
||||
}
|
||||
|
||||
inline void remove_edge(RelationGraph::out_edge_iterator outIter, RelationGraph& g) noexcept { // NOLINT
|
||||
auto e = *outIter;
|
||||
const auto u = source(e, g);
|
||||
const auto v = target(e, g);
|
||||
auto& s = g._vertices[u];
|
||||
auto& t = g._vertices[v];
|
||||
auto inIter = std::find(t.inEdges.begin(), t.inEdges.end(), RelationGraph::InEdge(u));
|
||||
CC_EXPECTS(inIter != t.inEdges.end());
|
||||
t.inEdges.erase(inIter);
|
||||
s.outEdges.erase(outIter.base());
|
||||
}
|
||||
|
||||
inline void remove_edge(RelationGraph::edge_descriptor e, RelationGraph& g) noexcept { // NOLINT
|
||||
const auto u = source(e, g);
|
||||
const auto v = target(e, g);
|
||||
auto& s = g._vertices[u];
|
||||
auto outIter = std::find(s.outEdges.begin(), s.outEdges.end(), RelationGraph::OutEdge(v));
|
||||
CC_EXPECTS(outIter != s.outEdges.end());
|
||||
remove_edge(RelationGraph::out_edge_iterator(outIter, u), g);
|
||||
}
|
||||
|
||||
// MutableGraph(Vertex)
|
||||
inline void clear_out_edges(RelationGraph::vertex_descriptor u, RelationGraph& g) noexcept { // NOLINT
|
||||
// Bidirectional (OutEdges)
|
||||
auto& outEdgeList = g.getOutEdgeList(u);
|
||||
auto outEnd = outEdgeList.end();
|
||||
for (auto iter = outEdgeList.begin(); iter != outEnd; ++iter) {
|
||||
auto& inEdgeList = g.getInEdgeList((*iter).get_target());
|
||||
// eraseFromIncidenceList
|
||||
impl::sequenceEraseIf(inEdgeList, [u](const auto& e) {
|
||||
return e.get_target() == u;
|
||||
});
|
||||
}
|
||||
outEdgeList.clear();
|
||||
}
|
||||
|
||||
inline void clear_in_edges(RelationGraph::vertex_descriptor u, RelationGraph& g) noexcept { // NOLINT
|
||||
// Bidirectional (InEdges)
|
||||
auto& inEdgeList = g.getInEdgeList(u);
|
||||
auto inEnd = inEdgeList.end();
|
||||
for (auto iter = inEdgeList.begin(); iter != inEnd; ++iter) {
|
||||
auto& outEdgeList = g.getOutEdgeList((*iter).get_target());
|
||||
// eraseFromIncidenceList
|
||||
impl::sequenceEraseIf(outEdgeList, [u](const auto& e) {
|
||||
return e.get_target() == u;
|
||||
});
|
||||
}
|
||||
inEdgeList.clear();
|
||||
}
|
||||
|
||||
inline void clear_vertex(RelationGraph::vertex_descriptor u, RelationGraph& g) noexcept { // NOLINT
|
||||
clear_out_edges(u, g);
|
||||
clear_in_edges(u, g);
|
||||
}
|
||||
|
||||
inline void remove_vertex(RelationGraph::vertex_descriptor u, RelationGraph& g) noexcept { // NOLINT
|
||||
{ // UuidGraph
|
||||
const auto& key = g.descID[u];
|
||||
auto num = g.vertexMap.erase(key);
|
||||
CC_ENSURES(num == 1);
|
||||
for (auto&& pair : g.vertexMap) {
|
||||
auto& v = pair.second;
|
||||
if (v > u) {
|
||||
--v;
|
||||
}
|
||||
}
|
||||
}
|
||||
impl::removeVectorVertex(const_cast<RelationGraph&>(g), u, RelationGraph::directed_category{});
|
||||
|
||||
// remove components
|
||||
g.descID.erase(g.descID.begin() + static_cast<std::ptrdiff_t>(u));
|
||||
}
|
||||
|
||||
// MutablePropertyGraph(Vertex)
|
||||
template <class Component0>
|
||||
inline RelationGraph::vertex_descriptor
|
||||
addVertex(Component0&& c0, RelationGraph& g) {
|
||||
auto v = gsl::narrow_cast<RelationGraph::vertex_descriptor>(g._vertices.size());
|
||||
|
||||
g._vertices.emplace_back();
|
||||
|
||||
{ // UuidGraph
|
||||
const auto& uuid = c0;
|
||||
auto res = g.vertexMap.emplace(uuid, v);
|
||||
CC_ENSURES(res.second);
|
||||
}
|
||||
g.descID.emplace_back(std::forward<Component0>(c0));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class Component0>
|
||||
inline RelationGraph::vertex_descriptor
|
||||
addVertex(std::piecewise_construct_t /*tag*/, Component0&& c0, RelationGraph& g) {
|
||||
auto v = gsl::narrow_cast<RelationGraph::vertex_descriptor>(g._vertices.size());
|
||||
|
||||
g._vertices.emplace_back();
|
||||
|
||||
{ // UuidGraph
|
||||
std::apply(
|
||||
[&](const auto&... args) {
|
||||
auto res = g.vertexMap.emplace(std::piecewise_construct, std::forward_as_tuple(args...), std::forward_as_tuple(v));
|
||||
CC_ENSURES(res.second);
|
||||
},
|
||||
c0);
|
||||
}
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... args) {
|
||||
g.descID.emplace_back(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::forward<Component0>(c0));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Vertex Index
|
||||
template <>
|
||||
struct property_map<cc::render::ResourceAccessGraph, vertex_index_t> {
|
||||
using const_type = identity_property_map;
|
||||
using type = identity_property_map;
|
||||
};
|
||||
|
||||
// Vertex Component
|
||||
template <>
|
||||
struct property_map<cc::render::ResourceAccessGraph, cc::render::ResourceAccessGraph::PassIDTag> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::RenderGraph::vertex_descriptor>,
|
||||
cc::render::RenderGraph::vertex_descriptor,
|
||||
const cc::render::RenderGraph::vertex_descriptor&>;
|
||||
using type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::RenderGraph::vertex_descriptor>,
|
||||
cc::render::RenderGraph::vertex_descriptor,
|
||||
cc::render::RenderGraph::vertex_descriptor&>;
|
||||
};
|
||||
|
||||
// Vertex Component
|
||||
template <>
|
||||
struct property_map<cc::render::ResourceAccessGraph, cc::render::ResourceAccessGraph::PassNodeTag> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::ResourceAccessNode>,
|
||||
cc::render::ResourceAccessNode,
|
||||
const cc::render::ResourceAccessNode&>;
|
||||
using type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::ResourceAccessNode>,
|
||||
cc::render::ResourceAccessNode,
|
||||
cc::render::ResourceAccessNode&>;
|
||||
};
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
struct property_map<cc::render::ResourceAccessGraph, T cc::render::ResourceAccessNode::*> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::ResourceAccessNode>,
|
||||
T,
|
||||
const T&,
|
||||
T cc::render::ResourceAccessNode::*>;
|
||||
using type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::ResourceAccessNode>,
|
||||
T,
|
||||
T&,
|
||||
T cc::render::ResourceAccessNode::*>;
|
||||
};
|
||||
|
||||
// Vertex Component
|
||||
template <>
|
||||
struct property_map<cc::render::ResourceAccessGraph, cc::render::ResourceAccessGraph::RenderPassInfoTag> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::FGRenderPassInfo>,
|
||||
cc::render::FGRenderPassInfo,
|
||||
const cc::render::FGRenderPassInfo&>;
|
||||
using type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::FGRenderPassInfo>,
|
||||
cc::render::FGRenderPassInfo,
|
||||
cc::render::FGRenderPassInfo&>;
|
||||
};
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
struct property_map<cc::render::ResourceAccessGraph, T cc::render::FGRenderPassInfo::*> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::FGRenderPassInfo>,
|
||||
T,
|
||||
const T&,
|
||||
T cc::render::FGRenderPassInfo::*>;
|
||||
using type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::FGRenderPassInfo>,
|
||||
T,
|
||||
T&,
|
||||
T cc::render::FGRenderPassInfo::*>;
|
||||
};
|
||||
|
||||
// Vertex Component
|
||||
template <>
|
||||
struct property_map<cc::render::ResourceAccessGraph, cc::render::ResourceAccessGraph::BarrierTag> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::BarrierNode>,
|
||||
cc::render::BarrierNode,
|
||||
const cc::render::BarrierNode&>;
|
||||
using type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::BarrierNode>,
|
||||
cc::render::BarrierNode,
|
||||
cc::render::BarrierNode&>;
|
||||
};
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
struct property_map<cc::render::ResourceAccessGraph, T cc::render::BarrierNode::*> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::ResourceAccessGraph,
|
||||
const ccstd::pmr::vector<cc::render::BarrierNode>,
|
||||
T,
|
||||
const T&,
|
||||
T cc::render::BarrierNode::*>;
|
||||
using type = cc::render::impl::VectorVertexComponentMemberPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::ResourceAccessGraph,
|
||||
ccstd::pmr::vector<cc::render::BarrierNode>,
|
||||
T,
|
||||
T&,
|
||||
T cc::render::BarrierNode::*>;
|
||||
};
|
||||
|
||||
// Vertex Index
|
||||
template <>
|
||||
struct property_map<cc::render::RelationGraph, vertex_index_t> {
|
||||
using const_type = identity_property_map;
|
||||
using type = identity_property_map;
|
||||
};
|
||||
|
||||
// Vertex Component
|
||||
template <>
|
||||
struct property_map<cc::render::RelationGraph, cc::render::RelationGraph::DescIDTag> {
|
||||
using const_type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
const cc::render::RelationGraph,
|
||||
const ccstd::pmr::vector<cc::render::ResourceAccessGraph::vertex_descriptor>,
|
||||
cc::render::ResourceAccessGraph::vertex_descriptor,
|
||||
const cc::render::ResourceAccessGraph::vertex_descriptor&>;
|
||||
using type = cc::render::impl::VectorVertexComponentPropertyMap<
|
||||
lvalue_property_map_tag,
|
||||
cc::render::RelationGraph,
|
||||
ccstd::pmr::vector<cc::render::ResourceAccessGraph::vertex_descriptor>,
|
||||
cc::render::ResourceAccessGraph::vertex_descriptor,
|
||||
cc::render::ResourceAccessGraph::vertex_descriptor&>;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
// Vertex Index
|
||||
inline boost::property_map<ResourceAccessGraph, boost::vertex_index_t>::const_type
|
||||
get(boost::vertex_index_t /*tag*/, const ResourceAccessGraph& /*g*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline boost::property_map<ResourceAccessGraph, boost::vertex_index_t>::type
|
||||
get(boost::vertex_index_t /*tag*/, ResourceAccessGraph& /*g*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline impl::ColorMap<ResourceAccessGraph::vertex_descriptor>
|
||||
get(ccstd::pmr::vector<boost::default_color_type>& colors, const ResourceAccessGraph& /*g*/) noexcept {
|
||||
return {colors};
|
||||
}
|
||||
|
||||
// Vertex Component
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::PassIDTag>::const_type
|
||||
get(ResourceAccessGraph::PassIDTag /*tag*/, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.passID};
|
||||
}
|
||||
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::PassIDTag>::type
|
||||
get(ResourceAccessGraph::PassIDTag /*tag*/, ResourceAccessGraph& g) noexcept {
|
||||
return {g.passID};
|
||||
}
|
||||
|
||||
// Vertex Component
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::PassNodeTag>::const_type
|
||||
get(ResourceAccessGraph::PassNodeTag /*tag*/, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.passResource};
|
||||
}
|
||||
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::PassNodeTag>::type
|
||||
get(ResourceAccessGraph::PassNodeTag /*tag*/, ResourceAccessGraph& g) noexcept {
|
||||
return {g.passResource};
|
||||
}
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T ResourceAccessNode::*>::const_type
|
||||
get(T ResourceAccessNode::*memberPointer, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.passResource, memberPointer};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T ResourceAccessNode::*>::type
|
||||
get(T ResourceAccessNode::*memberPointer, ResourceAccessGraph& g) noexcept {
|
||||
return {g.passResource, memberPointer};
|
||||
}
|
||||
|
||||
// Vertex Component
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::RenderPassInfoTag>::const_type
|
||||
get(ResourceAccessGraph::RenderPassInfoTag /*tag*/, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.rpInfo};
|
||||
}
|
||||
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::RenderPassInfoTag>::type
|
||||
get(ResourceAccessGraph::RenderPassInfoTag /*tag*/, ResourceAccessGraph& g) noexcept {
|
||||
return {g.rpInfo};
|
||||
}
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T FGRenderPassInfo::*>::const_type
|
||||
get(T FGRenderPassInfo::*memberPointer, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.rpInfo, memberPointer};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T FGRenderPassInfo::*>::type
|
||||
get(T FGRenderPassInfo::*memberPointer, ResourceAccessGraph& g) noexcept {
|
||||
return {g.rpInfo, memberPointer};
|
||||
}
|
||||
|
||||
// Vertex Component
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::BarrierTag>::const_type
|
||||
get(ResourceAccessGraph::BarrierTag /*tag*/, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.barrier};
|
||||
}
|
||||
|
||||
inline typename boost::property_map<ResourceAccessGraph, ResourceAccessGraph::BarrierTag>::type
|
||||
get(ResourceAccessGraph::BarrierTag /*tag*/, ResourceAccessGraph& g) noexcept {
|
||||
return {g.barrier};
|
||||
}
|
||||
|
||||
// Vertex ComponentMember
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T BarrierNode::*>::const_type
|
||||
get(T BarrierNode::*memberPointer, const ResourceAccessGraph& g) noexcept {
|
||||
return {g.barrier, memberPointer};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename boost::property_map<ResourceAccessGraph, T BarrierNode::*>::type
|
||||
get(T BarrierNode::*memberPointer, ResourceAccessGraph& g) noexcept {
|
||||
return {g.barrier, memberPointer};
|
||||
}
|
||||
|
||||
// Vertex Constant Getter
|
||||
template <class Tag>
|
||||
inline decltype(auto)
|
||||
get(Tag tag, const ResourceAccessGraph& g, ResourceAccessGraph::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
// Vertex Mutable Getter
|
||||
template <class Tag>
|
||||
inline decltype(auto)
|
||||
get(Tag tag, ResourceAccessGraph& g, ResourceAccessGraph::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
// Vertex Setter
|
||||
template <class Tag, class... Args>
|
||||
inline void put(
|
||||
Tag tag, ResourceAccessGraph& g,
|
||||
ResourceAccessGraph::vertex_descriptor v,
|
||||
Args&&... args) {
|
||||
put(get(tag, g), v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// UuidGraph
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
vertex(const RenderGraph::vertex_descriptor& key, const ResourceAccessGraph& g) {
|
||||
return g.passIndex.at(key);
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
vertex(const KeyLike& key, const ResourceAccessGraph& g) {
|
||||
const auto& index = g.passIndex;
|
||||
auto iter = index.find(key);
|
||||
if (iter == index.end()) {
|
||||
throw std::out_of_range("at(key, ResourceAccessGraph) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
findVertex(const KeyLike& key, const ResourceAccessGraph& g) noexcept {
|
||||
const auto& index = g.passIndex;
|
||||
auto iter = index.find(key);
|
||||
if (iter == index.end()) {
|
||||
return ResourceAccessGraph::null_vertex();
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
inline bool
|
||||
contains(const RenderGraph::vertex_descriptor& key, const ResourceAccessGraph& g) noexcept {
|
||||
auto iter = g.passIndex.find(key);
|
||||
return iter != g.passIndex.end();
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline bool
|
||||
contains(const KeyLike& key, const ResourceAccessGraph& g) noexcept {
|
||||
auto iter = g.passIndex.find(key);
|
||||
return iter != g.passIndex.end();
|
||||
}
|
||||
|
||||
// MutableGraph(Vertex)
|
||||
inline ResourceAccessGraph::vertex_descriptor
|
||||
add_vertex(ResourceAccessGraph& g, const RenderGraph::vertex_descriptor& key) { // NOLINT
|
||||
return addVertex(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(key), // passID
|
||||
std::forward_as_tuple(), // passResource
|
||||
std::forward_as_tuple(), // rpInfo
|
||||
std::forward_as_tuple(), // barrier
|
||||
g);
|
||||
}
|
||||
|
||||
// Vertex Index
|
||||
inline boost::property_map<RelationGraph, boost::vertex_index_t>::const_type
|
||||
get(boost::vertex_index_t /*tag*/, const RelationGraph& /*g*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline boost::property_map<RelationGraph, boost::vertex_index_t>::type
|
||||
get(boost::vertex_index_t /*tag*/, RelationGraph& /*g*/) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline impl::ColorMap<RelationGraph::vertex_descriptor>
|
||||
get(ccstd::pmr::vector<boost::default_color_type>& colors, const RelationGraph& /*g*/) noexcept {
|
||||
return {colors};
|
||||
}
|
||||
|
||||
// Vertex Component
|
||||
inline typename boost::property_map<RelationGraph, RelationGraph::DescIDTag>::const_type
|
||||
get(RelationGraph::DescIDTag /*tag*/, const RelationGraph& g) noexcept {
|
||||
return {g.descID};
|
||||
}
|
||||
|
||||
inline typename boost::property_map<RelationGraph, RelationGraph::DescIDTag>::type
|
||||
get(RelationGraph::DescIDTag /*tag*/, RelationGraph& g) noexcept {
|
||||
return {g.descID};
|
||||
}
|
||||
|
||||
// Vertex Constant Getter
|
||||
template <class Tag>
|
||||
inline decltype(auto)
|
||||
get(Tag tag, const RelationGraph& g, RelationGraph::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
// Vertex Mutable Getter
|
||||
template <class Tag>
|
||||
inline decltype(auto)
|
||||
get(Tag tag, RelationGraph& g, RelationGraph::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
// Vertex Setter
|
||||
template <class Tag, class... Args>
|
||||
inline void put(
|
||||
Tag tag, RelationGraph& g,
|
||||
RelationGraph::vertex_descriptor v,
|
||||
Args&&... args) {
|
||||
put(get(tag, g), v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// UuidGraph
|
||||
inline RelationGraph::vertex_descriptor
|
||||
vertex(const ResourceAccessGraph::vertex_descriptor& key, const RelationGraph& g) {
|
||||
return g.vertexMap.at(key);
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline RelationGraph::vertex_descriptor
|
||||
vertex(const KeyLike& key, const RelationGraph& g) {
|
||||
const auto& index = g.vertexMap;
|
||||
auto iter = index.find(key);
|
||||
if (iter == index.end()) {
|
||||
throw std::out_of_range("at(key, RelationGraph) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline RelationGraph::vertex_descriptor
|
||||
findVertex(const KeyLike& key, const RelationGraph& g) noexcept {
|
||||
const auto& index = g.vertexMap;
|
||||
auto iter = index.find(key);
|
||||
if (iter == index.end()) {
|
||||
return RelationGraph::null_vertex();
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
inline bool
|
||||
contains(const ResourceAccessGraph::vertex_descriptor& key, const RelationGraph& g) noexcept {
|
||||
auto iter = g.vertexMap.find(key);
|
||||
return iter != g.vertexMap.end();
|
||||
}
|
||||
|
||||
template <class KeyLike>
|
||||
inline bool
|
||||
contains(const KeyLike& key, const RelationGraph& g) noexcept {
|
||||
auto iter = g.vertexMap.find(key);
|
||||
return iter != g.vertexMap.end();
|
||||
}
|
||||
|
||||
// MutableGraph(Vertex)
|
||||
inline RelationGraph::vertex_descriptor
|
||||
add_vertex(RelationGraph& g, const ResourceAccessGraph::vertex_descriptor& key) { // NOLINT
|
||||
return addVertex(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(key), // descID
|
||||
g);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
174
cocos/renderer/pipeline/custom/FGDispatcherTypes.cpp
Normal file
174
cocos/renderer/pipeline/custom/FGDispatcherTypes.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "FGDispatcherTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
ResourceAccessNode::ResourceAccessNode(const allocator_type& alloc) noexcept
|
||||
: resourceStatus(alloc) {}
|
||||
|
||||
ResourceAccessNode::ResourceAccessNode(ResourceAccessNode&& rhs, const allocator_type& alloc)
|
||||
: resourceStatus(std::move(rhs.resourceStatus), alloc) {}
|
||||
|
||||
ResourceAccessNode::ResourceAccessNode(ResourceAccessNode const& rhs, const allocator_type& alloc)
|
||||
: resourceStatus(rhs.resourceStatus, alloc) {}
|
||||
|
||||
AttachmentInfo::AttachmentInfo(const allocator_type& alloc) noexcept
|
||||
: parentName(alloc) {}
|
||||
|
||||
AttachmentInfo::AttachmentInfo(AttachmentInfo&& rhs, const allocator_type& alloc)
|
||||
: parentName(std::move(rhs.parentName), alloc),
|
||||
attachmentIndex(rhs.attachmentIndex),
|
||||
isResolveView(rhs.isResolveView) {}
|
||||
|
||||
AttachmentInfo::AttachmentInfo(AttachmentInfo const& rhs, const allocator_type& alloc)
|
||||
: parentName(rhs.parentName, alloc),
|
||||
attachmentIndex(rhs.attachmentIndex),
|
||||
isResolveView(rhs.isResolveView) {}
|
||||
|
||||
FGRenderPassInfo::FGRenderPassInfo(const allocator_type& alloc) noexcept
|
||||
: orderedViews(alloc),
|
||||
viewIndex(alloc) {}
|
||||
|
||||
FGRenderPassInfo::FGRenderPassInfo(FGRenderPassInfo&& rhs, const allocator_type& alloc)
|
||||
: colorAccesses(std::move(rhs.colorAccesses)),
|
||||
dsAccess(rhs.dsAccess),
|
||||
dsResolveAccess(rhs.dsResolveAccess),
|
||||
rpInfo(std::move(rhs.rpInfo)),
|
||||
orderedViews(std::move(rhs.orderedViews), alloc),
|
||||
viewIndex(std::move(rhs.viewIndex), alloc),
|
||||
resolveCount(rhs.resolveCount),
|
||||
uniqueRasterViewCount(rhs.uniqueRasterViewCount) {}
|
||||
|
||||
FGRenderPassInfo::FGRenderPassInfo(FGRenderPassInfo const& rhs, const allocator_type& alloc)
|
||||
: colorAccesses(rhs.colorAccesses),
|
||||
dsAccess(rhs.dsAccess),
|
||||
dsResolveAccess(rhs.dsResolveAccess),
|
||||
rpInfo(rhs.rpInfo),
|
||||
orderedViews(rhs.orderedViews, alloc),
|
||||
viewIndex(rhs.viewIndex, alloc),
|
||||
resolveCount(rhs.resolveCount),
|
||||
uniqueRasterViewCount(rhs.uniqueRasterViewCount) {}
|
||||
|
||||
ResourceAccessGraph::ResourceAccessGraph(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
passID(alloc),
|
||||
passResource(alloc),
|
||||
rpInfo(alloc),
|
||||
barrier(alloc),
|
||||
passIndex(alloc),
|
||||
resourceNames(alloc),
|
||||
resourceIndex(alloc),
|
||||
leafPasses(alloc),
|
||||
culledPasses(alloc),
|
||||
resourceLifeRecord(alloc),
|
||||
topologicalOrder(alloc),
|
||||
resourceAccess(alloc),
|
||||
movedTarget(alloc),
|
||||
movedSourceStatus(alloc),
|
||||
movedTargetStatus(alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void ResourceAccessGraph::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
passID.reserve(sz);
|
||||
passResource.reserve(sz);
|
||||
rpInfo.reserve(sz);
|
||||
barrier.reserve(sz);
|
||||
}
|
||||
|
||||
ResourceAccessGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
ResourceAccessGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc) {}
|
||||
|
||||
ResourceAccessGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc) {}
|
||||
|
||||
RelationGraph::RelationGraph(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
descID(alloc),
|
||||
vertexMap(alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void RelationGraph::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
descID.reserve(sz);
|
||||
}
|
||||
|
||||
RelationGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
RelationGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc) {}
|
||||
|
||||
RelationGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc) {}
|
||||
|
||||
RenderingInfo::RenderingInfo(const allocator_type& alloc) noexcept
|
||||
: clearColors(alloc) {}
|
||||
|
||||
RenderingInfo::RenderingInfo(RenderingInfo&& rhs, const allocator_type& alloc)
|
||||
: renderpassInfo(std::move(rhs.renderpassInfo)),
|
||||
framebufferInfo(std::move(rhs.framebufferInfo)),
|
||||
clearColors(std::move(rhs.clearColors), alloc),
|
||||
clearDepth(rhs.clearDepth),
|
||||
clearStencil(rhs.clearStencil) {}
|
||||
|
||||
RenderingInfo::RenderingInfo(RenderingInfo const& rhs, const allocator_type& alloc)
|
||||
: renderpassInfo(rhs.renderpassInfo),
|
||||
framebufferInfo(rhs.framebufferInfo),
|
||||
clearColors(rhs.clearColors, alloc),
|
||||
clearDepth(rhs.clearDepth),
|
||||
clearStencil(rhs.clearStencil) {}
|
||||
|
||||
FrameGraphDispatcher::FrameGraphDispatcher(ResourceGraph& resourceGraphIn, const RenderGraph& renderGraphIn, const LayoutGraphData& layoutGraphIn, boost::container::pmr::memory_resource* scratchIn, const allocator_type& alloc) noexcept
|
||||
: resourceAccessGraph(alloc),
|
||||
resourceGraph(resourceGraphIn),
|
||||
renderGraph(renderGraphIn),
|
||||
layoutGraph(layoutGraphIn),
|
||||
scratch(scratchIn),
|
||||
relationGraph(alloc) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
506
cocos/renderer/pipeline/custom/FGDispatcherTypes.h
Normal file
506
cocos/renderer/pipeline/custom/FGDispatcherTypes.h
Normal file
@@ -0,0 +1,506 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/range/irange.hpp>
|
||||
#include <variant>
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/container/vector.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Map.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Set.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct NullTag {
|
||||
};
|
||||
|
||||
struct ResourceLifeRecord {
|
||||
uint32_t start{0};
|
||||
uint32_t end{0};
|
||||
};
|
||||
|
||||
struct LeafStatus {
|
||||
bool isExternal{false};
|
||||
bool needCulling{false};
|
||||
};
|
||||
|
||||
struct AccessStatus {
|
||||
gfx::AccessFlagBit accessFlag{gfx::AccessFlagBit::NONE};
|
||||
gfx::ResourceRange range;
|
||||
};
|
||||
|
||||
struct ResourceAccessNode {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {resourceStatus.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ResourceAccessNode(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ResourceAccessNode(ResourceAccessNode&& rhs, const allocator_type& alloc);
|
||||
ResourceAccessNode(ResourceAccessNode const& rhs, const allocator_type& alloc);
|
||||
|
||||
ResourceAccessNode(ResourceAccessNode&& rhs) noexcept = default;
|
||||
ResourceAccessNode(ResourceAccessNode const& rhs) = delete;
|
||||
ResourceAccessNode& operator=(ResourceAccessNode&& rhs) = default;
|
||||
ResourceAccessNode& operator=(ResourceAccessNode const& rhs) = default;
|
||||
|
||||
PmrFlatMap<ccstd::pmr::string, AccessStatus> resourceStatus;
|
||||
};
|
||||
|
||||
struct LayoutAccess {
|
||||
gfx::AccessFlagBit prevAccess{gfx::AccessFlagBit::NONE};
|
||||
gfx::AccessFlagBit nextAccess{gfx::AccessFlagBit::NONE};
|
||||
};
|
||||
|
||||
struct AttachmentInfo {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {parentName.get_allocator().resource()};
|
||||
}
|
||||
|
||||
AttachmentInfo(const allocator_type& alloc) noexcept; // NOLINT
|
||||
AttachmentInfo(AttachmentInfo&& rhs, const allocator_type& alloc);
|
||||
AttachmentInfo(AttachmentInfo const& rhs, const allocator_type& alloc);
|
||||
|
||||
AttachmentInfo(AttachmentInfo&& rhs) noexcept = default;
|
||||
AttachmentInfo(AttachmentInfo const& rhs) = delete;
|
||||
AttachmentInfo& operator=(AttachmentInfo&& rhs) = default;
|
||||
AttachmentInfo& operator=(AttachmentInfo const& rhs) = default;
|
||||
|
||||
ccstd::pmr::string parentName;
|
||||
uint32_t attachmentIndex{0};
|
||||
uint32_t isResolveView{0};
|
||||
};
|
||||
|
||||
struct FGRenderPassInfo {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {orderedViews.get_allocator().resource()};
|
||||
}
|
||||
|
||||
FGRenderPassInfo(const allocator_type& alloc) noexcept; // NOLINT
|
||||
FGRenderPassInfo(FGRenderPassInfo&& rhs, const allocator_type& alloc);
|
||||
FGRenderPassInfo(FGRenderPassInfo const& rhs, const allocator_type& alloc);
|
||||
|
||||
FGRenderPassInfo(FGRenderPassInfo&& rhs) noexcept = default;
|
||||
FGRenderPassInfo(FGRenderPassInfo const& rhs) = delete;
|
||||
FGRenderPassInfo& operator=(FGRenderPassInfo&& rhs) = default;
|
||||
FGRenderPassInfo& operator=(FGRenderPassInfo const& rhs) = default;
|
||||
|
||||
ccstd::vector<LayoutAccess> colorAccesses;
|
||||
LayoutAccess dsAccess;
|
||||
LayoutAccess dsResolveAccess;
|
||||
gfx::RenderPassInfo rpInfo;
|
||||
ccstd::pmr::vector<ccstd::pmr::string> orderedViews;
|
||||
PmrTransparentMap<ccstd::pmr::string, AttachmentInfo> viewIndex;
|
||||
uint32_t resolveCount{0};
|
||||
uint32_t uniqueRasterViewCount{0};
|
||||
};
|
||||
|
||||
struct Barrier {
|
||||
ResourceGraph::vertex_descriptor resourceID{0xFFFFFFFF};
|
||||
gfx::BarrierType type{gfx::BarrierType::FULL};
|
||||
gfx::GFXObject* barrier{nullptr};
|
||||
RenderGraph::vertex_descriptor beginVert{0xFFFFFFFF};
|
||||
RenderGraph::vertex_descriptor endVert{0xFFFFFFFF};
|
||||
AccessStatus beginStatus;
|
||||
AccessStatus endStatus;
|
||||
};
|
||||
|
||||
struct BarrierNode {
|
||||
ccstd::vector<Barrier> frontBarriers;
|
||||
ccstd::vector<Barrier> rearBarriers;
|
||||
};
|
||||
|
||||
struct SliceNode {
|
||||
bool full{false};
|
||||
ccstd::vector<uint32_t> mips;
|
||||
};
|
||||
|
||||
struct TextureNode {
|
||||
bool full{false};
|
||||
ccstd::vector<SliceNode> slices;
|
||||
};
|
||||
|
||||
struct ResourceNode {
|
||||
bool full{false};
|
||||
ccstd::vector<TextureNode> planes;
|
||||
};
|
||||
|
||||
struct ResourceAccessGraph {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {_vertices.get_allocator().resource()};
|
||||
}
|
||||
|
||||
inline boost::container::pmr::memory_resource* resource() const noexcept {
|
||||
return get_allocator().resource();
|
||||
}
|
||||
|
||||
ResourceAccessGraph(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ResourceAccessGraph(ResourceAccessGraph&& rhs) = delete;
|
||||
ResourceAccessGraph(ResourceAccessGraph const& rhs) = delete;
|
||||
ResourceAccessGraph& operator=(ResourceAccessGraph&& rhs) = delete;
|
||||
ResourceAccessGraph& operator=(ResourceAccessGraph const& rhs) = delete;
|
||||
|
||||
// Graph
|
||||
using directed_category = boost::bidirectional_tag;
|
||||
using vertex_descriptor = uint32_t;
|
||||
using edge_descriptor = impl::EdgeDescriptor<directed_category, vertex_descriptor>;
|
||||
using edge_parallel_category = boost::allow_parallel_edge_tag;
|
||||
struct traversal_category // NOLINT
|
||||
: virtual boost::incidence_graph_tag,
|
||||
virtual boost::bidirectional_graph_tag,
|
||||
virtual boost::adjacency_graph_tag,
|
||||
virtual boost::vertex_list_graph_tag,
|
||||
virtual boost::edge_list_graph_tag {};
|
||||
|
||||
constexpr static vertex_descriptor null_vertex() noexcept { // NOLINT
|
||||
return std::numeric_limits<vertex_descriptor>::max();
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
using OutEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using out_edge_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
using degree_size_type = uint32_t;
|
||||
|
||||
// BidirectionalGraph
|
||||
using InEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using in_edge_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
|
||||
// AdjacencyGraph
|
||||
using adjacency_iterator = boost::adjacency_iterator_generator<
|
||||
ResourceAccessGraph, vertex_descriptor, out_edge_iterator>::type;
|
||||
|
||||
// VertexListGraph
|
||||
using vertex_iterator = boost::integer_range<vertex_descriptor>::iterator;
|
||||
using vertices_size_type = uint32_t;
|
||||
|
||||
// VertexList help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
inline boost::integer_range<vertex_descriptor> getVertexList() const noexcept {
|
||||
return {0, static_cast<vertices_size_type>(_vertices.size())};
|
||||
}
|
||||
|
||||
inline vertex_descriptor getCurrentID() const noexcept {
|
||||
return static_cast<vertex_descriptor>(_vertices.size());
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<boost::default_color_type> colors(boost::container::pmr::memory_resource* mr) const {
|
||||
return ccstd::pmr::vector<boost::default_color_type>(_vertices.size(), mr);
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
using edge_iterator = impl::DirectedEdgeIterator<vertex_iterator, out_edge_iterator, ResourceAccessGraph>;
|
||||
using edges_size_type = uint32_t;
|
||||
|
||||
LayoutAccess getAccess(ccstd::pmr::string, RenderGraph::vertex_descriptor vertID);
|
||||
|
||||
|
||||
// ContinuousContainer
|
||||
void reserve(vertices_size_type sz);
|
||||
|
||||
// Members
|
||||
struct Vertex {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {outEdges.get_allocator().resource()};
|
||||
}
|
||||
|
||||
Vertex(const allocator_type& alloc) noexcept; // NOLINT
|
||||
Vertex(Vertex&& rhs, const allocator_type& alloc);
|
||||
Vertex(Vertex const& rhs, const allocator_type& alloc);
|
||||
|
||||
Vertex(Vertex&& rhs) noexcept = default;
|
||||
Vertex(Vertex const& rhs) = delete;
|
||||
Vertex& operator=(Vertex&& rhs) = default;
|
||||
Vertex& operator=(Vertex const& rhs) = default;
|
||||
|
||||
ccstd::pmr::vector<OutEdge> outEdges;
|
||||
ccstd::pmr::vector<InEdge> inEdges;
|
||||
};
|
||||
|
||||
struct PassIDTag {};
|
||||
struct PassNodeTag {};
|
||||
struct RenderPassInfoTag {};
|
||||
struct BarrierTag {};
|
||||
|
||||
// Vertices
|
||||
ccstd::pmr::vector<Vertex> _vertices;
|
||||
// Components
|
||||
ccstd::pmr::vector<RenderGraph::vertex_descriptor> passID;
|
||||
ccstd::pmr::vector<ResourceAccessNode> passResource;
|
||||
ccstd::pmr::vector<FGRenderPassInfo> rpInfo;
|
||||
ccstd::pmr::vector<BarrierNode> barrier;
|
||||
// UuidGraph
|
||||
PmrUnorderedMap<RenderGraph::vertex_descriptor, vertex_descriptor> passIndex;
|
||||
// Members
|
||||
ccstd::pmr::vector<ccstd::pmr::string> resourceNames;
|
||||
PmrUnorderedStringMap<ccstd::pmr::string, uint32_t> resourceIndex;
|
||||
vertex_descriptor presentPassID{0xFFFFFFFF};
|
||||
PmrFlatMap<vertex_descriptor, LeafStatus> leafPasses;
|
||||
PmrFlatSet<vertex_descriptor> culledPasses;
|
||||
PmrFlatMap<ccstd::pmr::string, ResourceLifeRecord> resourceLifeRecord;
|
||||
ccstd::pmr::vector<vertex_descriptor> topologicalOrder;
|
||||
PmrTransparentMap<ccstd::pmr::string, PmrFlatMap<uint32_t, AccessStatus>> resourceAccess;
|
||||
PmrFlatMap<ccstd::pmr::string, PmrFlatMap<ccstd::pmr::string, ccstd::pmr::string>> movedTarget;
|
||||
PmrFlatMap<ccstd::pmr::string, AccessStatus> movedSourceStatus;
|
||||
PmrFlatMap<ccstd::pmr::string, ResourceNode> movedTargetStatus;
|
||||
};
|
||||
|
||||
struct RelationGraph {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {_vertices.get_allocator().resource()};
|
||||
}
|
||||
|
||||
inline boost::container::pmr::memory_resource* resource() const noexcept {
|
||||
return get_allocator().resource();
|
||||
}
|
||||
|
||||
RelationGraph(const allocator_type& alloc) noexcept; // NOLINT
|
||||
RelationGraph(RelationGraph&& rhs) = delete;
|
||||
RelationGraph(RelationGraph const& rhs) = delete;
|
||||
RelationGraph& operator=(RelationGraph&& rhs) = delete;
|
||||
RelationGraph& operator=(RelationGraph const& rhs) = delete;
|
||||
|
||||
// Graph
|
||||
using directed_category = boost::bidirectional_tag;
|
||||
using vertex_descriptor = uint32_t;
|
||||
using edge_descriptor = impl::EdgeDescriptor<directed_category, vertex_descriptor>;
|
||||
using edge_parallel_category = boost::allow_parallel_edge_tag;
|
||||
struct traversal_category // NOLINT
|
||||
: virtual boost::incidence_graph_tag,
|
||||
virtual boost::bidirectional_graph_tag,
|
||||
virtual boost::adjacency_graph_tag,
|
||||
virtual boost::vertex_list_graph_tag,
|
||||
virtual boost::edge_list_graph_tag {};
|
||||
|
||||
constexpr static vertex_descriptor null_vertex() noexcept { // NOLINT
|
||||
return std::numeric_limits<vertex_descriptor>::max();
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
using OutEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using out_edge_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
using degree_size_type = uint32_t;
|
||||
|
||||
// BidirectionalGraph
|
||||
using InEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using in_edge_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
|
||||
// AdjacencyGraph
|
||||
using adjacency_iterator = boost::adjacency_iterator_generator<
|
||||
RelationGraph, vertex_descriptor, out_edge_iterator>::type;
|
||||
|
||||
// VertexListGraph
|
||||
using vertex_iterator = boost::integer_range<vertex_descriptor>::iterator;
|
||||
using vertices_size_type = uint32_t;
|
||||
|
||||
// VertexList help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
inline boost::integer_range<vertex_descriptor> getVertexList() const noexcept {
|
||||
return {0, static_cast<vertices_size_type>(_vertices.size())};
|
||||
}
|
||||
|
||||
inline vertex_descriptor getCurrentID() const noexcept {
|
||||
return static_cast<vertex_descriptor>(_vertices.size());
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<boost::default_color_type> colors(boost::container::pmr::memory_resource* mr) const {
|
||||
return ccstd::pmr::vector<boost::default_color_type>(_vertices.size(), mr);
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
using edge_iterator = impl::DirectedEdgeIterator<vertex_iterator, out_edge_iterator, RelationGraph>;
|
||||
using edges_size_type = uint32_t;
|
||||
|
||||
// ContinuousContainer
|
||||
void reserve(vertices_size_type sz);
|
||||
|
||||
// Members
|
||||
struct Vertex {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {outEdges.get_allocator().resource()};
|
||||
}
|
||||
|
||||
Vertex(const allocator_type& alloc) noexcept; // NOLINT
|
||||
Vertex(Vertex&& rhs, const allocator_type& alloc);
|
||||
Vertex(Vertex const& rhs, const allocator_type& alloc);
|
||||
|
||||
Vertex(Vertex&& rhs) noexcept = default;
|
||||
Vertex(Vertex const& rhs) = delete;
|
||||
Vertex& operator=(Vertex&& rhs) = default;
|
||||
Vertex& operator=(Vertex const& rhs) = default;
|
||||
|
||||
ccstd::pmr::vector<OutEdge> outEdges;
|
||||
ccstd::pmr::vector<InEdge> inEdges;
|
||||
};
|
||||
|
||||
struct DescIDTag {};
|
||||
|
||||
// Vertices
|
||||
ccstd::pmr::vector<Vertex> _vertices;
|
||||
// Components
|
||||
ccstd::pmr::vector<ResourceAccessGraph::vertex_descriptor> descID;
|
||||
// UuidGraph
|
||||
PmrUnorderedMap<ResourceAccessGraph::vertex_descriptor, vertex_descriptor> vertexMap;
|
||||
};
|
||||
|
||||
struct RenderingInfo {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {clearColors.get_allocator().resource()};
|
||||
}
|
||||
|
||||
RenderingInfo(const allocator_type& alloc) noexcept; // NOLINT
|
||||
RenderingInfo(RenderingInfo&& rhs, const allocator_type& alloc);
|
||||
RenderingInfo(RenderingInfo const& rhs, const allocator_type& alloc);
|
||||
|
||||
RenderingInfo(RenderingInfo&& rhs) noexcept = default;
|
||||
RenderingInfo(RenderingInfo const& rhs) = delete;
|
||||
RenderingInfo& operator=(RenderingInfo&& rhs) = default;
|
||||
RenderingInfo& operator=(RenderingInfo const& rhs) = default;
|
||||
|
||||
gfx::RenderPassInfo renderpassInfo;
|
||||
gfx::FramebufferInfo framebufferInfo;
|
||||
ccstd::pmr::vector<gfx::Color> clearColors;
|
||||
float clearDepth{0};
|
||||
uint8_t clearStencil{0};
|
||||
};
|
||||
|
||||
struct FrameGraphDispatcher {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {resourceAccessGraph.get_allocator().resource()};
|
||||
}
|
||||
|
||||
FrameGraphDispatcher(ResourceGraph& resourceGraphIn, const RenderGraph& renderGraphIn, const LayoutGraphData& layoutGraphIn, boost::container::pmr::memory_resource* scratchIn, const allocator_type& alloc) noexcept;
|
||||
FrameGraphDispatcher(FrameGraphDispatcher&& rhs) = delete;
|
||||
FrameGraphDispatcher(FrameGraphDispatcher const& rhs) = delete;
|
||||
FrameGraphDispatcher& operator=(FrameGraphDispatcher&& rhs) = delete;
|
||||
FrameGraphDispatcher& operator=(FrameGraphDispatcher const& rhs) = delete;
|
||||
|
||||
|
||||
void enablePassReorder(bool enable);
|
||||
|
||||
// how much paralell-execution weights during pass reorder,
|
||||
// eg:0.3 means 30% of effort aim to paralellize execution, other 70% aim to decrease memory using.
|
||||
// 0 by default
|
||||
void setParalellWeight(float paralellExecWeight);
|
||||
|
||||
void enableMemoryAliasing(bool enable);
|
||||
|
||||
void run();
|
||||
|
||||
const BarrierNode& getBarrier(RenderGraph::vertex_descriptor u) const;
|
||||
|
||||
const ResourceAccessNode& getAccessNode(RenderGraph::vertex_descriptor u) const;
|
||||
|
||||
const gfx::RenderPassInfo& getRenderPassInfo(RenderGraph::vertex_descriptor u) const;
|
||||
|
||||
RenderingInfo getRenderPassAndFrameBuffer(RenderGraph::vertex_descriptor u, const ResourceGraph& resg) const;
|
||||
|
||||
LayoutAccess getResourceAccess(ResourceGraph::vertex_descriptor r, RenderGraph::vertex_descriptor p) const;
|
||||
|
||||
// those resource been moved point to another resID
|
||||
ResourceGraph::vertex_descriptor realResourceID(const ccstd::pmr::string& name) const;
|
||||
|
||||
PmrFlatMap<NameLocalID, ResourceGraph::vertex_descriptor> buildDescriptorIndex(
|
||||
const PmrTransparentMap<ccstd::pmr::string, ccstd::pmr::vector<ComputeView>>&computeViews,
|
||||
const PmrTransparentMap<ccstd::pmr::string, RasterView>& rasterViews,
|
||||
boost::container::pmr::memory_resource* scratch) const;
|
||||
|
||||
PmrFlatMap<NameLocalID, ResourceGraph::vertex_descriptor> buildDescriptorIndex(
|
||||
const PmrTransparentMap<ccstd::pmr::string, ccstd::pmr::vector<ComputeView>>&computeViews,
|
||||
boost::container::pmr::memory_resource* scratch) const;
|
||||
|
||||
ResourceAccessGraph resourceAccessGraph;
|
||||
ResourceGraph& resourceGraph;
|
||||
const RenderGraph& renderGraph;
|
||||
const LayoutGraphData& layoutGraph;
|
||||
boost::container::pmr::memory_resource* scratch{nullptr};
|
||||
RelationGraph relationGraph;
|
||||
bool _enablePassReorder{false};
|
||||
bool _enableAutoBarrier{true};
|
||||
bool _enableMemoryAliasing{false};
|
||||
bool _accessGraphBuilt{false};
|
||||
float _paralellExecWeight{0.0F};
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
2643
cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp
Normal file
2643
cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp
Normal file
File diff suppressed because it is too large
Load Diff
81
cocos/renderer/pipeline/custom/LayoutGraphFwd.h
Normal file
81
cocos/renderer/pipeline/custom/LayoutGraphFwd.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct DescriptorDB;
|
||||
struct RenderStageTag;
|
||||
struct RenderPhaseTag;
|
||||
struct RenderPhase;
|
||||
|
||||
enum class RenderPassType : uint32_t;
|
||||
|
||||
struct LayoutGraph;
|
||||
|
||||
using UniformID = uint32_t;
|
||||
|
||||
struct UniformData;
|
||||
struct UniformBlockData;
|
||||
struct NameLocalID;
|
||||
struct DescriptorData;
|
||||
struct DescriptorBlockData;
|
||||
struct DescriptorSetLayoutData;
|
||||
struct DescriptorSetData;
|
||||
struct PipelineLayoutData;
|
||||
struct ShaderBindingData;
|
||||
struct ShaderLayoutData;
|
||||
struct TechniqueData;
|
||||
struct EffectData;
|
||||
struct ShaderProgramData;
|
||||
struct RenderStageData;
|
||||
struct RenderPhaseData;
|
||||
struct LayoutGraphData;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::NameLocalID> {
|
||||
hash_t operator()(const cc::render::NameLocalID& val) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
2059
cocos/renderer/pipeline/custom/LayoutGraphGraphs.h
Normal file
2059
cocos/renderer/pipeline/custom/LayoutGraphGraphs.h
Normal file
File diff suppressed because it is too large
Load Diff
73
cocos/renderer/pipeline/custom/LayoutGraphNames.h
Normal file
73
cocos/renderer/pipeline/custom/LayoutGraphNames.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonNames.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
inline const char* getName(const DescriptorDB& /*v*/) noexcept { return "DescriptorDB"; }
|
||||
inline const char* getName(const RenderStageTag& /*v*/) noexcept { return "RenderStage"; }
|
||||
inline const char* getName(const RenderPhaseTag& /*v*/) noexcept { return "RenderPhase"; }
|
||||
inline const char* getName(const RenderPhase& /*v*/) noexcept { return "RenderPhase"; }
|
||||
inline const char* getName(RenderPassType e) noexcept {
|
||||
switch (e) {
|
||||
case RenderPassType::SINGLE_RENDER_PASS: return "SINGLE_RENDER_PASS";
|
||||
case RenderPassType::RENDER_PASS: return "RENDER_PASS";
|
||||
case RenderPassType::RENDER_SUBPASS: return "RENDER_SUBPASS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(const LayoutGraph& /*v*/) noexcept { return "LayoutGraph"; }
|
||||
inline const char* getName(const UniformData& /*v*/) noexcept { return "UniformData"; }
|
||||
inline const char* getName(const UniformBlockData& /*v*/) noexcept { return "UniformBlockData"; }
|
||||
inline const char* getName(const NameLocalID& /*v*/) noexcept { return "NameLocalID"; }
|
||||
inline const char* getName(const DescriptorData& /*v*/) noexcept { return "DescriptorData"; }
|
||||
inline const char* getName(const DescriptorBlockData& /*v*/) noexcept { return "DescriptorBlockData"; }
|
||||
inline const char* getName(const DescriptorSetLayoutData& /*v*/) noexcept { return "DescriptorSetLayoutData"; }
|
||||
inline const char* getName(const DescriptorSetData& /*v*/) noexcept { return "DescriptorSetData"; }
|
||||
inline const char* getName(const PipelineLayoutData& /*v*/) noexcept { return "PipelineLayoutData"; }
|
||||
inline const char* getName(const ShaderBindingData& /*v*/) noexcept { return "ShaderBindingData"; }
|
||||
inline const char* getName(const ShaderLayoutData& /*v*/) noexcept { return "ShaderLayoutData"; }
|
||||
inline const char* getName(const TechniqueData& /*v*/) noexcept { return "TechniqueData"; }
|
||||
inline const char* getName(const EffectData& /*v*/) noexcept { return "EffectData"; }
|
||||
inline const char* getName(const ShaderProgramData& /*v*/) noexcept { return "ShaderProgramData"; }
|
||||
inline const char* getName(const RenderStageData& /*v*/) noexcept { return "RenderStageData"; }
|
||||
inline const char* getName(const RenderPhaseData& /*v*/) noexcept { return "RenderPhaseData"; }
|
||||
inline const char* getName(const LayoutGraphData& /*v*/) noexcept { return "LayoutGraphData"; }
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
405
cocos/renderer/pipeline/custom/LayoutGraphSerialization.h
Normal file
405
cocos/renderer/pipeline/custom/LayoutGraphSerialization.h
Normal file
@@ -0,0 +1,405 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/ArchiveTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonSerialization.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Range.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/SerializationUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorDB& v) {
|
||||
save(ar, v.blocks);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorDB& v) {
|
||||
load(ar, v.blocks);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const RenderPhase& v) {
|
||||
save(ar, v.shaders);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, RenderPhase& v) {
|
||||
load(ar, v.shaders);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const LayoutGraph& g) {
|
||||
using Graph = LayoutGraph;
|
||||
using VertexT = Graph::vertex_descriptor;
|
||||
using SizeT = Graph::vertices_size_type;
|
||||
static_assert(std::is_same_v<SizeT, VertexT>);
|
||||
|
||||
const auto numVertices = num_vertices(g);
|
||||
const auto numEdges = num_edges(g);
|
||||
save(ar, numVertices);
|
||||
save(ar, numEdges);
|
||||
|
||||
save(ar, static_cast<SizeT>(g.stages.size()));
|
||||
save(ar, static_cast<SizeT>(g.phases.size()));
|
||||
|
||||
const auto nameMap = get(Graph::NameTag{}, g);
|
||||
const auto descriptorsMap = get(Graph::DescriptorsTag{}, g);
|
||||
for (const auto& v : makeRange(vertices(g))) {
|
||||
const auto typeID = static_cast<SizeT>(tag(v, g).index());
|
||||
static_assert(std::is_same_v<decltype(typeID), const SizeT>);
|
||||
save(ar, typeID);
|
||||
save(ar, parent(v, g));
|
||||
save(ar, get(nameMap, v));
|
||||
save(ar, get(descriptorsMap, v));
|
||||
visitObject(
|
||||
v, g,
|
||||
overload(
|
||||
[&](const auto& object) {
|
||||
save(ar, object);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, LayoutGraph& g) {
|
||||
using Graph = LayoutGraph;
|
||||
using VertexT = Graph::vertex_descriptor;
|
||||
using SizeT = Graph::vertices_size_type;
|
||||
static_assert(std::is_same_v<SizeT, VertexT>);
|
||||
|
||||
SizeT numVertices = 0;
|
||||
SizeT numEdges = 0;
|
||||
load(ar, numVertices);
|
||||
load(ar, numEdges);
|
||||
g.reserve(numVertices);
|
||||
|
||||
SizeT stages = 0;
|
||||
SizeT phases = 0;
|
||||
load(ar, stages);
|
||||
load(ar, phases);
|
||||
g.stages.reserve(stages);
|
||||
g.phases.reserve(phases);
|
||||
|
||||
const auto nameMap = get(Graph::NameTag{}, g);
|
||||
const auto descriptorsMap = get(Graph::DescriptorsTag{}, g);
|
||||
for (SizeT v = 0; v != numVertices; ++v) {
|
||||
SizeT id = std::numeric_limits<SizeT>::max();
|
||||
VertexT u = Graph::null_vertex();
|
||||
ccstd::pmr::string name(g.get_allocator());
|
||||
DescriptorDB descriptors(g.get_allocator());
|
||||
load(ar, id);
|
||||
load(ar, u);
|
||||
load(ar, name);
|
||||
load(ar, descriptors);
|
||||
switch (id) {
|
||||
case 0: {
|
||||
RenderPassType val;
|
||||
load(ar, val);
|
||||
addVertex(std::move(name), std::move(descriptors), val, g, u);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
RenderPhase val(g.get_allocator());
|
||||
load(ar, val);
|
||||
addVertex(std::move(name), std::move(descriptors), std::move(val), g, u);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("load graph failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const UniformData& v) {
|
||||
save(ar, v.uniformID);
|
||||
save(ar, v.uniformType);
|
||||
save(ar, v.offset);
|
||||
save(ar, v.size);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, UniformData& v) {
|
||||
load(ar, v.uniformID);
|
||||
load(ar, v.uniformType);
|
||||
load(ar, v.offset);
|
||||
load(ar, v.size);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const UniformBlockData& v) {
|
||||
save(ar, v.bufferSize);
|
||||
save(ar, v.uniforms);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, UniformBlockData& v) {
|
||||
load(ar, v.bufferSize);
|
||||
load(ar, v.uniforms);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const NameLocalID& v) {
|
||||
save(ar, v.value);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, NameLocalID& v) {
|
||||
load(ar, v.value);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorData& v) {
|
||||
save(ar, v.descriptorID);
|
||||
save(ar, v.type);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorData& v) {
|
||||
load(ar, v.descriptorID);
|
||||
load(ar, v.type);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorBlockData& v) {
|
||||
save(ar, v.type);
|
||||
save(ar, v.visibility);
|
||||
save(ar, v.offset);
|
||||
save(ar, v.capacity);
|
||||
save(ar, v.descriptors);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorBlockData& v) {
|
||||
load(ar, v.type);
|
||||
load(ar, v.visibility);
|
||||
load(ar, v.offset);
|
||||
load(ar, v.capacity);
|
||||
load(ar, v.descriptors);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorSetLayoutData& v) {
|
||||
save(ar, v.slot);
|
||||
save(ar, v.capacity);
|
||||
save(ar, v.uniformBlockCapacity);
|
||||
save(ar, v.samplerTextureCapacity);
|
||||
save(ar, v.descriptorBlocks);
|
||||
save(ar, v.uniformBlocks);
|
||||
save(ar, v.bindingMap);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorSetLayoutData& v) {
|
||||
load(ar, v.slot);
|
||||
load(ar, v.capacity);
|
||||
load(ar, v.uniformBlockCapacity);
|
||||
load(ar, v.samplerTextureCapacity);
|
||||
load(ar, v.descriptorBlocks);
|
||||
load(ar, v.uniformBlocks);
|
||||
load(ar, v.bindingMap);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorSetData& v) {
|
||||
save(ar, v.descriptorSetLayoutData);
|
||||
save(ar, v.descriptorSetLayoutInfo);
|
||||
// skip, descriptorSetLayout: IntrusivePtr<gfx::DescriptorSetLayout>
|
||||
// skip, descriptorSet: IntrusivePtr<gfx::DescriptorSet>
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorSetData& v) {
|
||||
load(ar, v.descriptorSetLayoutData);
|
||||
load(ar, v.descriptorSetLayoutInfo);
|
||||
// skip, descriptorSetLayout: IntrusivePtr<gfx::DescriptorSetLayout>
|
||||
// skip, descriptorSet: IntrusivePtr<gfx::DescriptorSet>
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const PipelineLayoutData& v) {
|
||||
save(ar, v.descriptorSets);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, PipelineLayoutData& v) {
|
||||
load(ar, v.descriptorSets);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const ShaderBindingData& v) {
|
||||
save(ar, v.descriptorBindings);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, ShaderBindingData& v) {
|
||||
load(ar, v.descriptorBindings);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const ShaderLayoutData& v) {
|
||||
save(ar, v.layoutData);
|
||||
save(ar, v.bindingData);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, ShaderLayoutData& v) {
|
||||
load(ar, v.layoutData);
|
||||
load(ar, v.bindingData);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const TechniqueData& v) {
|
||||
save(ar, v.passes);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, TechniqueData& v) {
|
||||
load(ar, v.passes);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const EffectData& v) {
|
||||
save(ar, v.techniques);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, EffectData& v) {
|
||||
load(ar, v.techniques);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const ShaderProgramData& v) {
|
||||
save(ar, v.layout);
|
||||
// skip, pipelineLayout: IntrusivePtr<gfx::PipelineLayout>
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, ShaderProgramData& v) {
|
||||
load(ar, v.layout);
|
||||
// skip, pipelineLayout: IntrusivePtr<gfx::PipelineLayout>
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const RenderStageData& v) {
|
||||
save(ar, v.descriptorVisibility);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, RenderStageData& v) {
|
||||
load(ar, v.descriptorVisibility);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const RenderPhaseData& v) {
|
||||
save(ar, v.rootSignature);
|
||||
save(ar, v.shaderPrograms);
|
||||
save(ar, v.shaderIndex);
|
||||
// skip, pipelineLayout: IntrusivePtr<gfx::PipelineLayout>
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, RenderPhaseData& v) {
|
||||
load(ar, v.rootSignature);
|
||||
load(ar, v.shaderPrograms);
|
||||
load(ar, v.shaderIndex);
|
||||
// skip, pipelineLayout: IntrusivePtr<gfx::PipelineLayout>
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const LayoutGraphData& g) {
|
||||
using Graph = LayoutGraphData;
|
||||
using VertexT = Graph::vertex_descriptor;
|
||||
using SizeT = Graph::vertices_size_type;
|
||||
static_assert(std::is_same_v<SizeT, VertexT>);
|
||||
|
||||
const auto numVertices = num_vertices(g);
|
||||
const auto numEdges = num_edges(g);
|
||||
save(ar, numVertices);
|
||||
save(ar, numEdges);
|
||||
|
||||
save(ar, static_cast<SizeT>(g.stages.size()));
|
||||
save(ar, static_cast<SizeT>(g.phases.size()));
|
||||
|
||||
const auto nameMap = get(Graph::NameTag{}, g);
|
||||
const auto updateMap = get(Graph::UpdateTag{}, g);
|
||||
const auto layoutMap = get(Graph::LayoutTag{}, g);
|
||||
for (const auto& v : makeRange(vertices(g))) {
|
||||
const auto typeID = static_cast<SizeT>(tag(v, g).index());
|
||||
static_assert(std::is_same_v<decltype(typeID), const SizeT>);
|
||||
save(ar, typeID);
|
||||
save(ar, parent(v, g));
|
||||
save(ar, get(nameMap, v));
|
||||
save(ar, get(updateMap, v));
|
||||
save(ar, get(layoutMap, v));
|
||||
visitObject(
|
||||
v, g,
|
||||
overload(
|
||||
[&](const auto& object) {
|
||||
save(ar, object);
|
||||
}));
|
||||
}
|
||||
save(ar, g.valueNames);
|
||||
save(ar, g.attributeIndex);
|
||||
save(ar, g.constantIndex);
|
||||
save(ar, g.shaderLayoutIndex);
|
||||
save(ar, g.effects);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, LayoutGraphData& g) {
|
||||
using Graph = LayoutGraphData;
|
||||
using VertexT = Graph::vertex_descriptor;
|
||||
using SizeT = Graph::vertices_size_type;
|
||||
static_assert(std::is_same_v<SizeT, VertexT>);
|
||||
|
||||
SizeT numVertices = 0;
|
||||
SizeT numEdges = 0;
|
||||
load(ar, numVertices);
|
||||
load(ar, numEdges);
|
||||
g.reserve(numVertices);
|
||||
|
||||
SizeT stages = 0;
|
||||
SizeT phases = 0;
|
||||
load(ar, stages);
|
||||
load(ar, phases);
|
||||
g.stages.reserve(stages);
|
||||
g.phases.reserve(phases);
|
||||
|
||||
const auto nameMap = get(Graph::NameTag{}, g);
|
||||
const auto updateMap = get(Graph::UpdateTag{}, g);
|
||||
const auto layoutMap = get(Graph::LayoutTag{}, g);
|
||||
for (SizeT v = 0; v != numVertices; ++v) {
|
||||
SizeT id = std::numeric_limits<SizeT>::max();
|
||||
VertexT u = Graph::null_vertex();
|
||||
ccstd::pmr::string name(g.get_allocator());
|
||||
UpdateFrequency update{};
|
||||
PipelineLayoutData layout(g.get_allocator());
|
||||
load(ar, id);
|
||||
load(ar, u);
|
||||
load(ar, name);
|
||||
load(ar, update);
|
||||
load(ar, layout);
|
||||
switch (id) {
|
||||
case 0: {
|
||||
RenderStageData val(g.get_allocator());
|
||||
load(ar, val);
|
||||
addVertex(std::move(name), update, std::move(layout), std::move(val), g, u);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
RenderPhaseData val(g.get_allocator());
|
||||
load(ar, val);
|
||||
addVertex(std::move(name), update, std::move(layout), std::move(val), g, u);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("load graph failed");
|
||||
}
|
||||
}
|
||||
load(ar, g.valueNames);
|
||||
load(ar, g.attributeIndex);
|
||||
load(ar, g.constantIndex);
|
||||
load(ar, g.shaderLayoutIndex);
|
||||
load(ar, g.effects);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
280
cocos/renderer/pipeline/custom/LayoutGraphTypes.cpp
Normal file
280
cocos/renderer/pipeline/custom/LayoutGraphTypes.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "LayoutGraphTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
DescriptorDB::DescriptorDB(const allocator_type& alloc) noexcept
|
||||
: blocks(alloc) {}
|
||||
|
||||
DescriptorDB::DescriptorDB(DescriptorDB&& rhs, const allocator_type& alloc)
|
||||
: blocks(std::move(rhs.blocks), alloc) {}
|
||||
|
||||
DescriptorDB::DescriptorDB(DescriptorDB const& rhs, const allocator_type& alloc)
|
||||
: blocks(rhs.blocks, alloc) {}
|
||||
|
||||
RenderPhase::RenderPhase(const allocator_type& alloc) noexcept
|
||||
: shaders(alloc) {}
|
||||
|
||||
RenderPhase::RenderPhase(RenderPhase&& rhs, const allocator_type& alloc)
|
||||
: shaders(std::move(rhs.shaders), alloc) {}
|
||||
|
||||
RenderPhase::RenderPhase(RenderPhase const& rhs, const allocator_type& alloc)
|
||||
: shaders(rhs.shaders, alloc) {}
|
||||
|
||||
LayoutGraph::LayoutGraph(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
names(alloc),
|
||||
descriptors(alloc),
|
||||
stages(alloc),
|
||||
phases(alloc),
|
||||
pathIndex(alloc) {}
|
||||
|
||||
LayoutGraph::LayoutGraph(LayoutGraph&& rhs, const allocator_type& alloc)
|
||||
: _vertices(std::move(rhs._vertices), alloc),
|
||||
names(std::move(rhs.names), alloc),
|
||||
descriptors(std::move(rhs.descriptors), alloc),
|
||||
stages(std::move(rhs.stages), alloc),
|
||||
phases(std::move(rhs.phases), alloc),
|
||||
pathIndex(std::move(rhs.pathIndex), alloc) {}
|
||||
|
||||
LayoutGraph::LayoutGraph(LayoutGraph const& rhs, const allocator_type& alloc)
|
||||
: _vertices(rhs._vertices, alloc),
|
||||
names(rhs.names, alloc),
|
||||
descriptors(rhs.descriptors, alloc),
|
||||
stages(rhs.stages, alloc),
|
||||
phases(rhs.phases, alloc),
|
||||
pathIndex(rhs.pathIndex, alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void LayoutGraph::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
names.reserve(sz);
|
||||
descriptors.reserve(sz);
|
||||
}
|
||||
|
||||
LayoutGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
LayoutGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc),
|
||||
handle(std::move(rhs.handle)) {}
|
||||
|
||||
LayoutGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc),
|
||||
handle(rhs.handle) {}
|
||||
|
||||
UniformBlockData::UniformBlockData(const allocator_type& alloc) noexcept
|
||||
: uniforms(alloc) {}
|
||||
|
||||
UniformBlockData::UniformBlockData(UniformBlockData&& rhs, const allocator_type& alloc)
|
||||
: bufferSize(rhs.bufferSize),
|
||||
uniforms(std::move(rhs.uniforms), alloc) {}
|
||||
|
||||
UniformBlockData::UniformBlockData(UniformBlockData const& rhs, const allocator_type& alloc)
|
||||
: bufferSize(rhs.bufferSize),
|
||||
uniforms(rhs.uniforms, alloc) {}
|
||||
|
||||
DescriptorBlockData::DescriptorBlockData(const allocator_type& alloc) noexcept
|
||||
: descriptors(alloc) {}
|
||||
|
||||
DescriptorBlockData::DescriptorBlockData(DescriptorTypeOrder typeIn, gfx::ShaderStageFlagBit visibilityIn, uint32_t capacityIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: type(typeIn),
|
||||
visibility(visibilityIn),
|
||||
capacity(capacityIn),
|
||||
descriptors(alloc) {}
|
||||
|
||||
DescriptorBlockData::DescriptorBlockData(DescriptorBlockData&& rhs, const allocator_type& alloc)
|
||||
: type(rhs.type),
|
||||
visibility(rhs.visibility),
|
||||
offset(rhs.offset),
|
||||
capacity(rhs.capacity),
|
||||
descriptors(std::move(rhs.descriptors), alloc) {}
|
||||
|
||||
DescriptorBlockData::DescriptorBlockData(DescriptorBlockData const& rhs, const allocator_type& alloc)
|
||||
: type(rhs.type),
|
||||
visibility(rhs.visibility),
|
||||
offset(rhs.offset),
|
||||
capacity(rhs.capacity),
|
||||
descriptors(rhs.descriptors, alloc) {}
|
||||
|
||||
DescriptorSetLayoutData::DescriptorSetLayoutData(const allocator_type& alloc) noexcept
|
||||
: descriptorBlocks(alloc),
|
||||
uniformBlocks(alloc),
|
||||
bindingMap(alloc) {}
|
||||
|
||||
DescriptorSetLayoutData::DescriptorSetLayoutData(uint32_t slotIn, uint32_t capacityIn, ccstd::pmr::vector<DescriptorBlockData> descriptorBlocksIn, PmrUnorderedMap<NameLocalID, gfx::UniformBlock> uniformBlocksIn, PmrFlatMap<NameLocalID, uint32_t> bindingMapIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: slot(slotIn),
|
||||
capacity(capacityIn),
|
||||
descriptorBlocks(std::move(descriptorBlocksIn), alloc),
|
||||
uniformBlocks(std::move(uniformBlocksIn), alloc),
|
||||
bindingMap(std::move(bindingMapIn), alloc) {}
|
||||
|
||||
DescriptorSetLayoutData::DescriptorSetLayoutData(DescriptorSetLayoutData&& rhs, const allocator_type& alloc)
|
||||
: slot(rhs.slot),
|
||||
capacity(rhs.capacity),
|
||||
uniformBlockCapacity(rhs.uniformBlockCapacity),
|
||||
samplerTextureCapacity(rhs.samplerTextureCapacity),
|
||||
descriptorBlocks(std::move(rhs.descriptorBlocks), alloc),
|
||||
uniformBlocks(std::move(rhs.uniformBlocks), alloc),
|
||||
bindingMap(std::move(rhs.bindingMap), alloc) {}
|
||||
|
||||
DescriptorSetData::DescriptorSetData(const allocator_type& alloc) noexcept
|
||||
: descriptorSetLayoutData(alloc) {}
|
||||
|
||||
DescriptorSetData::DescriptorSetData(DescriptorSetLayoutData descriptorSetLayoutDataIn, IntrusivePtr<gfx::DescriptorSetLayout> descriptorSetLayoutIn, IntrusivePtr<gfx::DescriptorSet> descriptorSetIn, const allocator_type& alloc) noexcept
|
||||
: descriptorSetLayoutData(std::move(descriptorSetLayoutDataIn), alloc),
|
||||
descriptorSetLayout(std::move(descriptorSetLayoutIn)),
|
||||
descriptorSet(std::move(descriptorSetIn)) {}
|
||||
|
||||
DescriptorSetData::DescriptorSetData(DescriptorSetData&& rhs, const allocator_type& alloc)
|
||||
: descriptorSetLayoutData(std::move(rhs.descriptorSetLayoutData), alloc),
|
||||
descriptorSetLayoutInfo(std::move(rhs.descriptorSetLayoutInfo)),
|
||||
descriptorSetLayout(std::move(rhs.descriptorSetLayout)),
|
||||
descriptorSet(std::move(rhs.descriptorSet)) {}
|
||||
|
||||
PipelineLayoutData::PipelineLayoutData(const allocator_type& alloc) noexcept
|
||||
: descriptorSets(alloc) {}
|
||||
|
||||
PipelineLayoutData::PipelineLayoutData(PipelineLayoutData&& rhs, const allocator_type& alloc)
|
||||
: descriptorSets(std::move(rhs.descriptorSets), alloc) {}
|
||||
|
||||
ShaderBindingData::ShaderBindingData(const allocator_type& alloc) noexcept
|
||||
: descriptorBindings(alloc) {}
|
||||
|
||||
ShaderBindingData::ShaderBindingData(ShaderBindingData&& rhs, const allocator_type& alloc)
|
||||
: descriptorBindings(std::move(rhs.descriptorBindings), alloc) {}
|
||||
|
||||
ShaderLayoutData::ShaderLayoutData(const allocator_type& alloc) noexcept
|
||||
: layoutData(alloc),
|
||||
bindingData(alloc) {}
|
||||
|
||||
ShaderLayoutData::ShaderLayoutData(ShaderLayoutData&& rhs, const allocator_type& alloc)
|
||||
: layoutData(std::move(rhs.layoutData), alloc),
|
||||
bindingData(std::move(rhs.bindingData), alloc) {}
|
||||
|
||||
TechniqueData::TechniqueData(const allocator_type& alloc) noexcept
|
||||
: passes(alloc) {}
|
||||
|
||||
TechniqueData::TechniqueData(TechniqueData&& rhs, const allocator_type& alloc)
|
||||
: passes(std::move(rhs.passes), alloc) {}
|
||||
|
||||
EffectData::EffectData(const allocator_type& alloc) noexcept
|
||||
: techniques(alloc) {}
|
||||
|
||||
EffectData::EffectData(EffectData&& rhs, const allocator_type& alloc)
|
||||
: techniques(std::move(rhs.techniques), alloc) {}
|
||||
|
||||
ShaderProgramData::ShaderProgramData(const allocator_type& alloc) noexcept
|
||||
: layout(alloc) {}
|
||||
|
||||
ShaderProgramData::ShaderProgramData(ShaderProgramData&& rhs, const allocator_type& alloc)
|
||||
: layout(std::move(rhs.layout), alloc),
|
||||
pipelineLayout(std::move(rhs.pipelineLayout)) {}
|
||||
|
||||
RenderStageData::RenderStageData(const allocator_type& alloc) noexcept
|
||||
: descriptorVisibility(alloc) {}
|
||||
|
||||
RenderStageData::RenderStageData(RenderStageData&& rhs, const allocator_type& alloc)
|
||||
: descriptorVisibility(std::move(rhs.descriptorVisibility), alloc) {}
|
||||
|
||||
RenderPhaseData::RenderPhaseData(const allocator_type& alloc) noexcept
|
||||
: rootSignature(alloc),
|
||||
shaderPrograms(alloc),
|
||||
shaderIndex(alloc) {}
|
||||
|
||||
RenderPhaseData::RenderPhaseData(RenderPhaseData&& rhs, const allocator_type& alloc)
|
||||
: rootSignature(std::move(rhs.rootSignature), alloc),
|
||||
shaderPrograms(std::move(rhs.shaderPrograms), alloc),
|
||||
shaderIndex(std::move(rhs.shaderIndex), alloc),
|
||||
pipelineLayout(std::move(rhs.pipelineLayout)) {}
|
||||
|
||||
LayoutGraphData::LayoutGraphData(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
names(alloc),
|
||||
updateFrequencies(alloc),
|
||||
layouts(alloc),
|
||||
stages(alloc),
|
||||
phases(alloc),
|
||||
valueNames(alloc),
|
||||
attributeIndex(alloc),
|
||||
constantIndex(alloc),
|
||||
shaderLayoutIndex(alloc),
|
||||
effects(alloc),
|
||||
pathIndex(alloc) {}
|
||||
|
||||
LayoutGraphData::LayoutGraphData(LayoutGraphData&& rhs, const allocator_type& alloc)
|
||||
: _vertices(std::move(rhs._vertices), alloc),
|
||||
names(std::move(rhs.names), alloc),
|
||||
updateFrequencies(std::move(rhs.updateFrequencies), alloc),
|
||||
layouts(std::move(rhs.layouts), alloc),
|
||||
stages(std::move(rhs.stages), alloc),
|
||||
phases(std::move(rhs.phases), alloc),
|
||||
valueNames(std::move(rhs.valueNames), alloc),
|
||||
attributeIndex(std::move(rhs.attributeIndex), alloc),
|
||||
constantIndex(std::move(rhs.constantIndex), alloc),
|
||||
shaderLayoutIndex(std::move(rhs.shaderLayoutIndex), alloc),
|
||||
effects(std::move(rhs.effects), alloc),
|
||||
constantMacros(std::move(rhs.constantMacros)),
|
||||
pathIndex(std::move(rhs.pathIndex), alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void LayoutGraphData::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
names.reserve(sz);
|
||||
updateFrequencies.reserve(sz);
|
||||
layouts.reserve(sz);
|
||||
}
|
||||
|
||||
LayoutGraphData::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
LayoutGraphData::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc),
|
||||
handle(std::move(rhs.handle)) {}
|
||||
|
||||
LayoutGraphData::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc),
|
||||
handle(rhs.handle) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
729
cocos/renderer/pipeline/custom/LayoutGraphTypes.h
Normal file
729
cocos/renderer/pipeline/custom/LayoutGraphTypes.h
Normal file
@@ -0,0 +1,729 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/range/irange.hpp>
|
||||
#include "base/std/container/map.h"
|
||||
#include "cocos/base/Ptr.h"
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/container/vector.h"
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDescriptorSet.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDescriptorSetLayout.h"
|
||||
#include "cocos/renderer/gfx-base/GFXPipelineLayout.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Map.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Set.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct DescriptorDB {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {blocks.get_allocator().resource()};
|
||||
}
|
||||
|
||||
DescriptorDB(const allocator_type& alloc) noexcept; // NOLINT
|
||||
DescriptorDB(DescriptorDB&& rhs, const allocator_type& alloc);
|
||||
DescriptorDB(DescriptorDB const& rhs, const allocator_type& alloc);
|
||||
|
||||
DescriptorDB(DescriptorDB&& rhs) noexcept = default;
|
||||
DescriptorDB(DescriptorDB const& rhs) = delete;
|
||||
DescriptorDB& operator=(DescriptorDB&& rhs) = default;
|
||||
DescriptorDB& operator=(DescriptorDB const& rhs) = default;
|
||||
|
||||
ccstd::pmr::map<DescriptorBlockIndex, DescriptorBlock> blocks;
|
||||
};
|
||||
|
||||
struct RenderStageTag {};
|
||||
struct RenderPhaseTag {};
|
||||
|
||||
struct RenderPhase {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {shaders.get_allocator().resource()};
|
||||
}
|
||||
|
||||
RenderPhase(const allocator_type& alloc) noexcept; // NOLINT
|
||||
RenderPhase(RenderPhase&& rhs, const allocator_type& alloc);
|
||||
RenderPhase(RenderPhase const& rhs, const allocator_type& alloc);
|
||||
|
||||
RenderPhase(RenderPhase&& rhs) noexcept = default;
|
||||
RenderPhase(RenderPhase const& rhs) = delete;
|
||||
RenderPhase& operator=(RenderPhase&& rhs) = default;
|
||||
RenderPhase& operator=(RenderPhase const& rhs) = default;
|
||||
|
||||
PmrTransparentSet<ccstd::pmr::string> shaders;
|
||||
};
|
||||
|
||||
enum class RenderPassType : uint32_t {
|
||||
SINGLE_RENDER_PASS,
|
||||
RENDER_PASS,
|
||||
RENDER_SUBPASS,
|
||||
};
|
||||
|
||||
struct LayoutGraph {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {_vertices.get_allocator().resource()};
|
||||
}
|
||||
|
||||
inline boost::container::pmr::memory_resource* resource() const noexcept {
|
||||
return get_allocator().resource();
|
||||
}
|
||||
|
||||
LayoutGraph(const allocator_type& alloc) noexcept; // NOLINT
|
||||
LayoutGraph(LayoutGraph&& rhs, const allocator_type& alloc);
|
||||
LayoutGraph(LayoutGraph const& rhs, const allocator_type& alloc);
|
||||
|
||||
LayoutGraph(LayoutGraph&& rhs) noexcept = default;
|
||||
LayoutGraph(LayoutGraph const& rhs) = delete;
|
||||
LayoutGraph& operator=(LayoutGraph&& rhs) = default;
|
||||
LayoutGraph& operator=(LayoutGraph const& rhs) = default;
|
||||
|
||||
// Graph
|
||||
using directed_category = boost::bidirectional_tag;
|
||||
using vertex_descriptor = uint32_t;
|
||||
using edge_descriptor = impl::EdgeDescriptor<directed_category, vertex_descriptor>;
|
||||
using edge_parallel_category = boost::allow_parallel_edge_tag;
|
||||
struct traversal_category // NOLINT
|
||||
: virtual boost::incidence_graph_tag,
|
||||
virtual boost::bidirectional_graph_tag,
|
||||
virtual boost::adjacency_graph_tag,
|
||||
virtual boost::vertex_list_graph_tag,
|
||||
virtual boost::edge_list_graph_tag {};
|
||||
|
||||
constexpr static vertex_descriptor null_vertex() noexcept { // NOLINT
|
||||
return std::numeric_limits<vertex_descriptor>::max();
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
using OutEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using out_edge_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
using degree_size_type = uint32_t;
|
||||
|
||||
// BidirectionalGraph
|
||||
using InEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using in_edge_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
|
||||
// AdjacencyGraph
|
||||
using adjacency_iterator = boost::adjacency_iterator_generator<
|
||||
LayoutGraph, vertex_descriptor, out_edge_iterator>::type;
|
||||
|
||||
// VertexListGraph
|
||||
using vertex_iterator = boost::integer_range<vertex_descriptor>::iterator;
|
||||
using vertices_size_type = uint32_t;
|
||||
|
||||
// VertexList help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
inline boost::integer_range<vertex_descriptor> getVertexList() const noexcept {
|
||||
return {0, static_cast<vertices_size_type>(_vertices.size())};
|
||||
}
|
||||
|
||||
inline vertex_descriptor getCurrentID() const noexcept {
|
||||
return static_cast<vertex_descriptor>(_vertices.size());
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<boost::default_color_type> colors(boost::container::pmr::memory_resource* mr) const {
|
||||
return ccstd::pmr::vector<boost::default_color_type>(_vertices.size(), mr);
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
using edge_iterator = impl::DirectedEdgeIterator<vertex_iterator, out_edge_iterator, LayoutGraph>;
|
||||
using edges_size_type = uint32_t;
|
||||
|
||||
// AddressableGraph (Alias)
|
||||
using ownership_descriptor = impl::EdgeDescriptor<boost::bidirectional_tag, vertex_descriptor>;
|
||||
|
||||
using ChildEdge = OutEdge;
|
||||
using children_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, ownership_descriptor, int32_t>;
|
||||
using children_size_type = uint32_t;
|
||||
|
||||
using ParentEdge = InEdge;
|
||||
using parent_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, ownership_descriptor, int32_t>;
|
||||
|
||||
using ownership_iterator = impl::DirectedEdgeIterator<vertex_iterator, children_iterator, LayoutGraph>;
|
||||
using ownerships_size_type = edges_size_type;
|
||||
|
||||
// AddressableGraph help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getChildrenList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getChildrenList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getParentsList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getParentsList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
// PolymorphicGraph
|
||||
using VertexTag = ccstd::variant<RenderStageTag, RenderPhaseTag>;
|
||||
using VertexValue = ccstd::variant<RenderPassType*, RenderPhase*>;
|
||||
using VertexConstValue = ccstd::variant<const RenderPassType*, const RenderPhase*>;
|
||||
using VertexHandle = ccstd::variant<
|
||||
impl::ValueHandle<RenderStageTag, vertex_descriptor>,
|
||||
impl::ValueHandle<RenderPhaseTag, vertex_descriptor>>;
|
||||
|
||||
// ContinuousContainer
|
||||
void reserve(vertices_size_type sz);
|
||||
|
||||
// Members
|
||||
struct Vertex {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {outEdges.get_allocator().resource()};
|
||||
}
|
||||
|
||||
Vertex(const allocator_type& alloc) noexcept; // NOLINT
|
||||
Vertex(Vertex&& rhs, const allocator_type& alloc);
|
||||
Vertex(Vertex const& rhs, const allocator_type& alloc);
|
||||
|
||||
Vertex(Vertex&& rhs) noexcept = default;
|
||||
Vertex(Vertex const& rhs) = delete;
|
||||
Vertex& operator=(Vertex&& rhs) = default;
|
||||
Vertex& operator=(Vertex const& rhs) = default;
|
||||
|
||||
ccstd::pmr::vector<OutEdge> outEdges;
|
||||
ccstd::pmr::vector<InEdge> inEdges;
|
||||
VertexHandle handle;
|
||||
};
|
||||
|
||||
struct NameTag {};
|
||||
struct DescriptorsTag {};
|
||||
|
||||
// Vertices
|
||||
ccstd::pmr::vector<Vertex> _vertices;
|
||||
// Components
|
||||
ccstd::pmr::vector<ccstd::pmr::string> names;
|
||||
ccstd::pmr::vector<DescriptorDB> descriptors;
|
||||
// PolymorphicGraph
|
||||
ccstd::pmr::vector<RenderPassType> stages;
|
||||
ccstd::pmr::vector<RenderPhase> phases;
|
||||
// Path
|
||||
PmrTransparentMap<ccstd::pmr::string, vertex_descriptor> pathIndex;
|
||||
};
|
||||
|
||||
struct UniformData {
|
||||
UniformData() = default;
|
||||
UniformData(UniformID uniformIDIn, gfx::Type uniformTypeIn, uint32_t offsetIn) noexcept // NOLINT
|
||||
: uniformID(uniformIDIn),
|
||||
uniformType(uniformTypeIn),
|
||||
offset(offsetIn) {}
|
||||
|
||||
UniformID uniformID{0xFFFFFFFF};
|
||||
gfx::Type uniformType{gfx::Type::UNKNOWN};
|
||||
uint32_t offset{0};
|
||||
uint32_t size{0};
|
||||
};
|
||||
|
||||
struct UniformBlockData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {uniforms.get_allocator().resource()};
|
||||
}
|
||||
|
||||
UniformBlockData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
UniformBlockData(UniformBlockData&& rhs, const allocator_type& alloc);
|
||||
UniformBlockData(UniformBlockData const& rhs, const allocator_type& alloc);
|
||||
|
||||
UniformBlockData(UniformBlockData&& rhs) noexcept = default;
|
||||
UniformBlockData(UniformBlockData const& rhs) = delete;
|
||||
UniformBlockData& operator=(UniformBlockData&& rhs) = default;
|
||||
UniformBlockData& operator=(UniformBlockData const& rhs) = default;
|
||||
|
||||
uint32_t bufferSize{0};
|
||||
ccstd::pmr::vector<UniformData> uniforms;
|
||||
};
|
||||
|
||||
struct NameLocalID {
|
||||
uint32_t value{0xFFFFFFFF};
|
||||
};
|
||||
|
||||
inline bool operator==(const NameLocalID& lhs, const NameLocalID& rhs) noexcept {
|
||||
return std::forward_as_tuple(lhs.value) ==
|
||||
std::forward_as_tuple(rhs.value);
|
||||
}
|
||||
|
||||
inline bool operator!=(const NameLocalID& lhs, const NameLocalID& rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const NameLocalID& lhs, const NameLocalID& rhs) noexcept {
|
||||
return std::forward_as_tuple(lhs.value) <
|
||||
std::forward_as_tuple(rhs.value);
|
||||
}
|
||||
|
||||
struct DescriptorData {
|
||||
DescriptorData() = default;
|
||||
DescriptorData(NameLocalID descriptorIDIn, gfx::Type typeIn, uint32_t countIn) noexcept
|
||||
: descriptorID(descriptorIDIn),
|
||||
type(typeIn),
|
||||
count(countIn) {}
|
||||
DescriptorData(NameLocalID descriptorIDIn, gfx::Type typeIn) noexcept
|
||||
: descriptorID(descriptorIDIn),
|
||||
type(typeIn) {}
|
||||
DescriptorData(NameLocalID descriptorIDIn) noexcept // NOLINT
|
||||
: descriptorID(descriptorIDIn) {}
|
||||
|
||||
NameLocalID descriptorID;
|
||||
gfx::Type type{gfx::Type::UNKNOWN};
|
||||
uint32_t count{1};
|
||||
};
|
||||
|
||||
struct DescriptorBlockData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptors.get_allocator().resource()};
|
||||
}
|
||||
|
||||
DescriptorBlockData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
DescriptorBlockData(DescriptorTypeOrder typeIn, gfx::ShaderStageFlagBit visibilityIn, uint32_t capacityIn, const allocator_type& alloc) noexcept;
|
||||
DescriptorBlockData(DescriptorBlockData&& rhs, const allocator_type& alloc);
|
||||
DescriptorBlockData(DescriptorBlockData const& rhs, const allocator_type& alloc);
|
||||
|
||||
DescriptorBlockData(DescriptorBlockData&& rhs) noexcept = default;
|
||||
DescriptorBlockData(DescriptorBlockData const& rhs) = delete;
|
||||
DescriptorBlockData& operator=(DescriptorBlockData&& rhs) = default;
|
||||
DescriptorBlockData& operator=(DescriptorBlockData const& rhs) = default;
|
||||
|
||||
DescriptorTypeOrder type{DescriptorTypeOrder::UNIFORM_BUFFER};
|
||||
gfx::ShaderStageFlagBit visibility{gfx::ShaderStageFlagBit::NONE};
|
||||
uint32_t offset{0};
|
||||
uint32_t capacity{0};
|
||||
ccstd::pmr::vector<DescriptorData> descriptors;
|
||||
};
|
||||
|
||||
struct DescriptorSetLayoutData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptorBlocks.get_allocator().resource()};
|
||||
}
|
||||
|
||||
DescriptorSetLayoutData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
DescriptorSetLayoutData(uint32_t slotIn, uint32_t capacityIn, ccstd::pmr::vector<DescriptorBlockData> descriptorBlocksIn, PmrUnorderedMap<NameLocalID, gfx::UniformBlock> uniformBlocksIn, PmrFlatMap<NameLocalID, uint32_t> bindingMapIn, const allocator_type& alloc) noexcept;
|
||||
DescriptorSetLayoutData(DescriptorSetLayoutData&& rhs, const allocator_type& alloc);
|
||||
|
||||
DescriptorSetLayoutData(DescriptorSetLayoutData&& rhs) noexcept = default;
|
||||
DescriptorSetLayoutData(DescriptorSetLayoutData const& rhs) = delete;
|
||||
DescriptorSetLayoutData& operator=(DescriptorSetLayoutData&& rhs) = default;
|
||||
DescriptorSetLayoutData& operator=(DescriptorSetLayoutData const& rhs) = delete;
|
||||
|
||||
uint32_t slot{0xFFFFFFFF};
|
||||
uint32_t capacity{0};
|
||||
uint32_t uniformBlockCapacity{0};
|
||||
uint32_t samplerTextureCapacity{0};
|
||||
ccstd::pmr::vector<DescriptorBlockData> descriptorBlocks;
|
||||
PmrUnorderedMap<NameLocalID, gfx::UniformBlock> uniformBlocks;
|
||||
PmrFlatMap<NameLocalID, uint32_t> bindingMap;
|
||||
};
|
||||
|
||||
struct DescriptorSetData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptorSetLayoutData.get_allocator().resource()};
|
||||
}
|
||||
|
||||
DescriptorSetData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
DescriptorSetData(DescriptorSetLayoutData descriptorSetLayoutDataIn, IntrusivePtr<gfx::DescriptorSetLayout> descriptorSetLayoutIn, IntrusivePtr<gfx::DescriptorSet> descriptorSetIn, const allocator_type& alloc) noexcept;
|
||||
DescriptorSetData(DescriptorSetData&& rhs, const allocator_type& alloc);
|
||||
|
||||
DescriptorSetData(DescriptorSetData&& rhs) noexcept = default;
|
||||
DescriptorSetData(DescriptorSetData const& rhs) = delete;
|
||||
DescriptorSetData& operator=(DescriptorSetData&& rhs) = default;
|
||||
DescriptorSetData& operator=(DescriptorSetData const& rhs) = delete;
|
||||
|
||||
DescriptorSetLayoutData descriptorSetLayoutData;
|
||||
gfx::DescriptorSetLayoutInfo descriptorSetLayoutInfo;
|
||||
IntrusivePtr<gfx::DescriptorSetLayout> descriptorSetLayout;
|
||||
IntrusivePtr<gfx::DescriptorSet> descriptorSet;
|
||||
};
|
||||
|
||||
struct PipelineLayoutData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptorSets.get_allocator().resource()};
|
||||
}
|
||||
|
||||
PipelineLayoutData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
PipelineLayoutData(PipelineLayoutData&& rhs, const allocator_type& alloc);
|
||||
|
||||
PipelineLayoutData(PipelineLayoutData&& rhs) noexcept = default;
|
||||
PipelineLayoutData(PipelineLayoutData const& rhs) = delete;
|
||||
PipelineLayoutData& operator=(PipelineLayoutData&& rhs) = default;
|
||||
PipelineLayoutData& operator=(PipelineLayoutData const& rhs) = delete;
|
||||
|
||||
ccstd::pmr::map<UpdateFrequency, DescriptorSetData> descriptorSets;
|
||||
};
|
||||
|
||||
struct ShaderBindingData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptorBindings.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ShaderBindingData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ShaderBindingData(ShaderBindingData&& rhs, const allocator_type& alloc);
|
||||
|
||||
ShaderBindingData(ShaderBindingData&& rhs) noexcept = default;
|
||||
ShaderBindingData(ShaderBindingData const& rhs) = delete;
|
||||
ShaderBindingData& operator=(ShaderBindingData&& rhs) = default;
|
||||
ShaderBindingData& operator=(ShaderBindingData const& rhs) = delete;
|
||||
|
||||
PmrFlatMap<NameLocalID, uint32_t> descriptorBindings;
|
||||
};
|
||||
|
||||
struct ShaderLayoutData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {layoutData.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ShaderLayoutData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ShaderLayoutData(ShaderLayoutData&& rhs, const allocator_type& alloc);
|
||||
|
||||
ShaderLayoutData(ShaderLayoutData&& rhs) noexcept = default;
|
||||
ShaderLayoutData(ShaderLayoutData const& rhs) = delete;
|
||||
ShaderLayoutData& operator=(ShaderLayoutData&& rhs) = default;
|
||||
ShaderLayoutData& operator=(ShaderLayoutData const& rhs) = delete;
|
||||
|
||||
ccstd::pmr::map<UpdateFrequency, DescriptorSetLayoutData> layoutData;
|
||||
ccstd::pmr::map<UpdateFrequency, ShaderBindingData> bindingData;
|
||||
};
|
||||
|
||||
struct TechniqueData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {passes.get_allocator().resource()};
|
||||
}
|
||||
|
||||
TechniqueData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
TechniqueData(TechniqueData&& rhs, const allocator_type& alloc);
|
||||
|
||||
TechniqueData(TechniqueData&& rhs) noexcept = default;
|
||||
TechniqueData(TechniqueData const& rhs) = delete;
|
||||
TechniqueData& operator=(TechniqueData&& rhs) = default;
|
||||
TechniqueData& operator=(TechniqueData const& rhs) = delete;
|
||||
|
||||
ccstd::pmr::vector<ShaderLayoutData> passes;
|
||||
};
|
||||
|
||||
struct EffectData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {techniques.get_allocator().resource()};
|
||||
}
|
||||
|
||||
EffectData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
EffectData(EffectData&& rhs, const allocator_type& alloc);
|
||||
|
||||
EffectData(EffectData&& rhs) noexcept = default;
|
||||
EffectData(EffectData const& rhs) = delete;
|
||||
EffectData& operator=(EffectData&& rhs) = default;
|
||||
EffectData& operator=(EffectData const& rhs) = delete;
|
||||
|
||||
ccstd::pmr::map<ccstd::pmr::string, TechniqueData> techniques;
|
||||
};
|
||||
|
||||
struct ShaderProgramData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {layout.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ShaderProgramData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ShaderProgramData(ShaderProgramData&& rhs, const allocator_type& alloc);
|
||||
|
||||
ShaderProgramData(ShaderProgramData&& rhs) noexcept = default;
|
||||
ShaderProgramData(ShaderProgramData const& rhs) = delete;
|
||||
ShaderProgramData& operator=(ShaderProgramData&& rhs) = default;
|
||||
ShaderProgramData& operator=(ShaderProgramData const& rhs) = delete;
|
||||
|
||||
PipelineLayoutData layout;
|
||||
IntrusivePtr<gfx::PipelineLayout> pipelineLayout;
|
||||
};
|
||||
|
||||
struct RenderStageData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {descriptorVisibility.get_allocator().resource()};
|
||||
}
|
||||
|
||||
RenderStageData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
RenderStageData(RenderStageData&& rhs, const allocator_type& alloc);
|
||||
|
||||
RenderStageData(RenderStageData&& rhs) noexcept = default;
|
||||
RenderStageData(RenderStageData const& rhs) = delete;
|
||||
RenderStageData& operator=(RenderStageData&& rhs) = default;
|
||||
RenderStageData& operator=(RenderStageData const& rhs) = delete;
|
||||
|
||||
PmrUnorderedMap<NameLocalID, gfx::ShaderStageFlagBit> descriptorVisibility;
|
||||
};
|
||||
|
||||
struct RenderPhaseData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {rootSignature.get_allocator().resource()};
|
||||
}
|
||||
|
||||
RenderPhaseData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
RenderPhaseData(RenderPhaseData&& rhs, const allocator_type& alloc);
|
||||
|
||||
RenderPhaseData(RenderPhaseData&& rhs) noexcept = default;
|
||||
RenderPhaseData(RenderPhaseData const& rhs) = delete;
|
||||
RenderPhaseData& operator=(RenderPhaseData&& rhs) = default;
|
||||
RenderPhaseData& operator=(RenderPhaseData const& rhs) = delete;
|
||||
|
||||
ccstd::pmr::string rootSignature;
|
||||
ccstd::pmr::vector<ShaderProgramData> shaderPrograms;
|
||||
PmrTransparentMap<ccstd::pmr::string, uint32_t> shaderIndex;
|
||||
IntrusivePtr<gfx::PipelineLayout> pipelineLayout;
|
||||
};
|
||||
|
||||
struct LayoutGraphData {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {_vertices.get_allocator().resource()};
|
||||
}
|
||||
|
||||
inline boost::container::pmr::memory_resource* resource() const noexcept {
|
||||
return get_allocator().resource();
|
||||
}
|
||||
|
||||
LayoutGraphData(const allocator_type& alloc) noexcept; // NOLINT
|
||||
LayoutGraphData(LayoutGraphData&& rhs, const allocator_type& alloc);
|
||||
|
||||
LayoutGraphData(LayoutGraphData&& rhs) noexcept = default;
|
||||
LayoutGraphData(LayoutGraphData const& rhs) = delete;
|
||||
LayoutGraphData& operator=(LayoutGraphData&& rhs) = default;
|
||||
LayoutGraphData& operator=(LayoutGraphData const& rhs) = delete;
|
||||
|
||||
// Graph
|
||||
using directed_category = boost::bidirectional_tag;
|
||||
using vertex_descriptor = uint32_t;
|
||||
using edge_descriptor = impl::EdgeDescriptor<directed_category, vertex_descriptor>;
|
||||
using edge_parallel_category = boost::allow_parallel_edge_tag;
|
||||
struct traversal_category // NOLINT
|
||||
: virtual boost::incidence_graph_tag,
|
||||
virtual boost::bidirectional_graph_tag,
|
||||
virtual boost::adjacency_graph_tag,
|
||||
virtual boost::vertex_list_graph_tag,
|
||||
virtual boost::edge_list_graph_tag {};
|
||||
|
||||
constexpr static vertex_descriptor null_vertex() noexcept { // NOLINT
|
||||
return std::numeric_limits<vertex_descriptor>::max();
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
using OutEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using out_edge_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
using degree_size_type = uint32_t;
|
||||
|
||||
// BidirectionalGraph
|
||||
using InEdge = impl::StoredEdge<vertex_descriptor>;
|
||||
using in_edge_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, edge_descriptor, int32_t>;
|
||||
|
||||
// AdjacencyGraph
|
||||
using adjacency_iterator = boost::adjacency_iterator_generator<
|
||||
LayoutGraphData, vertex_descriptor, out_edge_iterator>::type;
|
||||
|
||||
// VertexListGraph
|
||||
using vertex_iterator = boost::integer_range<vertex_descriptor>::iterator;
|
||||
using vertices_size_type = uint32_t;
|
||||
|
||||
// VertexList help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getOutEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getInEdgeList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
inline boost::integer_range<vertex_descriptor> getVertexList() const noexcept {
|
||||
return {0, static_cast<vertices_size_type>(_vertices.size())};
|
||||
}
|
||||
|
||||
inline vertex_descriptor getCurrentID() const noexcept {
|
||||
return static_cast<vertex_descriptor>(_vertices.size());
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<boost::default_color_type> colors(boost::container::pmr::memory_resource* mr) const {
|
||||
return ccstd::pmr::vector<boost::default_color_type>(_vertices.size(), mr);
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
using edge_iterator = impl::DirectedEdgeIterator<vertex_iterator, out_edge_iterator, LayoutGraphData>;
|
||||
using edges_size_type = uint32_t;
|
||||
|
||||
// AddressableGraph (Alias)
|
||||
using ownership_descriptor = impl::EdgeDescriptor<boost::bidirectional_tag, vertex_descriptor>;
|
||||
|
||||
using ChildEdge = OutEdge;
|
||||
using children_iterator = impl::OutEdgeIter<
|
||||
ccstd::pmr::vector<OutEdge>::iterator,
|
||||
vertex_descriptor, ownership_descriptor, int32_t>;
|
||||
using children_size_type = uint32_t;
|
||||
|
||||
using ParentEdge = InEdge;
|
||||
using parent_iterator = impl::InEdgeIter<
|
||||
ccstd::pmr::vector<InEdge>::iterator,
|
||||
vertex_descriptor, ownership_descriptor, int32_t>;
|
||||
|
||||
using ownership_iterator = impl::DirectedEdgeIterator<vertex_iterator, children_iterator, LayoutGraphData>;
|
||||
using ownerships_size_type = edges_size_type;
|
||||
|
||||
// AddressableGraph help functions
|
||||
inline ccstd::pmr::vector<OutEdge>& getChildrenList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<OutEdge>& getChildrenList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].outEdges;
|
||||
}
|
||||
|
||||
inline ccstd::pmr::vector<InEdge>& getParentsList(vertex_descriptor v) noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
inline const ccstd::pmr::vector<InEdge>& getParentsList(vertex_descriptor v) const noexcept {
|
||||
return _vertices[v].inEdges;
|
||||
}
|
||||
|
||||
// PolymorphicGraph
|
||||
using VertexTag = ccstd::variant<RenderStageTag, RenderPhaseTag>;
|
||||
using VertexValue = ccstd::variant<RenderStageData*, RenderPhaseData*>;
|
||||
using VertexConstValue = ccstd::variant<const RenderStageData*, const RenderPhaseData*>;
|
||||
using VertexHandle = ccstd::variant<
|
||||
impl::ValueHandle<RenderStageTag, vertex_descriptor>,
|
||||
impl::ValueHandle<RenderPhaseTag, vertex_descriptor>>;
|
||||
|
||||
// ContinuousContainer
|
||||
void reserve(vertices_size_type sz);
|
||||
|
||||
// Members
|
||||
struct Vertex {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {outEdges.get_allocator().resource()};
|
||||
}
|
||||
|
||||
Vertex(const allocator_type& alloc) noexcept; // NOLINT
|
||||
Vertex(Vertex&& rhs, const allocator_type& alloc);
|
||||
Vertex(Vertex const& rhs, const allocator_type& alloc);
|
||||
|
||||
Vertex(Vertex&& rhs) noexcept = default;
|
||||
Vertex(Vertex const& rhs) = delete;
|
||||
Vertex& operator=(Vertex&& rhs) = default;
|
||||
Vertex& operator=(Vertex const& rhs) = default;
|
||||
|
||||
ccstd::pmr::vector<OutEdge> outEdges;
|
||||
ccstd::pmr::vector<InEdge> inEdges;
|
||||
VertexHandle handle;
|
||||
};
|
||||
|
||||
struct NameTag {};
|
||||
struct UpdateTag {};
|
||||
struct LayoutTag {};
|
||||
|
||||
// Vertices
|
||||
ccstd::pmr::vector<Vertex> _vertices;
|
||||
// Components
|
||||
ccstd::pmr::vector<ccstd::pmr::string> names;
|
||||
ccstd::pmr::vector<UpdateFrequency> updateFrequencies;
|
||||
ccstd::pmr::vector<PipelineLayoutData> layouts;
|
||||
// PolymorphicGraph
|
||||
ccstd::pmr::vector<RenderStageData> stages;
|
||||
ccstd::pmr::vector<RenderPhaseData> phases;
|
||||
// Members
|
||||
ccstd::pmr::vector<ccstd::pmr::string> valueNames;
|
||||
PmrFlatMap<ccstd::pmr::string, NameLocalID> attributeIndex;
|
||||
PmrFlatMap<ccstd::pmr::string, NameLocalID> constantIndex;
|
||||
PmrFlatMap<ccstd::pmr::string, uint32_t> shaderLayoutIndex;
|
||||
PmrFlatMap<ccstd::pmr::string, EffectData> effects;
|
||||
ccstd::string constantMacros;
|
||||
// Path
|
||||
PmrTransparentMap<ccstd::pmr::string, vertex_descriptor> pathIndex;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
inline hash_t hash<cc::render::NameLocalID>::operator()(const cc::render::NameLocalID& val) const noexcept {
|
||||
hash_t seed = 0;
|
||||
hash_combine(seed, val.value);
|
||||
return seed;
|
||||
}
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
511
cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp
Normal file
511
cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp
Normal file
@@ -0,0 +1,511 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "LayoutGraphUtils.h"
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include "LayoutGraphGraphs.h"
|
||||
#include "LayoutGraphNames.h"
|
||||
#include "LayoutGraphTypes.h"
|
||||
#include "RenderCommonNames.h"
|
||||
#include "RenderCommonTypes.h"
|
||||
#include "cocos/base/Log.h"
|
||||
#include "cocos/base/StringUtil.h"
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDef-common.h"
|
||||
#include "details/DebugUtils.h"
|
||||
#include "details/GslUtils.h"
|
||||
#include "details/Map.h"
|
||||
#include "details/Range.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace {
|
||||
|
||||
DescriptorBlockData& getDescriptorBlockData(
|
||||
PmrFlatMap<DescriptorBlockIndex, DescriptorBlockData>& map,
|
||||
const DescriptorBlockIndex& index) {
|
||||
auto iter = map.find(index);
|
||||
if (iter != map.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
iter = map.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(index),
|
||||
std::forward_as_tuple(index.descriptorType, index.visibility, 0))
|
||||
.first;
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
gfx::DescriptorType getGfxDescriptorType(DescriptorTypeOrder type) {
|
||||
switch (type) {
|
||||
case DescriptorTypeOrder::UNIFORM_BUFFER:
|
||||
return gfx::DescriptorType::UNIFORM_BUFFER;
|
||||
case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER:
|
||||
return gfx::DescriptorType::DYNAMIC_UNIFORM_BUFFER;
|
||||
case DescriptorTypeOrder::SAMPLER_TEXTURE:
|
||||
return gfx::DescriptorType::SAMPLER_TEXTURE;
|
||||
case DescriptorTypeOrder::SAMPLER:
|
||||
return gfx::DescriptorType::SAMPLER;
|
||||
case DescriptorTypeOrder::TEXTURE:
|
||||
return gfx::DescriptorType::TEXTURE;
|
||||
case DescriptorTypeOrder::STORAGE_BUFFER:
|
||||
return gfx::DescriptorType::STORAGE_BUFFER;
|
||||
case DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER:
|
||||
return gfx::DescriptorType::DYNAMIC_STORAGE_BUFFER;
|
||||
case DescriptorTypeOrder::STORAGE_IMAGE:
|
||||
return gfx::DescriptorType::STORAGE_IMAGE;
|
||||
case DescriptorTypeOrder::INPUT_ATTACHMENT:
|
||||
return gfx::DescriptorType::INPUT_ATTACHMENT;
|
||||
default:
|
||||
CC_LOG_ERROR("DescriptorType not found");
|
||||
return gfx::DescriptorType::INPUT_ATTACHMENT;
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorTypeOrder getDescriptorTypeOrder(gfx::DescriptorType type) {
|
||||
switch (type) {
|
||||
case gfx::DescriptorType::UNIFORM_BUFFER:
|
||||
return DescriptorTypeOrder::UNIFORM_BUFFER;
|
||||
case gfx::DescriptorType::DYNAMIC_UNIFORM_BUFFER:
|
||||
return DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER;
|
||||
case gfx::DescriptorType::SAMPLER_TEXTURE:
|
||||
return DescriptorTypeOrder::SAMPLER_TEXTURE;
|
||||
case gfx::DescriptorType::SAMPLER:
|
||||
return DescriptorTypeOrder::SAMPLER;
|
||||
case gfx::DescriptorType::TEXTURE:
|
||||
return DescriptorTypeOrder::TEXTURE;
|
||||
case gfx::DescriptorType::STORAGE_BUFFER:
|
||||
return DescriptorTypeOrder::STORAGE_BUFFER;
|
||||
case gfx::DescriptorType::DYNAMIC_STORAGE_BUFFER:
|
||||
return DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER;
|
||||
case gfx::DescriptorType::STORAGE_IMAGE:
|
||||
return DescriptorTypeOrder::STORAGE_IMAGE;
|
||||
case gfx::DescriptorType::INPUT_ATTACHMENT:
|
||||
return DescriptorTypeOrder::INPUT_ATTACHMENT;
|
||||
case gfx::DescriptorType::UNKNOWN:
|
||||
default:
|
||||
CC_LOG_ERROR("DescriptorTypeOrder not found");
|
||||
return DescriptorTypeOrder::INPUT_ATTACHMENT;
|
||||
}
|
||||
}
|
||||
|
||||
NameLocalID getOrCreateDescriptorID(LayoutGraphData& lg, std::string_view name) {
|
||||
auto iter = lg.attributeIndex.find(name);
|
||||
if (iter != lg.attributeIndex.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
const auto id = static_cast<uint32_t>(lg.valueNames.size());
|
||||
lg.attributeIndex.emplace(name, NameLocalID{id});
|
||||
lg.valueNames.emplace_back(name);
|
||||
return NameLocalID{id};
|
||||
}
|
||||
|
||||
void makeDescriptorSetLayoutData(
|
||||
LayoutGraphData& lg,
|
||||
UpdateFrequency rate, uint32_t set, const IDescriptorInfo& descriptors,
|
||||
DescriptorSetLayoutData& data,
|
||||
boost::container::pmr::memory_resource* scratch) {
|
||||
PmrFlatMap<DescriptorBlockIndex, DescriptorBlockData> map(scratch);
|
||||
PmrFlatMap<NameLocalID, gfx::UniformBlock> uniformBlocks(scratch);
|
||||
for (const auto& cb : descriptors.blocks) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::UNIFORM_BUFFER,
|
||||
cb.stageFlags,
|
||||
});
|
||||
|
||||
const auto nameID = getOrCreateDescriptorID(lg, cb.name);
|
||||
block.descriptors.emplace_back(nameID, gfx::Type::UNKNOWN, 1);
|
||||
// add uniform buffer
|
||||
uniformBlocks.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(nameID),
|
||||
std::forward_as_tuple(gfx::UniformBlock{set, 0xFFFFFFFF, cb.name, cb.members, 1}));
|
||||
}
|
||||
for (const auto& samplerTexture : descriptors.samplerTextures) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::SAMPLER_TEXTURE,
|
||||
samplerTexture.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, samplerTexture.name);
|
||||
block.descriptors.emplace_back(nameID, samplerTexture.type, samplerTexture.count);
|
||||
}
|
||||
for (const auto& sampler : descriptors.samplers) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::SAMPLER,
|
||||
sampler.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, sampler.name);
|
||||
block.descriptors.emplace_back(nameID, gfx::Type::SAMPLER, sampler.count);
|
||||
}
|
||||
for (const auto& texture : descriptors.textures) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::TEXTURE,
|
||||
texture.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, texture.name);
|
||||
block.descriptors.emplace_back(nameID, texture.type, texture.count);
|
||||
}
|
||||
for (const auto& buffer : descriptors.buffers) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::STORAGE_BUFFER,
|
||||
buffer.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, buffer.name);
|
||||
block.descriptors.emplace_back(nameID, gfx::Type::UNKNOWN, 1);
|
||||
}
|
||||
for (const auto& image : descriptors.images) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::STORAGE_IMAGE,
|
||||
image.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, image.name);
|
||||
block.descriptors.emplace_back(nameID, image.type, image.count);
|
||||
}
|
||||
for (const auto& subpassInput : descriptors.subpassInputs) {
|
||||
auto& block = getDescriptorBlockData(
|
||||
map, DescriptorBlockIndex{
|
||||
rate,
|
||||
ParameterType::TABLE,
|
||||
DescriptorTypeOrder::INPUT_ATTACHMENT,
|
||||
subpassInput.stageFlags,
|
||||
});
|
||||
const auto nameID = getOrCreateDescriptorID(lg, subpassInput.name);
|
||||
block.descriptors.emplace_back(nameID, gfx::Type::UNKNOWN, subpassInput.count);
|
||||
}
|
||||
|
||||
// calculate bindings
|
||||
uint32_t capacity = 0;
|
||||
for (auto&& [index, block] : map) {
|
||||
block.offset = capacity;
|
||||
for (const auto& d : block.descriptors) {
|
||||
if (index.descriptorType == DescriptorTypeOrder::UNIFORM_BUFFER) {
|
||||
// update uniform buffer binding
|
||||
auto iter = uniformBlocks.find(d.descriptorID);
|
||||
if (iter == uniformBlocks.end()) {
|
||||
CC_LOG_ERROR("Uniform block not found");
|
||||
continue;
|
||||
}
|
||||
auto& ub = iter->second;
|
||||
assert(ub.binding == 0xFFFFFFFF);
|
||||
ub.binding = block.capacity;
|
||||
// add uniform buffer to output
|
||||
data.uniformBlocks.emplace(d.descriptorID, std::move(ub));
|
||||
}
|
||||
// update block capacity
|
||||
auto iter = data.bindingMap.find(d.descriptorID);
|
||||
if (iter != data.bindingMap.end()) {
|
||||
CC_LOG_ERROR("Duplicated descriptor name: %s", lg.valueNames[d.descriptorID.value].c_str());
|
||||
continue;
|
||||
}
|
||||
data.bindingMap.emplace(d.descriptorID, block.offset + block.capacity);
|
||||
block.capacity += d.count;
|
||||
}
|
||||
// increate total capacity
|
||||
capacity += block.capacity;
|
||||
data.capacity += block.capacity;
|
||||
if (index.descriptorType == DescriptorTypeOrder::UNIFORM_BUFFER ||
|
||||
index.descriptorType == DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER) {
|
||||
data.uniformBlockCapacity += block.capacity;
|
||||
} else if (index.descriptorType == DescriptorTypeOrder::SAMPLER_TEXTURE) {
|
||||
data.samplerTextureCapacity += block.capacity;
|
||||
}
|
||||
data.descriptorBlocks.emplace_back(std::move(block));
|
||||
}
|
||||
}
|
||||
|
||||
void initializeDescriptorSetLayoutInfo(
|
||||
const DescriptorSetLayoutData& layoutData,
|
||||
gfx::DescriptorSetLayoutInfo& info) {
|
||||
for (const auto& block : layoutData.descriptorBlocks) {
|
||||
auto slot = block.offset;
|
||||
for (const auto& d : block.descriptors) {
|
||||
auto& binding = info.bindings.emplace_back();
|
||||
binding.binding = slot;
|
||||
binding.descriptorType = getGfxDescriptorType(block.type);
|
||||
binding.count = d.count;
|
||||
binding.stageFlags = block.visibility;
|
||||
binding.immutableSamplers = {};
|
||||
|
||||
// update slot
|
||||
slot += d.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const ccstd::unordered_map<ccstd::string, uint32_t> DEFAULT_UNIFORM_COUNTS{
|
||||
{"cc_lightPos", pipeline::UBOForwardLight::LIGHTS_PER_PASS},
|
||||
{"cc_lightColor", pipeline::UBOForwardLight::LIGHTS_PER_PASS},
|
||||
{"cc_lightSizeRangeAngle", pipeline::UBOForwardLight::LIGHTS_PER_PASS},
|
||||
{"cc_lightDir", pipeline::UBOForwardLight::LIGHTS_PER_PASS},
|
||||
{"cc_lightBoundingSizeVS", pipeline::UBOForwardLight::LIGHTS_PER_PASS},
|
||||
};
|
||||
|
||||
const TransparentSet<ccstd::string> DYNAMIC_UNIFORM_BLOCK{
|
||||
{"CCCamera"},
|
||||
{"CCForwardLight"},
|
||||
{"CCUILocal"},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
uint32_t getUniformBlockSize(const ccstd::vector<gfx::Uniform>& blockMembers) {
|
||||
uint32_t prevSize = 0;
|
||||
for (const auto& m : blockMembers) {
|
||||
if (m.count) {
|
||||
prevSize += getTypeSize(m.type) * m.count;
|
||||
continue;
|
||||
}
|
||||
auto iter = DEFAULT_UNIFORM_COUNTS.find(m.name);
|
||||
if (iter != DEFAULT_UNIFORM_COUNTS.end()) {
|
||||
prevSize += getTypeSize(m.type) * iter->second;
|
||||
continue;
|
||||
}
|
||||
if (m.name == "cc_joints") {
|
||||
const auto sz = getTypeSize(m.type) * pipeline::UBOSkinning::layout.members[0].count;
|
||||
CC_EXPECTS(sz == pipeline::UBOSkinning::size);
|
||||
prevSize += sz;
|
||||
continue;
|
||||
}
|
||||
CC_LOG_ERROR("Invalid uniform count: %s", m.name.c_str());
|
||||
}
|
||||
CC_ENSURES(prevSize);
|
||||
return prevSize;
|
||||
}
|
||||
|
||||
bool isDynamicUniformBlock(std::string_view name) {
|
||||
return DYNAMIC_UNIFORM_BLOCK.find(name) != DYNAMIC_UNIFORM_BLOCK.end();
|
||||
}
|
||||
|
||||
gfx::DescriptorSet* getOrCreatePerPassDescriptorSet(
|
||||
gfx::Device* device,
|
||||
LayoutGraphData& lg, LayoutGraphData::vertex_descriptor vertID) {
|
||||
auto& ppl = get(LayoutGraphData::LayoutTag{}, lg, vertID);
|
||||
auto iter = ppl.descriptorSets.find(UpdateFrequency::PER_PASS);
|
||||
if (iter == ppl.descriptorSets.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto& data = iter->second;
|
||||
if (!data.descriptorSet) {
|
||||
if (!data.descriptorSetLayout) {
|
||||
data.descriptorSetLayout = device->createDescriptorSetLayout(data.descriptorSetLayoutInfo);
|
||||
}
|
||||
CC_ENSURES(data.descriptorSetLayout);
|
||||
data.descriptorSet = device->createDescriptorSet(gfx::DescriptorSetInfo{data.descriptorSetLayout.get()});
|
||||
}
|
||||
CC_ENSURES(data.descriptorSet);
|
||||
return data.descriptorSet;
|
||||
}
|
||||
|
||||
void generateConstantMacros(
|
||||
gfx::Device* device,
|
||||
ccstd::string& constantMacros) {
|
||||
constantMacros = StringUtil::format(
|
||||
R"(
|
||||
#define CC_DEVICE_SUPPORT_FLOAT_TEXTURE %d
|
||||
#define CC_DEVICE_MAX_VERTEX_UNIFORM_VECTORS %d
|
||||
#define CC_DEVICE_MAX_FRAGMENT_UNIFORM_VECTORS %d
|
||||
#define CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT %d
|
||||
#define CC_PLATFORM_ANDROID_AND_WEBGL 0
|
||||
#define CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES 0
|
||||
#define CC_JOINT_UNIFORM_CAPACITY %d
|
||||
)",
|
||||
hasAnyFlags(device->getFormatFeatures(gfx::Format::RGBA32F),
|
||||
gfx::FormatFeature::RENDER_TARGET | gfx::FormatFeature::SAMPLED_TEXTURE),
|
||||
device->getCapabilities().maxVertexUniformVectors,
|
||||
device->getCapabilities().maxFragmentUniformVectors,
|
||||
device->hasFeature(gfx::Feature::INPUT_ATTACHMENT_BENEFIT),
|
||||
pipeline::SkinningJointCapacity::jointUniformCapacity);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
ccstd::string getName(gfx::ShaderStageFlagBit stage) {
|
||||
std::ostringstream oss;
|
||||
int count = 0;
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::VERTEX)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Vertex";
|
||||
}
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::CONTROL)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Control";
|
||||
}
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::EVALUATION)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Evaluation";
|
||||
}
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::GEOMETRY)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Geometry";
|
||||
}
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::FRAGMENT)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Fragment";
|
||||
}
|
||||
if (hasFlag(stage, gfx::ShaderStageFlagBit::COMPUTE)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "Compute";
|
||||
}
|
||||
if (hasAllFlags(stage, gfx::ShaderStageFlagBit::ALL)) {
|
||||
if (count++) {
|
||||
oss << " | ";
|
||||
}
|
||||
oss << "All";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void printLayoutGraphData(
|
||||
const LayoutGraphData& lg, std::ostream& oss,
|
||||
boost::container::pmr::memory_resource* scratch) {
|
||||
ccstd::pmr::string space(scratch);
|
||||
|
||||
oss << "\n";
|
||||
|
||||
for (const auto v : makeRange(vertices(lg))) {
|
||||
if (parent(v, lg) != LayoutGraphData::null_vertex()) {
|
||||
continue;
|
||||
}
|
||||
const auto& name = get(LayoutGraphData::NameTag{}, lg, v);
|
||||
OSS << "\"" << name << "\": ";
|
||||
|
||||
visit(
|
||||
[&](auto tag) {
|
||||
oss << getName(tag);
|
||||
},
|
||||
tag(v, lg));
|
||||
|
||||
oss << " {\n";
|
||||
INDENT_BEG();
|
||||
const auto& info = get(LayoutGraphData::LayoutTag{}, lg, v);
|
||||
for (const auto& set : info.descriptorSets) {
|
||||
OSS << "Set<" << getName(set.first) << "> {\n";
|
||||
{
|
||||
INDENT();
|
||||
for (const auto& block : set.second.descriptorSetLayoutData.descriptorBlocks) {
|
||||
OSS << "Block<" << getName(block.type) << ", " << getName(block.visibility) << "> {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "capacity: " << block.capacity << ",\n";
|
||||
OSS << "count: " << block.descriptors.size() << ",\n";
|
||||
if (!block.descriptors.empty()) {
|
||||
OSS << "Descriptors{ ";
|
||||
int count = 0;
|
||||
for (const auto& d : block.descriptors) {
|
||||
if (count++) {
|
||||
oss << ", ";
|
||||
}
|
||||
const auto& name = lg.valueNames.at(d.descriptorID.value);
|
||||
oss << "\"" << name;
|
||||
if (d.count != 1) {
|
||||
oss << "[" << d.count << "]";
|
||||
}
|
||||
oss << "\"";
|
||||
}
|
||||
oss << " }\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
INDENT_END();
|
||||
OSS << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
gfx::TextureType getTextureType(ResourceDimension dimension, uint32_t arraySize) {
|
||||
switch (dimension) {
|
||||
case ResourceDimension::TEXTURE1D:
|
||||
return arraySize > 1 ? gfx::TextureType::TEX1D_ARRAY : gfx::TextureType::TEX1D;
|
||||
case ResourceDimension::TEXTURE2D:
|
||||
return arraySize > 1 ? gfx::TextureType::TEX2D_ARRAY : gfx::TextureType::TEX2D;
|
||||
case ResourceDimension::TEXTURE3D:
|
||||
return gfx::TextureType::TEX3D;
|
||||
case ResourceDimension::BUFFER:
|
||||
default:
|
||||
return gfx::TextureType::TEX2D;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceDimension getResourceDimension(gfx::TextureType type) {
|
||||
switch (type) {
|
||||
case gfx::TextureType::TEX1D:
|
||||
case gfx::TextureType::TEX1D_ARRAY:
|
||||
return ResourceDimension::TEXTURE1D;
|
||||
case gfx::TextureType::TEX3D:
|
||||
return ResourceDimension::TEXTURE3D;
|
||||
case gfx::TextureType::TEX2D:
|
||||
case gfx::TextureType::TEX2D_ARRAY:
|
||||
case gfx::TextureType::CUBE:
|
||||
default:
|
||||
return ResourceDimension::TEXTURE2D;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
74
cocos/renderer/pipeline/custom/LayoutGraphUtils.h
Normal file
74
cocos/renderer/pipeline/custom/LayoutGraphUtils.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <iosfwd>
|
||||
#include "cocos/core/assets/EffectAsset.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonTypes.h"
|
||||
#include "gfx-base/GFXDevice.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
gfx::DescriptorType getGfxDescriptorType(DescriptorTypeOrder type);
|
||||
DescriptorTypeOrder getDescriptorTypeOrder(gfx::DescriptorType type);
|
||||
|
||||
NameLocalID getOrCreateDescriptorID(LayoutGraphData& lg, std::string_view name);
|
||||
|
||||
void makeDescriptorSetLayoutData(
|
||||
LayoutGraphData& lg,
|
||||
UpdateFrequency rate, uint32_t set, const IDescriptorInfo& descriptors,
|
||||
DescriptorSetLayoutData& data,
|
||||
boost::container::pmr::memory_resource* scratch);
|
||||
|
||||
void initializeDescriptorSetLayoutInfo(
|
||||
const DescriptorSetLayoutData& layoutData,
|
||||
gfx::DescriptorSetLayoutInfo& info);
|
||||
|
||||
uint32_t getUniformBlockSize(const ccstd::vector<gfx::Uniform>& blockMembers);
|
||||
|
||||
bool isDynamicUniformBlock(std::string_view name);
|
||||
|
||||
gfx::DescriptorSet* getOrCreatePerPassDescriptorSet(
|
||||
gfx::Device* device,
|
||||
LayoutGraphData& lg, LayoutGraphData::vertex_descriptor vertID);
|
||||
|
||||
void generateConstantMacros(
|
||||
gfx::Device* device,
|
||||
ccstd::string& constantMacros);
|
||||
|
||||
void printLayoutGraphData(
|
||||
const LayoutGraphData& lg, std::ostream& oss,
|
||||
boost::container::pmr::memory_resource* scratch);
|
||||
|
||||
gfx::TextureType getTextureType(ResourceDimension dimension, uint32_t arraySize);
|
||||
ResourceDimension getResourceDimension(gfx::TextureType type);
|
||||
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
900
cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp
Normal file
900
cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp
Normal file
@@ -0,0 +1,900 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NativeBuiltinUtils.h"
|
||||
#include "cocos/application/ApplicationManager.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDef-common.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDevice.h"
|
||||
#include "cocos/renderer/pipeline/Define.h"
|
||||
#include "cocos/renderer/pipeline/PipelineSceneData.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
#include "cocos/scene/Camera.h"
|
||||
#include "cocos/scene/DirectionalLight.h"
|
||||
#include "cocos/scene/Fog.h"
|
||||
#include "cocos/scene/Shadow.h"
|
||||
#include "cocos/scene/Skybox.h"
|
||||
#include "cocos/scene/SpotLight.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]) {
|
||||
const float minX = viewport.x;
|
||||
const float maxX = viewport.x + viewport.z;
|
||||
float minY = viewport.y;
|
||||
float maxY = viewport.y + viewport.w;
|
||||
if (device.getCapabilities().screenSpaceSignY > 0) {
|
||||
std::swap(minY, maxY);
|
||||
}
|
||||
int n = 0;
|
||||
vbData[n++] = -1.0F;
|
||||
vbData[n++] = -1.0F;
|
||||
vbData[n++] = minX; // uv
|
||||
vbData[n++] = maxY;
|
||||
vbData[n++] = 1.0F;
|
||||
vbData[n++] = -1.0F;
|
||||
vbData[n++] = maxX;
|
||||
vbData[n++] = maxY;
|
||||
vbData[n++] = -1.0F;
|
||||
vbData[n++] = 1.0F;
|
||||
vbData[n++] = minX;
|
||||
vbData[n++] = minY;
|
||||
vbData[n++] = 1.0F;
|
||||
vbData[n++] = 1.0F;
|
||||
vbData[n++] = maxX;
|
||||
vbData[n++] = minY;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
||||
void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter) {
|
||||
const auto &root = *Root::getInstance();
|
||||
const auto shadingWidth = static_cast<float>(width);
|
||||
const auto shadingHeight = static_cast<float>(height);
|
||||
setter.setVec4(
|
||||
"cc_time",
|
||||
Vec4(
|
||||
root.getCumulativeTime(),
|
||||
root.getFrameTime(),
|
||||
static_cast<float>(CC_CURRENT_ENGINE()->getTotalFrames()),
|
||||
0.0F));
|
||||
|
||||
setter.setVec4(
|
||||
"cc_screenSize",
|
||||
Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight));
|
||||
setter.setVec4(
|
||||
"cc_nativeSize",
|
||||
Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight));
|
||||
|
||||
const auto *debugView = root.getDebugView();
|
||||
float debugViewData[4] = {0.0F, 0.0F, 0.0F, 0.0F};
|
||||
if (debugView && debugView->isEnabled()) {
|
||||
debugViewData[0] = static_cast<float>(debugView->getSingleMode());
|
||||
for (auto i = static_cast<uint32_t>(pipeline::DebugViewCompositeType::DIRECT_DIFFUSE);
|
||||
i < static_cast<uint32_t>(pipeline::DebugViewCompositeType::MAX_BIT_COUNT); ++i) {
|
||||
const uint32_t offset = i >> 3;
|
||||
const uint32_t bit = i % 8;
|
||||
debugViewData[1 + offset] += (debugView->isCompositeModeEnabled(i) ? 1.0F : 0.0F) * powf(10.0F, static_cast<float>(bit));
|
||||
}
|
||||
debugViewData[3] += (debugView->isLightingWithAlbedo() ? 1.0F : 0.0F) * powf(10.0F, static_cast<float>(6));
|
||||
debugViewData[3] += (debugView->isCsmLayerColoration() ? 1.0F : 0.0F) * powf(10.0F, static_cast<float>(7));
|
||||
}
|
||||
setter.setVec4(
|
||||
"cc_debug_view_mode",
|
||||
Vec4(debugViewData[0], debugViewData[1], debugViewData[2], debugViewData[3]));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
uint8_t getCombineSignY(gfx::Device *device) {
|
||||
// 0: vk, 1: metal, 2: none, 3: gl-like
|
||||
static int8_t combineSignY{-1};
|
||||
if (combineSignY < 0) {
|
||||
const float screenSpaceSignY = device->getCapabilities().screenSpaceSignY * 0.5F + 0.5F;
|
||||
const float clipSpaceSignY = device->getCapabilities().clipSpaceSignY * 0.5F + 0.5F;
|
||||
combineSignY = static_cast<int8_t>(static_cast<int>(screenSpaceSignY) << 1 | static_cast<int>(clipSpaceSignY));
|
||||
}
|
||||
return static_cast<uint8_t>(combineSignY);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setCameraUBOValues(
|
||||
const scene::Camera &camera,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &cfg,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
RenderData &data) {
|
||||
CC_EXPECTS(camera.getNode());
|
||||
CC_EXPECTS(cfg.getSkybox());
|
||||
const auto &skybox = *cfg.getSkybox();
|
||||
const auto &shadingScale = cfg.getShadingScale();
|
||||
// Camera
|
||||
setMat4Impl(data, layoutGraph, "cc_matView", camera.getMatView());
|
||||
setMat4Impl(data, layoutGraph, "cc_matViewInv", camera.getNode()->getWorldMatrix());
|
||||
setMat4Impl(data, layoutGraph, "cc_matProj", camera.getMatProj());
|
||||
setMat4Impl(data, layoutGraph, "cc_matProjInv", camera.getMatProjInv());
|
||||
setMat4Impl(data, layoutGraph, "cc_matViewProj", camera.getMatViewProj());
|
||||
setMat4Impl(data, layoutGraph, "cc_matViewProjInv", camera.getMatViewProjInv());
|
||||
setVec4Impl(data, layoutGraph, "cc_cameraPos",
|
||||
Vec4(
|
||||
camera.getPosition().x,
|
||||
camera.getPosition().y,
|
||||
camera.getPosition().z,
|
||||
getCombineSignY(cc::gfx::Device::getInstance())));
|
||||
setVec4Impl(data, layoutGraph, "cc_surfaceTransform",
|
||||
Vec4(
|
||||
static_cast<float>(camera.getSurfaceTransform()),
|
||||
static_cast<float>(camera.getCameraUsage()),
|
||||
cosf(static_cast<float>(mathutils::toRadian(skybox.getRotationAngle()))),
|
||||
sinf(static_cast<float>(mathutils::toRadian(skybox.getRotationAngle())))));
|
||||
setVec4Impl(data, layoutGraph, "cc_screenScale",
|
||||
Vec4(
|
||||
cfg.getShadingScale(),
|
||||
cfg.getShadingScale(),
|
||||
1.0F / cfg.getShadingScale(),
|
||||
1.0F / cfg.getShadingScale()));
|
||||
setVec4Impl(data, layoutGraph, "cc_exposure",
|
||||
Vec4(
|
||||
camera.getExposure(),
|
||||
1.0F / camera.getExposure(),
|
||||
cfg.isHDR() ? 1.0F : 0.0F,
|
||||
1.0F / scene::Camera::getStandardExposureValue()));
|
||||
|
||||
if (mainLight) {
|
||||
const auto &shadowInfo = *cfg.getShadows();
|
||||
const bool shadowEnable = (mainLight->isShadowEnabled() &&
|
||||
shadowInfo.getType() == scene::ShadowType::SHADOW_MAP);
|
||||
setVec4Impl(data, layoutGraph, "cc_mainLitDir",
|
||||
Vec4(
|
||||
mainLight->getDirection().x,
|
||||
mainLight->getDirection().y,
|
||||
mainLight->getDirection().z,
|
||||
shadowEnable));
|
||||
auto r = mainLight->getColor().x;
|
||||
auto g = mainLight->getColor().y;
|
||||
auto b = mainLight->getColor().z;
|
||||
if (mainLight->isUseColorTemperature()) {
|
||||
r *= mainLight->getColorTemperatureRGB().x;
|
||||
g *= mainLight->getColorTemperatureRGB().y;
|
||||
b *= mainLight->getColorTemperatureRGB().z;
|
||||
}
|
||||
auto w = mainLight->getIlluminance();
|
||||
if (cfg.isHDR()) {
|
||||
w *= camera.getExposure();
|
||||
}
|
||||
setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(r, g, b, w));
|
||||
} else {
|
||||
setVec4Impl(data, layoutGraph, "cc_mainLitDir", Vec4(0, 0, 1, 0));
|
||||
setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
CC_EXPECTS(cfg.getAmbient());
|
||||
auto &ambient = *cfg.getAmbient();
|
||||
auto &skyColor = ambient.getSkyColor();
|
||||
if (cfg.isHDR()) {
|
||||
skyColor.w = ambient.getSkyIllum() * camera.getExposure();
|
||||
} else {
|
||||
skyColor.w = ambient.getSkyIllum();
|
||||
}
|
||||
setVec4Impl(data, layoutGraph, "cc_ambientSky",
|
||||
Vec4(skyColor.x, skyColor.y, skyColor.z, skyColor.w));
|
||||
setVec4Impl(data, layoutGraph, "cc_ambientGround",
|
||||
Vec4(
|
||||
ambient.getGroundAlbedo().x,
|
||||
ambient.getGroundAlbedo().y,
|
||||
ambient.getGroundAlbedo().z,
|
||||
skybox.getEnvmap() ? static_cast<float>(skybox.getEnvmap()->mipmapLevel()) : 1.0F));
|
||||
|
||||
CC_EXPECTS(cfg.getFog());
|
||||
const auto &fog = *cfg.getFog();
|
||||
|
||||
const auto &colorTempRGB = fog.getColorArray();
|
||||
setVec4Impl(data, layoutGraph, "cc_fogColor",
|
||||
Vec4(colorTempRGB.x, colorTempRGB.y, colorTempRGB.z, colorTempRGB.z));
|
||||
setVec4Impl(data, layoutGraph, "cc_fogBase",
|
||||
Vec4(fog.getFogStart(), fog.getFogEnd(), fog.getFogDensity(), 0.0F));
|
||||
setVec4Impl(data, layoutGraph, "cc_fogAdd",
|
||||
Vec4(fog.getFogTop(), fog.getFogRange(), fog.getFogAtten(), 0.0F));
|
||||
setVec4Impl(data, layoutGraph, "cc_nearFar",
|
||||
Vec4(camera.getNearClip(), camera.getFarClip(), camera.getClipSpaceMinz(), 0.0F));
|
||||
setVec4Impl(data, layoutGraph, "cc_viewPort",
|
||||
Vec4(
|
||||
camera.getViewport().x,
|
||||
camera.getViewport().y,
|
||||
shadingScale * static_cast<float>(camera.getWindow()->getWidth()) * camera.getViewport().z,
|
||||
shadingScale * static_cast<float>(camera.getWindow()->getHeight()) * camera.getViewport().w));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
float getPCFRadius(
|
||||
const scene::Shadows &shadowInfo,
|
||||
const scene::DirectionalLight &mainLight) {
|
||||
const auto &shadowMapSize = shadowInfo.getSize().x;
|
||||
switch (mainLight.getShadowPcf()) {
|
||||
case scene::PCFType::HARD:
|
||||
return 0.0F;
|
||||
case scene::PCFType::SOFT:
|
||||
return 1.0F / (shadowMapSize * 0.5F);
|
||||
case scene::PCFType::SOFT_2X:
|
||||
return 2.0F / (shadowMapSize * 0.5F);
|
||||
case scene::PCFType::SOFT_4X:
|
||||
return 3.0F / (shadowMapSize * 0.5F);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setShadowUBOView(
|
||||
gfx::Device &device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &pplSceneData,
|
||||
const scene::DirectionalLight &mainLight,
|
||||
RenderData &data) {
|
||||
const auto &shadowInfo = *pplSceneData.getShadows();
|
||||
const auto &csmLayers = *pplSceneData.getCSMLayers();
|
||||
const auto &csmSupported = pplSceneData.getCSMSupported();
|
||||
const auto &packing = pipeline::supportsR32FloatTexture(&device) ? 0.0F : 1.0F;
|
||||
Vec4 vec4ShadowInfo{};
|
||||
if (shadowInfo.isEnabled()) {
|
||||
if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) {
|
||||
if (mainLight.isShadowEnabled()) {
|
||||
if (mainLight.isShadowFixedArea() ||
|
||||
mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1 || !csmSupported) {
|
||||
// Shadow
|
||||
const auto &matShadowView = csmLayers.getSpecialLayer()->getMatShadowView();
|
||||
const auto &matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj();
|
||||
const auto &matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj();
|
||||
const auto &near = mainLight.getShadowNear();
|
||||
const auto &far = mainLight.getShadowFar();
|
||||
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo",
|
||||
Vec4(matShadowProj.m[10], matShadowProj.m[14],
|
||||
matShadowProj.m[11], matShadowProj.m[15]));
|
||||
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowProjInfo",
|
||||
Vec4(matShadowProj.m[00], matShadowProj.m[05],
|
||||
1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05]));
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj);
|
||||
vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo);
|
||||
vec4ShadowInfo.set(static_cast<float>(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo);
|
||||
} else {
|
||||
{ // CSM
|
||||
const auto layerThreshold = getPCFRadius(shadowInfo, mainLight);
|
||||
const auto numCascades = static_cast<uint32_t>(mainLight.getCSMLevel());
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir0", numCascades);
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir1", numCascades);
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir2", numCascades);
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmAtlas", numCascades);
|
||||
setMat4ArraySizeImpl(data, layoutGraph, "cc_matCSMViewProj", numCascades);
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjDepthInfo", numCascades);
|
||||
setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjInfo", numCascades);
|
||||
|
||||
Vec4 csmSplitsInfo{};
|
||||
for (uint32_t i = 0; i < numCascades; ++i) {
|
||||
const auto &layer = *csmLayers.getLayers()[i];
|
||||
|
||||
const auto &matShadowView = layer.getMatShadowView();
|
||||
vec4ShadowInfo.set(matShadowView.m[0], matShadowView.m[4], matShadowView.m[8], layerThreshold);
|
||||
setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir0", vec4ShadowInfo, i);
|
||||
vec4ShadowInfo.set(matShadowView.m[1], matShadowView.m[5], matShadowView.m[9], layer.getSplitCameraNear());
|
||||
setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir1", vec4ShadowInfo, i);
|
||||
vec4ShadowInfo.set(matShadowView.m[2], matShadowView.m[6], matShadowView.m[10], layer.getSplitCameraFar());
|
||||
setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir2", vec4ShadowInfo, i);
|
||||
|
||||
const auto &csmAtlas = layer.getCSMAtlas();
|
||||
setVec4ArrayElemImpl(data, layoutGraph, "cc_csmAtlas", csmAtlas, i);
|
||||
|
||||
const auto &matShadowViewProj = layer.getMatShadowViewProj();
|
||||
setMat4ArrayElemImpl(data, layoutGraph, "cc_matCSMViewProj", matShadowViewProj, i);
|
||||
|
||||
const auto &matShadowProj = layer.getMatShadowProj();
|
||||
setVec4ArrayElemImpl(data, layoutGraph,
|
||||
"cc_csmProjDepthInfo",
|
||||
Vec4(matShadowProj.m[10], matShadowProj.m[14],
|
||||
matShadowProj.m[11], matShadowProj.m[15]),
|
||||
i);
|
||||
|
||||
setVec4ArrayElemImpl(data, layoutGraph,
|
||||
"cc_csmProjInfo",
|
||||
Vec4(matShadowProj.m[00], matShadowProj.m[05],
|
||||
1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05]),
|
||||
i);
|
||||
|
||||
(&csmSplitsInfo.x)[i] = layer.getSplitCameraFar() / mainLight.getShadowDistance();
|
||||
}
|
||||
setVec4Impl(data, layoutGraph, "cc_csmSplitsInfo", csmSplitsInfo);
|
||||
}
|
||||
{ // Shadow
|
||||
vec4ShadowInfo.set(0, 0, 0, 1.0F - mainLight.getShadowSaturation());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo);
|
||||
vec4ShadowInfo.set(
|
||||
static_cast<float>(scene::LightType::DIRECTIONAL),
|
||||
packing,
|
||||
mainLight.getShadowNormalBias(),
|
||||
static_cast<float>(mainLight.getCSMLevel()));
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo);
|
||||
}
|
||||
}
|
||||
{ // Shadow
|
||||
vec4ShadowInfo.set(
|
||||
shadowInfo.getSize().x, shadowInfo.getSize().y,
|
||||
static_cast<float>(mainLight.getShadowPcf()), mainLight.getShadowBias());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const Vec3 tempVec3 = shadowInfo.getNormal().getNormalized();
|
||||
setVec4Impl(data, layoutGraph,
|
||||
"cc_planarNDInfo",
|
||||
Vec4(tempVec3.x, tempVec3.y, tempVec3.z, -shadowInfo.getDistance()));
|
||||
vec4ShadowInfo.set(
|
||||
0, 0,
|
||||
0, shadowInfo.getPlaneBias());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo);
|
||||
}
|
||||
{
|
||||
const auto &color = shadowInfo.getShadowColor4f();
|
||||
setColorImpl(data, layoutGraph, "cc_shadowColor",
|
||||
gfx::Color{color[0], color[1], color[2], color[3]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setShadowUBOLightView(
|
||||
gfx::Device *device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &pplSceneData,
|
||||
const BuiltinCascadedShadowMap *csm,
|
||||
const scene::Light &light,
|
||||
uint32_t level,
|
||||
RenderData &data) {
|
||||
const auto &shadowInfo = *pplSceneData.getShadows();
|
||||
const auto &packing = pipeline::supportsR32FloatTexture(device) ? 0.0F : 1.0F;
|
||||
const auto &cap = device->getCapabilities();
|
||||
Vec4 vec4ShadowInfo{};
|
||||
|
||||
// ShadowMap
|
||||
switch (light.getType()) {
|
||||
case scene::LightType::DIRECTIONAL: {
|
||||
const auto &mainLight = dynamic_cast<const scene::DirectionalLight &>(light);
|
||||
if (shadowInfo.isEnabled() && mainLight.isShadowEnabled()) {
|
||||
if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) {
|
||||
float near = 0.1F;
|
||||
float far = 0.0F;
|
||||
Mat4 matShadowView;
|
||||
Mat4 matShadowProj;
|
||||
Mat4 matShadowViewProj;
|
||||
scene::CSMLevel levelCount{};
|
||||
CC_EXPECTS(csm);
|
||||
if (mainLight.isShadowFixedArea() || mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1) {
|
||||
matShadowView = csm->specialLayer.shadowView;
|
||||
matShadowProj = csm->specialLayer.shadowProj;
|
||||
matShadowViewProj = csm->specialLayer.shadowViewProj;
|
||||
if (mainLight.isShadowFixedArea()) {
|
||||
near = mainLight.getShadowNear();
|
||||
far = mainLight.getShadowFar();
|
||||
levelCount = static_cast<scene::CSMLevel>(0);
|
||||
} else {
|
||||
near = 0.1F;
|
||||
far = csm->specialLayer.shadowCameraFar;
|
||||
levelCount = scene::CSMLevel::LEVEL_1;
|
||||
}
|
||||
vec4ShadowInfo.set(static_cast<float>(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo);
|
||||
} else {
|
||||
CC_EXPECTS(level < csm->layers.size());
|
||||
const auto &layer = csm->layers[level];
|
||||
matShadowView = layer.shadowView;
|
||||
matShadowProj = layer.shadowProj;
|
||||
matShadowViewProj = layer.shadowViewProj;
|
||||
|
||||
near = layer.splitCameraNear;
|
||||
far = layer.splitCameraFar;
|
||||
levelCount = mainLight.getCSMLevel();
|
||||
}
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo",
|
||||
Vec4(
|
||||
matShadowProj.m[10],
|
||||
matShadowProj.m[14],
|
||||
matShadowProj.m[11],
|
||||
matShadowProj.m[15]));
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowProjInfo",
|
||||
Vec4(
|
||||
matShadowProj.m[00],
|
||||
matShadowProj.m[05],
|
||||
1.0F / matShadowProj.m[00],
|
||||
1.0F / matShadowProj.m[05]));
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj);
|
||||
vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo);
|
||||
vec4ShadowInfo.set(
|
||||
static_cast<float>(scene::LightType::DIRECTIONAL),
|
||||
packing,
|
||||
mainLight.getShadowNormalBias(),
|
||||
static_cast<float>(levelCount));
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo);
|
||||
vec4ShadowInfo.set(
|
||||
shadowInfo.getSize().x,
|
||||
shadowInfo.getSize().y,
|
||||
static_cast<float>(mainLight.getShadowPcf()),
|
||||
mainLight.getShadowBias());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case scene::LightType::SPOT: {
|
||||
const auto &spotLight = dynamic_cast<const scene::SpotLight &>(light);
|
||||
if (shadowInfo.isEnabled() && spotLight.isShadowEnabled()) {
|
||||
const auto &matShadowCamera = spotLight.getNode()->getWorldMatrix();
|
||||
const auto matShadowView = matShadowCamera.getInversed();
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView);
|
||||
|
||||
Mat4 matShadowViewProj{};
|
||||
Mat4::createPerspective(spotLight.getAngle(), 1.0F, 0.001F,
|
||||
spotLight.getRange(), true,
|
||||
cap.clipSpaceMinZ, cap.clipSpaceSignY, 0, &matShadowViewProj);
|
||||
matShadowViewProj.multiply(matShadowView);
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj);
|
||||
|
||||
const Vec4 shadowNFLSInfos(0.01F, spotLight.getRange(), 0.0F, 0.0F);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", shadowNFLSInfos);
|
||||
|
||||
const Vec4 shadowWHPBInfos(
|
||||
shadowInfo.getSize().x,
|
||||
shadowInfo.getSize().y,
|
||||
spotLight.getShadowPcf(),
|
||||
spotLight.getShadowBias());
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", shadowWHPBInfos);
|
||||
|
||||
const Vec4 shadowLPNNInfos(static_cast<float>(scene::LightType::SPOT), packing, spotLight.getShadowNormalBias(), 0.0F);
|
||||
setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", shadowLPNNInfos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const auto &color = shadowInfo.getShadowColor4f();
|
||||
setColorImpl(data, layoutGraph, "cc_shadowColor", gfx::Color{color[0], color[1], color[2], color[3]});
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void updatePlanarNormalAndDistance(
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const scene::Shadows &shadowInfo,
|
||||
RenderData &data) {
|
||||
const Vec3 normal = shadowInfo.getNormal().getNormalized();
|
||||
const Vec4 planarNDInfo{normal.x, normal.y, normal.z, -shadowInfo.getDistance()};
|
||||
setVec4Impl(data, layoutGraph, "cc_planarNDInfo", planarNDInfo);
|
||||
}
|
||||
|
||||
std::tuple<Mat4, Mat4, Mat4, Mat4>
|
||||
computeShadowMatrices(
|
||||
const gfx::DeviceCaps &cap,
|
||||
const Mat4 &matShadowCamera,
|
||||
float fov, float farPlane) {
|
||||
auto matShadowView = matShadowCamera.getInversed();
|
||||
|
||||
Mat4 matShadowProj;
|
||||
Mat4::createPerspective(
|
||||
fov, 1.0F, 0.001F, farPlane,
|
||||
true, cap.clipSpaceMinZ, cap.clipSpaceSignY,
|
||||
0, &matShadowProj);
|
||||
|
||||
Mat4 matShadowViewProj = matShadowProj;
|
||||
Mat4 matShadowInvProj = matShadowProj;
|
||||
|
||||
matShadowInvProj.inverse();
|
||||
matShadowViewProj.multiply(matShadowView);
|
||||
|
||||
return {matShadowView, matShadowViewProj, matShadowProj, matShadowInvProj};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setPunctualLightShadowUBO(
|
||||
gfx::Device *device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &pplSceneData,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
const scene::Light &light,
|
||||
RenderData &data) {
|
||||
const auto &shadowInfo = *pplSceneData.getShadows();
|
||||
const auto &packing = pipeline::supportsR32FloatTexture(device) ? 0.0F : 1.0F;
|
||||
const auto &cap = device->getCapabilities();
|
||||
Vec4 vec4ShadowInfo{};
|
||||
|
||||
if (mainLight) {
|
||||
// update planar PROJ
|
||||
updatePlanarNormalAndDistance(layoutGraph, shadowInfo, data);
|
||||
}
|
||||
|
||||
// ShadowMap
|
||||
switch (light.getType()) {
|
||||
case scene::LightType::DIRECTIONAL:
|
||||
// noop
|
||||
break;
|
||||
case scene::LightType::SPHERE: {
|
||||
const auto &shadowSize = shadowInfo.getSize();
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowWHPBInfo",
|
||||
Vec4{shadowSize.x, shadowSize.y, 1.0F, 0.0F});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowLPNNInfo",
|
||||
Vec4{static_cast<float>(scene::LightType::SPHERE), packing, 0.0F, 0.0F});
|
||||
} break;
|
||||
case scene::LightType::SPOT: {
|
||||
const auto &shadowSize = shadowInfo.getSize();
|
||||
const auto &spotLight = dynamic_cast<const scene::SpotLight &>(light);
|
||||
const auto &matShadowCamera = spotLight.getNode()->getWorldMatrix();
|
||||
const auto [matShadowView, matShadowViewProj, matShadowProj, matShadowInvProj] =
|
||||
computeShadowMatrices(cap, matShadowCamera, spotLight.getAngle(), spotLight.getRange());
|
||||
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView);
|
||||
setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj);
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowNFLSInfo",
|
||||
Vec4{0.1F, spotLight.getRange(), 0.0F, 0.0F});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowWHPBInfo",
|
||||
Vec4{shadowSize.x, shadowSize.y, spotLight.getShadowPcf(), spotLight.getShadowBias()});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowLPNNInfo",
|
||||
Vec4{static_cast<float>(scene::LightType::SPOT), packing, spotLight.getShadowNormalBias(), 0.0F});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowInvProjDepthInfo",
|
||||
Vec4{matShadowInvProj.m[10], matShadowInvProj.m[14], matShadowInvProj.m[11], matShadowInvProj.m[15]});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowProjDepthInfo",
|
||||
Vec4{matShadowProj.m[10], matShadowProj.m[14], matShadowProj.m[11], matShadowProj.m[15]});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowProjInfo",
|
||||
Vec4{matShadowProj.m[00], matShadowProj.m[05], 1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05]});
|
||||
} break;
|
||||
case scene::LightType::POINT: {
|
||||
const auto &shadowSize = shadowInfo.getSize();
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowWHPBInfo",
|
||||
Vec4{shadowSize.x, shadowSize.y, 1.0F, 0.0F});
|
||||
setVec4Impl(
|
||||
data, layoutGraph, "cc_shadowLPNNInfo",
|
||||
Vec4{static_cast<float>(scene::LightType::POINT), packing, 0.0F, 0.0F});
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setLegacyTextureUBOView(
|
||||
gfx::Device &device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &pplSceneData,
|
||||
RenderData &data) {
|
||||
const auto &skybox = *pplSceneData.getSkybox();
|
||||
if (skybox.getReflectionMap()) {
|
||||
auto &texture = *skybox.getReflectionMap()->getGFXTexture();
|
||||
auto *sampler = device.getSampler(skybox.getReflectionMap()->getSamplerInfo());
|
||||
setTextureImpl(data, layoutGraph, "cc_environment", &texture);
|
||||
setSamplerImpl(data, layoutGraph, "cc_environment", sampler);
|
||||
} else {
|
||||
const auto *envmap =
|
||||
skybox.getEnvmap()
|
||||
? skybox.getEnvmap()
|
||||
: BuiltinResMgr::getInstance()->get<TextureCube>("default-cube-texture");
|
||||
if (envmap) {
|
||||
auto *texture = envmap->getGFXTexture();
|
||||
auto *sampler = device.getSampler(envmap->getSamplerInfo());
|
||||
setTextureImpl(data, layoutGraph, "cc_environment", texture);
|
||||
setSamplerImpl(data, layoutGraph, "cc_environment", sampler);
|
||||
}
|
||||
}
|
||||
const auto *diffuseMap =
|
||||
skybox.getDiffuseMap()
|
||||
? skybox.getDiffuseMap()
|
||||
: BuiltinResMgr::getInstance()->get<TextureCube>("default-cube-texture");
|
||||
if (diffuseMap) {
|
||||
auto *texture = diffuseMap->getGFXTexture();
|
||||
auto *sampler = device.getSampler(diffuseMap->getSamplerInfo());
|
||||
setTextureImpl(data, layoutGraph, "cc_diffuseMap", texture);
|
||||
setSamplerImpl(data, layoutGraph, "cc_diffuseMap", sampler);
|
||||
}
|
||||
gfx::SamplerInfo samplerPointInfo{
|
||||
gfx::Filter::POINT,
|
||||
gfx::Filter::POINT,
|
||||
gfx::Filter::NONE,
|
||||
gfx::Address::CLAMP,
|
||||
gfx::Address::CLAMP,
|
||||
gfx::Address::CLAMP};
|
||||
auto *pointSampler = device.getSampler(samplerPointInfo);
|
||||
setSamplerImpl(data, layoutGraph, "cc_shadowMap", pointSampler);
|
||||
// setTextureImpl(data, layoutGraph, "cc_shadowMap", BuiltinResMgr::getInstance()->get<Texture2D>("default-texture")->getGFXTexture());
|
||||
setSamplerImpl(data, layoutGraph, "cc_spotShadowMap", pointSampler);
|
||||
// setTextureImpl(data, layoutGraph, "cc_spotShadowMap", BuiltinResMgr::getInstance()->get<Texture2D>("default-texture")->getGFXTexture());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
float kLightMeterScale{10000.0F};
|
||||
|
||||
} // namespace
|
||||
|
||||
void setLightUBO(
|
||||
const scene::Light *light, bool bHDR, float exposure,
|
||||
const scene::Shadows *shadowInfo,
|
||||
char *buffer, size_t bufferSize) {
|
||||
CC_EXPECTS(bufferSize % sizeof(float) == 0);
|
||||
const auto maxSize = bufferSize / sizeof(float);
|
||||
auto *lightBufferData = reinterpret_cast<float *>(buffer);
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
Vec3 position = Vec3(0.0F, 0.0F, 0.0F);
|
||||
float size = 0.F;
|
||||
float range = 0.F;
|
||||
float luminanceHDR = 0.F;
|
||||
float luminanceLDR = 0.F;
|
||||
if (light->getType() == scene::LightType::SPHERE) {
|
||||
const auto *sphereLight = static_cast<const scene::SphereLight *>(light);
|
||||
position = sphereLight->getPosition();
|
||||
size = sphereLight->getSize();
|
||||
range = sphereLight->getRange();
|
||||
luminanceHDR = sphereLight->getLuminanceHDR();
|
||||
luminanceLDR = sphereLight->getLuminanceLDR();
|
||||
} else if (light->getType() == scene::LightType::SPOT) {
|
||||
const auto *spotLight = static_cast<const scene::SpotLight *>(light);
|
||||
position = spotLight->getPosition();
|
||||
size = spotLight->getSize();
|
||||
range = spotLight->getRange();
|
||||
luminanceHDR = spotLight->getLuminanceHDR();
|
||||
luminanceLDR = spotLight->getLuminanceLDR();
|
||||
} else if (light->getType() == scene::LightType::POINT) {
|
||||
const auto *pointLight = static_cast<const scene::PointLight *>(light);
|
||||
position = pointLight->getPosition();
|
||||
size = 0.0F;
|
||||
range = pointLight->getRange();
|
||||
luminanceHDR = pointLight->getLuminanceHDR();
|
||||
luminanceLDR = pointLight->getLuminanceLDR();
|
||||
} else if (light->getType() == scene::LightType::RANGED_DIRECTIONAL) {
|
||||
const auto *rangedDirLight = static_cast<const scene::RangedDirectionalLight *>(light);
|
||||
position = rangedDirLight->getPosition();
|
||||
size = 0.0F;
|
||||
range = 0.0F;
|
||||
luminanceHDR = rangedDirLight->getIlluminanceHDR();
|
||||
luminanceLDR = rangedDirLight->getIlluminanceLDR();
|
||||
}
|
||||
auto index = offset + pipeline::UBOForwardLight::LIGHT_POS_OFFSET;
|
||||
CC_EXPECTS(index + 4 < maxSize);
|
||||
lightBufferData[index++] = position.x;
|
||||
lightBufferData[index++] = position.y;
|
||||
lightBufferData[index] = position.z;
|
||||
|
||||
index = offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET;
|
||||
CC_EXPECTS(index + 4 < maxSize);
|
||||
lightBufferData[index++] = size;
|
||||
lightBufferData[index] = range;
|
||||
|
||||
index = offset + pipeline::UBOForwardLight::LIGHT_COLOR_OFFSET;
|
||||
CC_EXPECTS(index + 4 < maxSize);
|
||||
const auto &color = light->getColor();
|
||||
if (light->isUseColorTemperature()) {
|
||||
const auto &tempRGB = light->getColorTemperatureRGB();
|
||||
lightBufferData[index++] = color.x * tempRGB.x;
|
||||
lightBufferData[index++] = color.y * tempRGB.y;
|
||||
lightBufferData[index++] = color.z * tempRGB.z;
|
||||
} else {
|
||||
lightBufferData[index++] = color.x;
|
||||
lightBufferData[index++] = color.y;
|
||||
lightBufferData[index++] = color.z;
|
||||
}
|
||||
|
||||
if (bHDR) {
|
||||
lightBufferData[index] = luminanceHDR * exposure * kLightMeterScale;
|
||||
} else {
|
||||
lightBufferData[index] = luminanceLDR;
|
||||
}
|
||||
|
||||
switch (light->getType()) {
|
||||
case scene::LightType::SPHERE:
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_POS_OFFSET + 3] =
|
||||
static_cast<float>(scene::LightType::SPHERE);
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 2] = 0;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 3] = 0;
|
||||
break;
|
||||
case scene::LightType::SPOT: {
|
||||
const auto *spotLight = static_cast<const scene::SpotLight *>(light);
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_POS_OFFSET + 3] = static_cast<float>(scene::LightType::SPOT);
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 2] = spotLight->getSpotAngle();
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 3] =
|
||||
(shadowInfo->isEnabled() &&
|
||||
spotLight->isShadowEnabled() &&
|
||||
shadowInfo->getType() == scene::ShadowType::SHADOW_MAP)
|
||||
? 1.0F
|
||||
: 0.0F;
|
||||
|
||||
index = offset + pipeline::UBOForwardLight::LIGHT_DIR_OFFSET;
|
||||
const auto &direction = spotLight->getDirection();
|
||||
lightBufferData[index++] = direction.x;
|
||||
lightBufferData[index++] = direction.y;
|
||||
lightBufferData[index] = direction.z;
|
||||
} break;
|
||||
case scene::LightType::POINT:
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_POS_OFFSET + 3] = static_cast<float>(scene::LightType::POINT);
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 2] = 0;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 3] = 0;
|
||||
break;
|
||||
case scene::LightType::RANGED_DIRECTIONAL: {
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_POS_OFFSET + 3] = static_cast<float>(scene::LightType::RANGED_DIRECTIONAL);
|
||||
|
||||
const auto *rangedDirLight = static_cast<const scene::RangedDirectionalLight *>(light);
|
||||
const Vec3 &right = rangedDirLight->getRight();
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 0] = right.x;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 1] = right.y;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 2] = right.z;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_SIZE_RANGE_ANGLE_OFFSET + 3] = 0;
|
||||
|
||||
const auto &direction = rangedDirLight->getDirection();
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_DIR_OFFSET + 0] = direction.x;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_DIR_OFFSET + 1] = direction.y;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_DIR_OFFSET + 2] = direction.z;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_DIR_OFFSET + 3] = 0;
|
||||
|
||||
const auto &scale = rangedDirLight->getScale();
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_BOUNDING_SIZE_VS_OFFSET + 0] = scale.x * 0.5F;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_BOUNDING_SIZE_VS_OFFSET + 1] = scale.y * 0.5F;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_BOUNDING_SIZE_VS_OFFSET + 2] = scale.z * 0.5F;
|
||||
lightBufferData[offset + pipeline::UBOForwardLight::LIGHT_BOUNDING_SIZE_VS_OFFSET + 3] = 0;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const BuiltinCascadedShadowMap *getBuiltinShadowCSM(
|
||||
const PipelineRuntime &pplRuntime,
|
||||
const scene::Camera &camera,
|
||||
const scene::DirectionalLight *mainLight) {
|
||||
const auto &ppl = dynamic_cast<const NativePipeline &>(pplRuntime);
|
||||
// no main light
|
||||
if (!mainLight) {
|
||||
return nullptr;
|
||||
}
|
||||
// not attached to a node
|
||||
if (!mainLight->getNode()) {
|
||||
return nullptr;
|
||||
}
|
||||
const pipeline::PipelineSceneData &pplSceneData = *pplRuntime.getPipelineSceneData();
|
||||
auto &csmLayers = *pplSceneData.getCSMLayers();
|
||||
const auto &shadows = *pplSceneData.getShadows();
|
||||
// shadow not enabled
|
||||
if (!shadows.isEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
// shadow type is planar
|
||||
if (shadows.getType() == scene::ShadowType::PLANAR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// find csm
|
||||
const BuiltinCascadedShadowMapKey key{&camera, mainLight};
|
||||
auto iter = ppl.builtinCSMs.find(key);
|
||||
if (iter != ppl.builtinCSMs.end()) {
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
// add new csm info
|
||||
bool added = false;
|
||||
std::tie(iter, added) = ppl.builtinCSMs.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(key),
|
||||
std::forward_as_tuple());
|
||||
CC_ENSURES(added);
|
||||
|
||||
auto &csm = iter->second;
|
||||
|
||||
// update csm layers
|
||||
csmLayers.update(&pplSceneData, &camera);
|
||||
|
||||
// copy csm data
|
||||
CC_EXPECTS(csm.layers.size() == csmLayers.getLayers().size());
|
||||
for (uint32_t i = 0; i != csm.layers.size(); ++i) {
|
||||
const auto &src = *csmLayers.getLayers()[i];
|
||||
auto &dst = csm.layers[i];
|
||||
dst.shadowView = src.getMatShadowView();
|
||||
dst.shadowProj = src.getMatShadowProj();
|
||||
dst.shadowViewProj = src.getMatShadowViewProj();
|
||||
dst.validFrustum = src.getValidFrustum();
|
||||
dst.splitFrustum = src.getSplitFrustum();
|
||||
dst.lightViewFrustum = src.getLightViewFrustum();
|
||||
dst.castLightViewBoundingBox = src.getCastLightViewBoundingBox();
|
||||
dst.shadowCameraFar = src.getShadowCameraFar();
|
||||
dst.splitCameraNear = src.getSplitCameraNear();
|
||||
dst.splitCameraFar = src.getSplitCameraFar();
|
||||
dst.csmAtlas = src.getCSMAtlas();
|
||||
}
|
||||
|
||||
{
|
||||
const auto &src = *csmLayers.getSpecialLayer();
|
||||
auto &dst = csm.specialLayer;
|
||||
dst.shadowView = src.getMatShadowView();
|
||||
dst.shadowProj = src.getMatShadowProj();
|
||||
dst.shadowViewProj = src.getMatShadowViewProj();
|
||||
dst.validFrustum = src.getValidFrustum();
|
||||
dst.splitFrustum = src.getSplitFrustum();
|
||||
dst.lightViewFrustum = src.getLightViewFrustum();
|
||||
dst.castLightViewBoundingBox = src.getCastLightViewBoundingBox();
|
||||
dst.shadowCameraFar = src.getShadowCameraFar();
|
||||
}
|
||||
|
||||
csm.shadowDistance = mainLight->getShadowDistance();
|
||||
|
||||
return &csm;
|
||||
}
|
||||
|
||||
const geometry::Frustum &getBuiltinShadowFrustum(
|
||||
const PipelineRuntime &pplRuntime,
|
||||
const scene::Camera &camera,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
uint32_t level) {
|
||||
const auto &ppl = dynamic_cast<const NativePipeline &>(pplRuntime);
|
||||
|
||||
const auto &shadows = *ppl.pipelineSceneData->getShadows();
|
||||
if (shadows.getType() == scene::ShadowType::PLANAR) {
|
||||
return camera.getFrustum();
|
||||
}
|
||||
|
||||
BuiltinCascadedShadowMapKey key{&camera, mainLight};
|
||||
auto iter = ppl.builtinCSMs.find(key);
|
||||
if (iter == ppl.builtinCSMs.end()) {
|
||||
throw std::runtime_error("Builtin shadow CSM not found");
|
||||
}
|
||||
|
||||
const auto &csmLevel = mainLight->getCSMLevel();
|
||||
const auto &csm = iter->second;
|
||||
|
||||
if (mainLight->isShadowFixedArea() || csmLevel == scene::CSMLevel::LEVEL_1) {
|
||||
return csm.specialLayer.validFrustum;
|
||||
}
|
||||
return csm.layers[level].validFrustum;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
122
cocos/renderer/pipeline/custom/NativeBuiltinUtils.h
Normal file
122
cocos/renderer/pipeline/custom/NativeBuiltinUtils.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include "cocos/math/Vec4.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDevice.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativePipelineFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace scene {
|
||||
class Camera;
|
||||
class Light;
|
||||
class DirectionalLight;
|
||||
class Shadows;
|
||||
} // namespace scene
|
||||
|
||||
namespace geometry {
|
||||
class Frustum;
|
||||
} // namespace geometry
|
||||
|
||||
namespace gfx {
|
||||
class Device;
|
||||
} // namespace gfx
|
||||
|
||||
namespace pipeline {
|
||||
class PipelineSceneData;
|
||||
} // namespace pipeline
|
||||
|
||||
namespace render {
|
||||
|
||||
void setCameraUBOValues(
|
||||
const scene::Camera &camera,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &cfg,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
RenderData &data);
|
||||
|
||||
void setLegacyTextureUBOView(
|
||||
gfx::Device &device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &sceneData,
|
||||
RenderData &data);
|
||||
|
||||
// For use shadow map
|
||||
void setShadowUBOView(
|
||||
gfx::Device &device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &sceneData,
|
||||
const scene::DirectionalLight &mainLight,
|
||||
RenderData &data);
|
||||
|
||||
// For build shadow map
|
||||
void setShadowUBOLightView(
|
||||
gfx::Device *device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &sceneData,
|
||||
const BuiltinCascadedShadowMap *csm,
|
||||
const scene::Light &light,
|
||||
uint32_t level,
|
||||
RenderData &data);
|
||||
|
||||
// Additive light
|
||||
void setLightUBO(
|
||||
const scene::Light *light, bool bHDR, float exposure,
|
||||
const scene::Shadows *shadowInfo,
|
||||
char *buffer, size_t bufferSize);
|
||||
|
||||
void setPunctualLightShadowUBO(
|
||||
gfx::Device *device,
|
||||
const LayoutGraphData &layoutGraph,
|
||||
const pipeline::PipelineSceneData &pplSceneData,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
const scene::Light &light,
|
||||
RenderData &data);
|
||||
|
||||
// Render graph
|
||||
void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter);
|
||||
|
||||
// Geometry
|
||||
void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]);
|
||||
|
||||
// Shadow
|
||||
const BuiltinCascadedShadowMap *getBuiltinShadowCSM(
|
||||
const PipelineRuntime &pplRuntime,
|
||||
const scene::Camera &camera,
|
||||
const scene::DirectionalLight *mainLight);
|
||||
|
||||
const geometry::Frustum &getBuiltinShadowFrustum(
|
||||
const PipelineRuntime &pplRuntime,
|
||||
const scene::Camera &camera,
|
||||
const scene::DirectionalLight *mainLight,
|
||||
uint32_t level);
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
2108
cocos/renderer/pipeline/custom/NativeExecutor.cpp
Normal file
2108
cocos/renderer/pipeline/custom/NativeExecutor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
96
cocos/renderer/pipeline/custom/NativeFactory.cpp
Normal file
96
cocos/renderer/pipeline/custom/NativeFactory.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2022 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <sstream>
|
||||
#include "BinaryArchive.h"
|
||||
#include "LayoutGraphSerialization.h"
|
||||
#include "NativePipelineTypes.h"
|
||||
#include "RenderInterfaceTypes.h"
|
||||
#include "RenderingModule.h"
|
||||
#include "details/GslUtils.h"
|
||||
#include "pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "pipeline/custom/details/Pmr.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace {
|
||||
|
||||
NativeRenderingModule* sRenderingModule = nullptr;
|
||||
NativePipeline* sPipeline = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
RenderingModule* Factory::init(gfx::Device* deviceIn, const ccstd::vector<unsigned char>& bufferIn) {
|
||||
std::shared_ptr<NativeProgramLibrary> ptr(
|
||||
allocatePmrUniquePtr<NativeProgramLibrary>(
|
||||
boost::container::pmr::get_default_resource()));
|
||||
{
|
||||
std::string buffer(bufferIn.begin(), bufferIn.end());
|
||||
std::istringstream iss(buffer, std::ios::binary);
|
||||
BinaryInputArchive ar(iss, boost::container::pmr::get_default_resource());
|
||||
load(ar, ptr->layoutGraph);
|
||||
}
|
||||
ptr->init(deviceIn);
|
||||
|
||||
sRenderingModule = ccnew NativeRenderingModule(std::move(ptr));
|
||||
return sRenderingModule;
|
||||
}
|
||||
|
||||
void Factory::destroy(RenderingModule* renderingModule) noexcept {
|
||||
auto* ptr = dynamic_cast<NativeRenderingModule*>(renderingModule);
|
||||
if (ptr) {
|
||||
ptr->programLibrary.reset();
|
||||
CC_EXPECTS(sRenderingModule == renderingModule);
|
||||
sRenderingModule = nullptr;
|
||||
sPipeline = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Pipeline* Factory::createPipeline() {
|
||||
if (sPipeline) {
|
||||
return sPipeline;
|
||||
}
|
||||
sPipeline = ccnew NativePipeline(boost::container::pmr::get_default_resource());
|
||||
CC_EXPECTS(sRenderingModule);
|
||||
sRenderingModule->programLibrary->pipeline = sPipeline;
|
||||
return sPipeline;
|
||||
}
|
||||
|
||||
ProgramLibrary* getProgramLibrary() {
|
||||
if (!sRenderingModule) {
|
||||
return nullptr;
|
||||
}
|
||||
return sRenderingModule->programLibrary.get();
|
||||
}
|
||||
|
||||
RenderingModule* getRenderingModule() {
|
||||
return sRenderingModule;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
47
cocos/renderer/pipeline/custom/NativeFwd.h
Normal file
47
cocos/renderer/pipeline/custom/NativeFwd.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/PrivateFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct ProgramInfo;
|
||||
struct ProgramGroup;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
1559
cocos/renderer/pipeline/custom/NativePipeline.cpp
Normal file
1559
cocos/renderer/pipeline/custom/NativePipeline.cpp
Normal file
File diff suppressed because it is too large
Load Diff
130
cocos/renderer/pipeline/custom/NativePipelineFwd.h
Normal file
130
cocos/renderer/pipeline/custom/NativePipelineFwd.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace scene {
|
||||
|
||||
class ReflectionProbe;
|
||||
|
||||
} // namespace scene
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class T>
|
||||
using Array4 = std::array<T, 4>;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class NativeRenderNode;
|
||||
class NativeSetter;
|
||||
class NativeSceneBuilder;
|
||||
class NativeRenderSubpassBuilderImpl;
|
||||
class NativeRenderQueueBuilder;
|
||||
class NativeRenderSubpassBuilder;
|
||||
class NativeMultisampleRenderSubpassBuilder;
|
||||
class NativeComputeSubpassBuilder;
|
||||
class NativeRenderPassBuilder;
|
||||
class NativeMultisampleRenderPassBuilder;
|
||||
class NativeComputeQueueBuilder;
|
||||
class NativeComputePassBuilder;
|
||||
struct RenderInstancingQueue;
|
||||
struct DrawInstance;
|
||||
struct ProbeHelperQueue;
|
||||
struct RenderDrawQueue;
|
||||
struct NativeRenderQueue;
|
||||
struct ResourceGroup;
|
||||
struct BufferPool;
|
||||
struct DescriptorSetPool;
|
||||
struct UniformBlockResource;
|
||||
struct ProgramResource;
|
||||
struct LayoutGraphNodeResource;
|
||||
struct QuadResource;
|
||||
|
||||
enum class ResourceType;
|
||||
|
||||
struct SceneResource;
|
||||
struct FrustumCullingKey;
|
||||
struct FrustumCullingID;
|
||||
struct FrustumCulling;
|
||||
struct LightBoundsCullingID;
|
||||
struct LightBoundsCullingKey;
|
||||
struct LightBoundsCulling;
|
||||
struct NativeRenderQueueID;
|
||||
struct NativeRenderQueueDesc;
|
||||
struct LightBoundsCullingResult;
|
||||
struct SceneCulling;
|
||||
struct LightResource;
|
||||
struct NativeRenderContext;
|
||||
class NativeProgramLibrary;
|
||||
struct PipelineCustomization;
|
||||
struct BuiltinShadowTransform;
|
||||
struct BuiltinCascadedShadowMapKey;
|
||||
struct BuiltinCascadedShadowMap;
|
||||
class NativePipeline;
|
||||
class NativeProgramProxy;
|
||||
class NativeRenderingModule;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::FrustumCullingKey> {
|
||||
hash_t operator()(const cc::render::FrustumCullingKey& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::FrustumCullingID> {
|
||||
hash_t operator()(const cc::render::FrustumCullingID& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::LightBoundsCullingKey> {
|
||||
hash_t operator()(const cc::render::LightBoundsCullingKey& val) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
39
cocos/renderer/pipeline/custom/NativePipelineGraphs.h
Normal file
39
cocos/renderer/pipeline/custom/NativePipelineGraphs.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphImpl.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Overload.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/PathUtils.h"
|
||||
|
||||
// clang-format on
|
||||
265
cocos/renderer/pipeline/custom/NativePipelineTypes.cpp
Normal file
265
cocos/renderer/pipeline/custom/NativePipelineTypes.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "NativePipelineTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
RenderInstancingQueue::RenderInstancingQueue(const allocator_type& alloc) noexcept
|
||||
: sortedBatches(alloc),
|
||||
passInstances(alloc),
|
||||
instanceBuffers(alloc) {}
|
||||
|
||||
RenderInstancingQueue::RenderInstancingQueue(RenderInstancingQueue&& rhs, const allocator_type& alloc)
|
||||
: sortedBatches(std::move(rhs.sortedBatches), alloc),
|
||||
passInstances(std::move(rhs.passInstances), alloc),
|
||||
instanceBuffers(std::move(rhs.instanceBuffers), alloc) {}
|
||||
|
||||
RenderInstancingQueue::RenderInstancingQueue(RenderInstancingQueue const& rhs, const allocator_type& alloc)
|
||||
: sortedBatches(rhs.sortedBatches, alloc),
|
||||
passInstances(rhs.passInstances, alloc),
|
||||
instanceBuffers(rhs.instanceBuffers, alloc) {}
|
||||
|
||||
ProbeHelperQueue::ProbeHelperQueue(const allocator_type& alloc) noexcept
|
||||
: probeMap(alloc) {}
|
||||
|
||||
ProbeHelperQueue::ProbeHelperQueue(ProbeHelperQueue&& rhs, const allocator_type& alloc)
|
||||
: probeMap(std::move(rhs.probeMap), alloc) {}
|
||||
|
||||
ProbeHelperQueue::ProbeHelperQueue(ProbeHelperQueue const& rhs, const allocator_type& alloc)
|
||||
: probeMap(rhs.probeMap, alloc) {}
|
||||
|
||||
RenderDrawQueue::RenderDrawQueue(const allocator_type& alloc) noexcept
|
||||
: instances(alloc) {}
|
||||
|
||||
RenderDrawQueue::RenderDrawQueue(RenderDrawQueue&& rhs, const allocator_type& alloc)
|
||||
: instances(std::move(rhs.instances), alloc) {}
|
||||
|
||||
RenderDrawQueue::RenderDrawQueue(RenderDrawQueue const& rhs, const allocator_type& alloc)
|
||||
: instances(rhs.instances, alloc) {}
|
||||
|
||||
NativeRenderQueue::NativeRenderQueue(const allocator_type& alloc) noexcept
|
||||
: opaqueQueue(alloc),
|
||||
transparentQueue(alloc),
|
||||
probeQueue(alloc),
|
||||
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),
|
||||
sceneFlags(rhs.sceneFlags),
|
||||
subpassOrPassLayoutID(rhs.subpassOrPassLayoutID),
|
||||
lightByteOffset(rhs.lightByteOffset) {}
|
||||
|
||||
ResourceGroup::ResourceGroup(const allocator_type& alloc) noexcept
|
||||
: instancingBuffers(alloc) {}
|
||||
|
||||
BufferPool::BufferPool(const allocator_type& alloc) noexcept
|
||||
: currentBuffers(alloc),
|
||||
currentBufferViews(alloc),
|
||||
freeBuffers(alloc),
|
||||
freeBufferViews(alloc) {}
|
||||
|
||||
BufferPool::BufferPool(gfx::Device* deviceIn, uint32_t bufferSizeIn, bool dynamicIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: device(deviceIn),
|
||||
bufferSize(bufferSizeIn),
|
||||
dynamic(dynamicIn),
|
||||
currentBuffers(alloc),
|
||||
currentBufferViews(alloc),
|
||||
freeBuffers(alloc),
|
||||
freeBufferViews(alloc) {}
|
||||
|
||||
BufferPool::BufferPool(BufferPool&& rhs, const allocator_type& alloc)
|
||||
: device(rhs.device),
|
||||
bufferSize(rhs.bufferSize),
|
||||
dynamic(rhs.dynamic),
|
||||
currentBuffers(std::move(rhs.currentBuffers), alloc),
|
||||
currentBufferViews(std::move(rhs.currentBufferViews), alloc),
|
||||
freeBuffers(std::move(rhs.freeBuffers), alloc),
|
||||
freeBufferViews(std::move(rhs.freeBufferViews), alloc) {}
|
||||
|
||||
DescriptorSetPool::DescriptorSetPool(const allocator_type& alloc) noexcept
|
||||
: currentDescriptorSets(alloc),
|
||||
freeDescriptorSets(alloc) {}
|
||||
|
||||
DescriptorSetPool::DescriptorSetPool(gfx::Device* deviceIn, IntrusivePtr<gfx::DescriptorSetLayout> setLayoutIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: device(deviceIn),
|
||||
setLayout(std::move(setLayoutIn)),
|
||||
currentDescriptorSets(alloc),
|
||||
freeDescriptorSets(alloc) {}
|
||||
|
||||
DescriptorSetPool::DescriptorSetPool(DescriptorSetPool&& rhs, const allocator_type& alloc)
|
||||
: device(rhs.device),
|
||||
setLayout(std::move(rhs.setLayout)),
|
||||
currentDescriptorSets(std::move(rhs.currentDescriptorSets), alloc),
|
||||
freeDescriptorSets(std::move(rhs.freeDescriptorSets), alloc) {}
|
||||
|
||||
UniformBlockResource::UniformBlockResource(const allocator_type& alloc) noexcept
|
||||
: cpuBuffer(alloc),
|
||||
bufferPool(alloc) {}
|
||||
|
||||
UniformBlockResource::UniformBlockResource(UniformBlockResource&& rhs, const allocator_type& alloc)
|
||||
: cpuBuffer(std::move(rhs.cpuBuffer), alloc),
|
||||
bufferPool(std::move(rhs.bufferPool), alloc) {}
|
||||
|
||||
ProgramResource::ProgramResource(const allocator_type& alloc) noexcept
|
||||
: uniformBuffers(alloc),
|
||||
descriptorSetPool(alloc) {}
|
||||
|
||||
ProgramResource::ProgramResource(ProgramResource&& rhs, const allocator_type& alloc)
|
||||
: uniformBuffers(std::move(rhs.uniformBuffers), alloc),
|
||||
descriptorSetPool(std::move(rhs.descriptorSetPool), alloc) {}
|
||||
|
||||
LayoutGraphNodeResource::LayoutGraphNodeResource(const allocator_type& alloc) noexcept
|
||||
: uniformBuffers(alloc),
|
||||
descriptorSetPool(alloc),
|
||||
programResources(alloc) {}
|
||||
|
||||
LayoutGraphNodeResource::LayoutGraphNodeResource(LayoutGraphNodeResource&& rhs, const allocator_type& alloc)
|
||||
: uniformBuffers(std::move(rhs.uniformBuffers), alloc),
|
||||
descriptorSetPool(std::move(rhs.descriptorSetPool), alloc),
|
||||
programResources(std::move(rhs.programResources), alloc) {}
|
||||
|
||||
SceneResource::SceneResource(const allocator_type& alloc) noexcept
|
||||
: resourceIndex(alloc),
|
||||
storageBuffers(alloc),
|
||||
storageImages(alloc) {}
|
||||
|
||||
SceneResource::SceneResource(SceneResource&& rhs, const allocator_type& alloc)
|
||||
: resourceIndex(std::move(rhs.resourceIndex), alloc),
|
||||
storageBuffers(std::move(rhs.storageBuffers), alloc),
|
||||
storageImages(std::move(rhs.storageImages), alloc) {}
|
||||
|
||||
FrustumCulling::FrustumCulling(const allocator_type& alloc) noexcept
|
||||
: resultIndex(alloc) {}
|
||||
|
||||
FrustumCulling::FrustumCulling(FrustumCulling&& rhs, const allocator_type& alloc)
|
||||
: resultIndex(std::move(rhs.resultIndex), alloc) {}
|
||||
|
||||
FrustumCulling::FrustumCulling(FrustumCulling const& rhs, const allocator_type& alloc)
|
||||
: resultIndex(rhs.resultIndex, alloc) {}
|
||||
|
||||
LightBoundsCulling::LightBoundsCulling(const allocator_type& alloc) noexcept
|
||||
: resultIndex(alloc) {}
|
||||
|
||||
LightBoundsCulling::LightBoundsCulling(LightBoundsCulling&& rhs, const allocator_type& alloc)
|
||||
: resultIndex(std::move(rhs.resultIndex), alloc) {}
|
||||
|
||||
LightBoundsCulling::LightBoundsCulling(LightBoundsCulling const& rhs, const allocator_type& alloc)
|
||||
: resultIndex(rhs.resultIndex, alloc) {}
|
||||
|
||||
SceneCulling::SceneCulling(const allocator_type& alloc) noexcept
|
||||
: frustumCullings(alloc),
|
||||
frustumCullingResults(alloc),
|
||||
lightBoundsCullings(alloc),
|
||||
lightBoundsCullingResults(alloc),
|
||||
renderQueues(alloc),
|
||||
renderQueueIndex(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),
|
||||
numFrustumCulling(rhs.numFrustumCulling),
|
||||
numLightBoundsCulling(rhs.numLightBoundsCulling),
|
||||
numRenderQueues(rhs.numRenderQueues),
|
||||
gpuCullingPassID(rhs.gpuCullingPassID),
|
||||
enableLightCulling(rhs.enableLightCulling) {}
|
||||
|
||||
LightResource::LightResource(const allocator_type& alloc) noexcept
|
||||
: cpuBuffer(alloc),
|
||||
lights(alloc),
|
||||
lightIndex(alloc) {}
|
||||
|
||||
NativeRenderContext::NativeRenderContext(std::unique_ptr<gfx::DefaultResource> defaultResourceIn, const allocator_type& alloc) noexcept
|
||||
: defaultResource(std::move(defaultResourceIn)),
|
||||
resourceGroups(alloc),
|
||||
layoutGraphResources(alloc),
|
||||
renderSceneResources(alloc),
|
||||
sceneCulling(alloc),
|
||||
lightResources(alloc) {}
|
||||
|
||||
NativeProgramLibrary::NativeProgramLibrary(const allocator_type& alloc) noexcept
|
||||
: layoutGraph(alloc),
|
||||
phases(alloc),
|
||||
localLayoutData(alloc) {}
|
||||
|
||||
PipelineCustomization::PipelineCustomization(const allocator_type& alloc) noexcept
|
||||
: contexts(alloc),
|
||||
renderPasses(alloc),
|
||||
renderSubpasses(alloc),
|
||||
computeSubpasses(alloc),
|
||||
computePasses(alloc),
|
||||
renderQueues(alloc),
|
||||
renderCommands(alloc) {}
|
||||
|
||||
PipelineCustomization::PipelineCustomization(PipelineCustomization&& rhs, const allocator_type& alloc)
|
||||
: currentContext(std::move(rhs.currentContext)),
|
||||
contexts(std::move(rhs.contexts), alloc),
|
||||
renderPasses(std::move(rhs.renderPasses), alloc),
|
||||
renderSubpasses(std::move(rhs.renderSubpasses), alloc),
|
||||
computeSubpasses(std::move(rhs.computeSubpasses), alloc),
|
||||
computePasses(std::move(rhs.computePasses), alloc),
|
||||
renderQueues(std::move(rhs.renderQueues), alloc),
|
||||
renderCommands(std::move(rhs.renderCommands), alloc) {}
|
||||
|
||||
PipelineCustomization::PipelineCustomization(PipelineCustomization const& rhs, const allocator_type& alloc)
|
||||
: currentContext(rhs.currentContext),
|
||||
contexts(rhs.contexts, alloc),
|
||||
renderPasses(rhs.renderPasses, alloc),
|
||||
renderSubpasses(rhs.renderSubpasses, alloc),
|
||||
computeSubpasses(rhs.computeSubpasses, alloc),
|
||||
computePasses(rhs.computePasses, alloc),
|
||||
renderQueues(rhs.renderQueues, alloc),
|
||||
renderCommands(rhs.renderCommands, alloc) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
1760
cocos/renderer/pipeline/custom/NativePipelineTypes.h
Normal file
1760
cocos/renderer/pipeline/custom/NativePipelineTypes.h
Normal file
File diff suppressed because it is too large
Load Diff
149
cocos/renderer/pipeline/custom/NativePools.cpp
Normal file
149
cocos/renderer/pipeline/custom/NativePools.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "NativePipelineTypes.h"
|
||||
#include "details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
void BufferPool::init(gfx::Device* deviceIn, uint32_t sz, bool bDynamic) {
|
||||
CC_EXPECTS(deviceIn);
|
||||
CC_EXPECTS(sz);
|
||||
CC_EXPECTS(!device);
|
||||
CC_EXPECTS(bufferSize == 0);
|
||||
|
||||
device = deviceIn;
|
||||
bufferSize = sz;
|
||||
dynamic = bDynamic;
|
||||
}
|
||||
|
||||
void BufferPool::syncResources() {
|
||||
for (auto& buffer : currentBuffers) {
|
||||
freeBuffers.emplace_back(std::move(buffer));
|
||||
}
|
||||
currentBuffers.clear();
|
||||
|
||||
for (auto& bufferView : currentBufferViews) {
|
||||
freeBufferViews.emplace_back(std::move(bufferView));
|
||||
}
|
||||
currentBufferViews.clear();
|
||||
}
|
||||
|
||||
gfx::Buffer* BufferPool::allocateBuffer() {
|
||||
CC_EXPECTS(device);
|
||||
CC_EXPECTS(bufferSize);
|
||||
|
||||
gfx::Buffer* ptr = nullptr;
|
||||
|
||||
if (freeBuffers.empty()) {
|
||||
{
|
||||
gfx::BufferInfo info{
|
||||
gfx::BufferUsageBit::UNIFORM | gfx::BufferUsageBit::TRANSFER_DST,
|
||||
gfx::MemoryUsageBit::HOST | gfx::MemoryUsageBit::DEVICE,
|
||||
bufferSize,
|
||||
bufferSize};
|
||||
freeBuffers.emplace_back(device->createBuffer(info));
|
||||
}
|
||||
|
||||
if (dynamic) {
|
||||
gfx::BufferViewInfo info{
|
||||
freeBuffers.back().get(),
|
||||
0, bufferSize};
|
||||
freeBufferViews.emplace_back(device->createBuffer(info));
|
||||
}
|
||||
}
|
||||
{
|
||||
CC_ENSURES(!freeBuffers.empty());
|
||||
auto& buffer = freeBuffers.back();
|
||||
ptr = buffer.get();
|
||||
CC_EXPECTS(buffer->getSize() == bufferSize);
|
||||
currentBuffers.emplace_back(std::move(buffer));
|
||||
freeBuffers.pop_back();
|
||||
}
|
||||
if (dynamic) {
|
||||
CC_ENSURES(!freeBufferViews.empty());
|
||||
auto& bufferView = freeBufferViews.back();
|
||||
ptr = bufferView.get();
|
||||
CC_EXPECTS(bufferView->getSize() == bufferSize);
|
||||
currentBufferViews.emplace_back(std::move(bufferView));
|
||||
freeBufferViews.pop_back();
|
||||
}
|
||||
CC_ENSURES(ptr);
|
||||
if (dynamic) {
|
||||
CC_ENSURES(ptr->isBufferView());
|
||||
} else {
|
||||
CC_ENSURES(!ptr->isBufferView());
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void UniformBlockResource::init(gfx::Device* deviceIn, uint32_t sz, bool bDynamic) {
|
||||
CC_EXPECTS(cpuBuffer.empty());
|
||||
cpuBuffer.resize(sz);
|
||||
bufferPool.init(deviceIn, sz, bDynamic);
|
||||
}
|
||||
|
||||
gfx::Buffer* UniformBlockResource::createFromCpuBuffer() {
|
||||
CC_EXPECTS(cpuBuffer.size() == bufferPool.bufferSize);
|
||||
auto* bufferOrView = bufferPool.allocateBuffer();
|
||||
if (bufferPool.dynamic) {
|
||||
auto* buffer = bufferPool.currentBuffers.back().get();
|
||||
buffer->update(cpuBuffer.data(), static_cast<uint32_t>(cpuBuffer.size()));
|
||||
} else {
|
||||
bufferOrView->update(cpuBuffer.data(), static_cast<uint32_t>(cpuBuffer.size()));
|
||||
}
|
||||
return bufferOrView;
|
||||
}
|
||||
|
||||
void DescriptorSetPool::init(gfx::Device* deviceIn,
|
||||
IntrusivePtr<gfx::DescriptorSetLayout> layout) {
|
||||
CC_EXPECTS(deviceIn);
|
||||
CC_EXPECTS(layout);
|
||||
CC_EXPECTS(!device);
|
||||
CC_EXPECTS(!setLayout);
|
||||
device = deviceIn;
|
||||
setLayout = std::move(layout);
|
||||
}
|
||||
|
||||
void DescriptorSetPool::syncDescriptorSets() {
|
||||
for (auto& set : currentDescriptorSets) {
|
||||
freeDescriptorSets.emplace_back(std::move(set));
|
||||
}
|
||||
currentDescriptorSets.clear();
|
||||
}
|
||||
|
||||
gfx::DescriptorSet& DescriptorSetPool::getCurrentDescriptorSet() {
|
||||
CC_EXPECTS(!currentDescriptorSets.empty());
|
||||
return *currentDescriptorSets.back();
|
||||
}
|
||||
|
||||
const gfx::DescriptorSet& DescriptorSetPool::getCurrentDescriptorSet() const {
|
||||
CC_EXPECTS(!currentDescriptorSets.empty());
|
||||
return *currentDescriptorSets.back();
|
||||
}
|
||||
|
||||
gfx::DescriptorSet* DescriptorSetPool::allocateDescriptorSet() {
|
||||
CC_EXPECTS(device);
|
||||
CC_EXPECTS(setLayout);
|
||||
|
||||
gfx::DescriptorSet* ptr = nullptr;
|
||||
|
||||
if (freeDescriptorSets.empty()) {
|
||||
freeDescriptorSets.emplace_back(
|
||||
device->createDescriptorSet(gfx::DescriptorSetInfo{setLayout.get()}));
|
||||
}
|
||||
|
||||
{
|
||||
CC_ENSURES(!freeDescriptorSets.empty());
|
||||
auto& set = freeDescriptorSets.back();
|
||||
ptr = set.get();
|
||||
CC_EXPECTS(set->getLayout() == setLayout);
|
||||
currentDescriptorSets.emplace_back(std::move(set));
|
||||
freeDescriptorSets.pop_back();
|
||||
}
|
||||
CC_ENSURES(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
1614
cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp
Normal file
1614
cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1391
cocos/renderer/pipeline/custom/NativeRenderGraph.cpp
Normal file
1391
cocos/renderer/pipeline/custom/NativeRenderGraph.cpp
Normal file
File diff suppressed because it is too large
Load Diff
327
cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp
Normal file
327
cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include <boost/graph/filtered_graph.hpp>
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonNames.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/DebugUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphView.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace {
|
||||
|
||||
const char *getName(const gfx::LoadOp &op) {
|
||||
switch (op) {
|
||||
case gfx::LoadOp::LOAD:
|
||||
return "LOAD";
|
||||
case gfx::LoadOp::CLEAR:
|
||||
return "CLEAR";
|
||||
case gfx::LoadOp::DISCARD:
|
||||
return "DISCARD";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
const char *getName(const gfx::StoreOp &op) {
|
||||
switch (op) {
|
||||
case gfx::StoreOp::STORE:
|
||||
return "STORE";
|
||||
case gfx::StoreOp::DISCARD:
|
||||
return "DISCARD";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string getName(const gfx::ClearFlagBit &flags) {
|
||||
std::ostringstream oss;
|
||||
int count = 0;
|
||||
if (hasAnyFlags(flags, gfx::ClearFlagBit::COLOR)) {
|
||||
if (count++) {
|
||||
oss << "|";
|
||||
}
|
||||
oss << "COLOR";
|
||||
}
|
||||
if (hasAnyFlags(flags, gfx::ClearFlagBit::DEPTH)) {
|
||||
if (count++) {
|
||||
oss << "|";
|
||||
}
|
||||
oss << "DEPTH";
|
||||
}
|
||||
if (hasAnyFlags(flags, gfx::ClearFlagBit::STENCIL)) {
|
||||
if (count++) {
|
||||
oss << "|";
|
||||
}
|
||||
oss << "STENCIL";
|
||||
}
|
||||
if (flags == gfx::ClearFlagBit::NONE) {
|
||||
oss << "NONE";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
struct RenderGraphPrintVisitor : boost::dfs_visitor<> {
|
||||
void discover_vertex(
|
||||
RenderGraph::vertex_descriptor vertID,
|
||||
const AddressableView<RenderGraph> &gv) const {
|
||||
const auto &g = gv.mGraph;
|
||||
const auto &name = get(RenderGraph::NameTag{}, g, vertID);
|
||||
visitObject(
|
||||
vertID, gv.mGraph,
|
||||
[&](const RasterPass &pass) {
|
||||
OSS << "RasterPass \"" << name << "\" {\n";
|
||||
indent(space);
|
||||
for (const auto &[name, rasterView] : pass.rasterViews) {
|
||||
OSS << "RasterView \"" << name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "slotName: \"" << rasterView.slotName << "\";\n";
|
||||
OSS << "accessType: " << getName(rasterView.accessType) << ";\n";
|
||||
OSS << "attachmentType: " << getName(rasterView.attachmentType) << ";\n";
|
||||
OSS << "loadOp: " << getName(rasterView.loadOp) << ";\n";
|
||||
OSS << "storeOp: " << getName(rasterView.storeOp) << ";\n";
|
||||
OSS << "clearFlags: " << getName(rasterView.clearFlags) << ";\n";
|
||||
const auto &c = rasterView.clearColor;
|
||||
if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::COLOR)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n";
|
||||
} else if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << "];\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
for (const auto &[name, computeViews] : pass.computeViews) {
|
||||
OSS << "ComputeViews \"" << name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
for (const auto &computeView : computeViews) {
|
||||
OSS << "ComputeView \"" << computeView.name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "accessType: " << getName(computeView.accessType) << ";\n";
|
||||
OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n";
|
||||
const auto &c = computeView.clearValue;
|
||||
if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n";
|
||||
} else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << "];\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
},
|
||||
[&](const RasterSubpass &subpass) {
|
||||
std::ignore = subpass;
|
||||
},
|
||||
[&](const ComputeSubpass &subpass) {
|
||||
std::ignore = subpass;
|
||||
},
|
||||
[&](const ComputePass &pass) {
|
||||
OSS << "ComputePass \"" << name << "\" {\n";
|
||||
indent(space);
|
||||
for (const auto &[name, computeViews] : pass.computeViews) {
|
||||
OSS << "ComputeViews \"" << name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
for (const auto &computeView : computeViews) {
|
||||
OSS << "ComputeView \"" << computeView.name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "accessType: " << getName(computeView.accessType) << ";\n";
|
||||
OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n";
|
||||
const auto &c = computeView.clearValue;
|
||||
if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n";
|
||||
} else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << "];\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
},
|
||||
[&](const ResolvePass &pass) {
|
||||
OSS << "ResolvePass \"" << name << "\" {\n";
|
||||
for (const auto &pair : pass.resolvePairs) {
|
||||
INDENT();
|
||||
OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n";
|
||||
}
|
||||
indent(space);
|
||||
},
|
||||
[&](const CopyPass &pass) {
|
||||
OSS << "CopyPass \"" << name << "\" {\n";
|
||||
for (const auto &pair : pass.copyPairs) {
|
||||
INDENT();
|
||||
OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n";
|
||||
}
|
||||
indent(space);
|
||||
},
|
||||
[&](const MovePass &pass) {
|
||||
OSS << "MovePass \"" << name << "\" {\n";
|
||||
for (const auto &pair : pass.movePairs) {
|
||||
INDENT();
|
||||
OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n";
|
||||
}
|
||||
indent(space);
|
||||
},
|
||||
[&](const RaytracePass &pass) {
|
||||
std::ignore = pass;
|
||||
OSS << "RaytracePass \"" << name << "\" {\n";
|
||||
indent(space);
|
||||
},
|
||||
[&](const RenderQueue &queue) {
|
||||
OSS << "Queue \"" << name << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "hint: " << getName(queue.hint) << ";\n";
|
||||
}
|
||||
indent(space);
|
||||
},
|
||||
[&](const SceneData &scene) {
|
||||
std::ignore = scene;
|
||||
OSS << "Scene \"" << name << "\" {\n";
|
||||
indent(space);
|
||||
},
|
||||
[&](const Blit &blit) {
|
||||
std::ignore = blit;
|
||||
OSS << "Blit \"" << name << "\";\n";
|
||||
},
|
||||
[&](const Dispatch &dispatch) {
|
||||
OSS << "Dispatch \"" << name << "\", ["
|
||||
<< dispatch.threadGroupCountX << ", "
|
||||
<< dispatch.threadGroupCountY << ", "
|
||||
<< dispatch.threadGroupCountZ << "];\n";
|
||||
},
|
||||
[&](const ccstd::pmr::vector<ClearView> &clearViews) {
|
||||
OSS << "Clear \"" << name << "\" {\n";
|
||||
indent(space);
|
||||
for (const auto &view : clearViews) {
|
||||
INDENT();
|
||||
OSS << "\"" << view.slotName << "\" {\n";
|
||||
{
|
||||
INDENT();
|
||||
OSS << "clearFlags: " << getName(view.clearFlags) << ";\n";
|
||||
const auto &c = view.clearColor;
|
||||
if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::COLOR)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n";
|
||||
} else if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) {
|
||||
OSS << "clearColor: [" << c.x << ", " << c.y << "];\n";
|
||||
}
|
||||
}
|
||||
OSS << "}\n";
|
||||
}
|
||||
},
|
||||
[&](const gfx::Viewport &vp) {
|
||||
OSS << "Viewport \"" << name << "\" ["
|
||||
<< "left: " << vp.left << ", "
|
||||
<< "top: " << vp.top << ", "
|
||||
<< "width: " << vp.width << ", "
|
||||
<< "height: " << vp.height << ", "
|
||||
<< "minDepth: " << vp.minDepth << ", "
|
||||
<< "maxDepth: " << vp.maxDepth << "]\n";
|
||||
});
|
||||
}
|
||||
|
||||
void finish_vertex(
|
||||
RenderGraph::vertex_descriptor vertID,
|
||||
const AddressableView<RenderGraph> &gv) const {
|
||||
std::ignore = gv;
|
||||
visitObject(
|
||||
vertID, gv.mGraph,
|
||||
[&](const RasterPass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const RasterSubpass &subpass) {
|
||||
std::ignore = subpass;
|
||||
},
|
||||
[&](const ComputeSubpass &subpass) {
|
||||
std::ignore = subpass;
|
||||
},
|
||||
[&](const ComputePass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const ResolvePass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const CopyPass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const MovePass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const RaytracePass &pass) {
|
||||
std::ignore = pass;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const RenderQueue &queue) {
|
||||
std::ignore = queue;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const SceneData &scene) {
|
||||
std::ignore = scene;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const Blit &blit) {
|
||||
},
|
||||
[&](const Dispatch &dispatch) {
|
||||
},
|
||||
[&](const ccstd::pmr::vector<ClearView> &clear) {
|
||||
std::ignore = clear;
|
||||
unindent(space);
|
||||
OSS << "}\n";
|
||||
},
|
||||
[&](const gfx::Viewport &clear) {
|
||||
});
|
||||
}
|
||||
|
||||
std::ostringstream &oss;
|
||||
ccstd::pmr::string &space;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ccstd::string RenderGraph::print(
|
||||
boost::container::pmr::memory_resource *scratch) const {
|
||||
const auto &rg = *this;
|
||||
std::ostringstream oss;
|
||||
ccstd::pmr::string space(scratch);
|
||||
oss << "\n";
|
||||
OSS << "RenderGraph {\n";
|
||||
{
|
||||
INDENT();
|
||||
RenderGraphPrintVisitor visitor{
|
||||
{}, oss, space};
|
||||
AddressableView<RenderGraph> graphView(rg);
|
||||
auto colors = rg.colors(scratch);
|
||||
boost::depth_first_search(graphView, visitor, get(colors, rg));
|
||||
}
|
||||
OSS << "}\n";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
229
cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h
Normal file
229
cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h
Normal file
@@ -0,0 +1,229 @@
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
#include "pipeline/custom/RenderGraphTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class Component0, class Component1, class Component2, class Component3, class Tag, class ValueT>
|
||||
RenderGraph::vertex_descriptor
|
||||
addVertex2(Tag tag, Component0 &&c0, Component1 &&c1, Component2 &&c2, Component3 &&c3, ValueT &&val,
|
||||
RenderGraph &g, RenderGraph::vertex_descriptor u = RenderGraph::null_vertex()) {
|
||||
auto v = addVertex(
|
||||
tag,
|
||||
std::forward<Component0>(c0),
|
||||
std::forward<Component1>(c1),
|
||||
std::forward<Component2>(c2),
|
||||
std::forward<Component3>(c3),
|
||||
std::forward<ValueT>(val),
|
||||
g,
|
||||
u);
|
||||
g.sortedVertices.emplace_back(v);
|
||||
CC_EXPECTS(g.sortedVertices.size() == num_vertices(g));
|
||||
return v;
|
||||
}
|
||||
|
||||
inline LayoutGraphData::vertex_descriptor getSubpassOrPassID(
|
||||
RenderGraph::vertex_descriptor vertID,
|
||||
const RenderGraph &rg, const LayoutGraphData &lg) {
|
||||
const auto queueID = parent(vertID, rg);
|
||||
CC_ENSURES(queueID != RenderGraph::null_vertex());
|
||||
const auto subpassOrPassID = parent(queueID, rg);
|
||||
CC_ENSURES(subpassOrPassID != RenderGraph::null_vertex());
|
||||
const auto passID = parent(subpassOrPassID, rg);
|
||||
|
||||
auto layoutID = LayoutGraphData::null_vertex();
|
||||
if (passID == RenderGraph::null_vertex()) { // single render pass
|
||||
const auto &layoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID);
|
||||
CC_ENSURES(!layoutName.empty());
|
||||
layoutID = locate(LayoutGraphData::null_vertex(), layoutName, lg);
|
||||
} else { // render pass
|
||||
const auto &passLayoutName = get(RenderGraph::LayoutTag{}, rg, passID);
|
||||
CC_ENSURES(!passLayoutName.empty());
|
||||
const auto passLayoutID = locate(LayoutGraphData::null_vertex(), passLayoutName, lg);
|
||||
CC_ENSURES(passLayoutID != LayoutGraphData::null_vertex());
|
||||
|
||||
const auto &subpassLayoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID);
|
||||
if (subpassLayoutName.empty()) {
|
||||
layoutID = passLayoutID; // expect to be multisample pass
|
||||
} else {
|
||||
const auto subpassLayoutID = locate(passLayoutID, subpassLayoutName, lg);
|
||||
CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex());
|
||||
layoutID = subpassLayoutID;
|
||||
}
|
||||
|
||||
}
|
||||
CC_ENSURES(layoutID != LayoutGraphData::null_vertex());
|
||||
return layoutID;
|
||||
}
|
||||
|
||||
inline std::tuple<RenderGraph::vertex_descriptor, LayoutGraphData::vertex_descriptor>
|
||||
addRenderPassVertex(
|
||||
RenderGraph &renderGraph, const LayoutGraphData &layoutGraph,
|
||||
uint32_t width, uint32_t height, // NOLINT(bugprone-easily-swappable-parameters)
|
||||
uint32_t count, uint32_t quality, // NOLINT(bugprone-easily-swappable-parameters)
|
||||
const ccstd::string &passName) {
|
||||
RasterPass pass(renderGraph.get_allocator());
|
||||
pass.width = width;
|
||||
pass.height = height;
|
||||
pass.viewport.width = width;
|
||||
pass.viewport.height = height;
|
||||
pass.count = count;
|
||||
pass.quality = quality;
|
||||
|
||||
auto passID = addVertex2(
|
||||
RasterPassTag{},
|
||||
std::forward_as_tuple(passName),
|
||||
std::forward_as_tuple(passName),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(std::move(pass)),
|
||||
renderGraph);
|
||||
|
||||
auto passLayoutID = locate(LayoutGraphData::null_vertex(), passName, layoutGraph);
|
||||
CC_EXPECTS(passLayoutID != LayoutGraphData::null_vertex());
|
||||
|
||||
return {passID, passLayoutID};
|
||||
}
|
||||
|
||||
inline std::tuple<RenderGraph::vertex_descriptor, LayoutGraphData::vertex_descriptor>
|
||||
addRenderSubpassVertex(
|
||||
RasterPass &pass,
|
||||
RenderGraph &renderGraph, RenderGraph::vertex_descriptor passID,
|
||||
const LayoutGraphData &layoutGraph, LayoutGraphData::vertex_descriptor passLayoutID,
|
||||
const ccstd::string &subpassName,
|
||||
uint32_t count, uint32_t quality) { // NOLINT(bugprone-easily-swappable-parameters)
|
||||
|
||||
// if subpassName is empty, it must be basic multisample render pass
|
||||
CC_EXPECTS(!subpassName.empty() || count > 1);
|
||||
|
||||
auto &subpassGraph = pass.subpassGraph;
|
||||
const auto subpassIndex = num_vertices(pass.subpassGraph);
|
||||
{
|
||||
auto id = addVertex(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(subpassName),
|
||||
std::forward_as_tuple(),
|
||||
subpassGraph);
|
||||
CC_ENSURES(id == subpassIndex);
|
||||
}
|
||||
|
||||
RasterSubpass subpass(subpassIndex, count, quality, renderGraph.get_allocator());
|
||||
subpass.viewport.width = pass.width;
|
||||
subpass.viewport.height = pass.height;
|
||||
|
||||
auto subpassID = addVertex2(
|
||||
RasterSubpassTag{},
|
||||
std::forward_as_tuple(subpassName),
|
||||
std::forward_as_tuple(subpassName),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(std::move(subpass)),
|
||||
renderGraph, passID);
|
||||
|
||||
auto subpassLayoutID = LayoutGraphData::null_vertex();
|
||||
if (subpassName.empty()) { // Basic multisample render pass (single subpass)
|
||||
CC_EXPECTS(count > 1);
|
||||
subpassLayoutID = passLayoutID;
|
||||
} else {
|
||||
if constexpr (ENABLE_SUBPASS) {
|
||||
subpassLayoutID = locate(passLayoutID, subpassName, layoutGraph);
|
||||
} else {
|
||||
subpassLayoutID = locate(LayoutGraphData::null_vertex(), subpassName, layoutGraph);
|
||||
}
|
||||
}
|
||||
CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex());
|
||||
|
||||
return {subpassID, subpassLayoutID};
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
void addPassComputeViewImpl(
|
||||
Tag tag,
|
||||
RenderGraph &renderGraph,
|
||||
RenderGraph::vertex_descriptor passID,
|
||||
const ccstd::string &name, const ComputeView &view) {
|
||||
std::ignore = tag;
|
||||
CC_EXPECTS(!name.empty());
|
||||
CC_EXPECTS(!view.name.empty());
|
||||
auto &pass = get(Tag{}, passID, renderGraph);
|
||||
auto iter = pass.computeViews.find(name.c_str());
|
||||
if (iter == pass.computeViews.end()) {
|
||||
bool added = false;
|
||||
std::tie(iter, added) = pass.computeViews.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(name.c_str()),
|
||||
std::forward_as_tuple());
|
||||
CC_ENSURES(added);
|
||||
}
|
||||
iter->second.emplace_back(view);
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
void addSubpassComputeViewImpl(
|
||||
Tag tag,
|
||||
RenderGraph &renderGraph,
|
||||
RenderGraph::vertex_descriptor subpassID,
|
||||
const ccstd::string &name, const ComputeView &view) {
|
||||
std::ignore = tag;
|
||||
CC_EXPECTS(!name.empty());
|
||||
CC_EXPECTS(!view.name.empty());
|
||||
auto &subpass = get(Tag{}, subpassID, renderGraph);
|
||||
const auto passID = parent(subpassID, renderGraph);
|
||||
CC_EXPECTS(passID != RenderGraph::null_vertex());
|
||||
CC_EXPECTS(holds<RasterPassTag>(passID, renderGraph));
|
||||
auto &pass = get(RasterPassTag{}, passID, renderGraph);
|
||||
CC_EXPECTS(subpass.subpassID < num_vertices(pass.subpassGraph));
|
||||
auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID);
|
||||
CC_EXPECTS(subpass.computeViews.size() == subpassData.computeViews.size());
|
||||
{
|
||||
auto iter = subpassData.computeViews.find(name.c_str());
|
||||
if (iter == subpassData.computeViews.end()) {
|
||||
bool added = false;
|
||||
std::tie(iter, added) = subpassData.computeViews.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(name.c_str()),
|
||||
std::forward_as_tuple());
|
||||
CC_ENSURES(added);
|
||||
}
|
||||
iter->second.emplace_back(view);
|
||||
}
|
||||
{
|
||||
auto iter = subpass.computeViews.find(name.c_str());
|
||||
if (iter == subpass.computeViews.end()) {
|
||||
bool added = false;
|
||||
std::tie(iter, added) = subpass.computeViews.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(name.c_str()),
|
||||
std::forward_as_tuple());
|
||||
CC_ENSURES(added);
|
||||
}
|
||||
iter->second.emplace_back(view);
|
||||
}
|
||||
CC_ENSURES(subpass.computeViews.size() == subpassData.computeViews.size());
|
||||
CC_ENSURES(subpass.computeViews.find(std::string_view{name}) != subpass.computeViews.end());
|
||||
CC_ENSURES(subpassData.computeViews.find(std::string_view{name}) != subpassData.computeViews.end());
|
||||
CC_ENSURES(subpass.computeViews.find(std::string_view{name})->second.size() ==
|
||||
subpassData.computeViews.find(std::string_view{name})->second.size());
|
||||
}
|
||||
|
||||
inline bool defaultAttachment(std::string_view slotName) {
|
||||
return slotName.empty() || slotName == "_";
|
||||
}
|
||||
|
||||
static constexpr std::string_view DEPTH_PLANE_NAME = "depth";
|
||||
static constexpr std::string_view STENCIL_PLANE_NAME = "stencil";
|
||||
static constexpr std::string_view CUBE_TOP_NAME = "top";
|
||||
static constexpr std::string_view CUBE_BOTTOM_NAME = "bottom";
|
||||
static constexpr std::string_view CUBE_FRONT_NAME = "front";
|
||||
static constexpr std::string_view CUBE_REAR_NAME = "rear";
|
||||
static constexpr std::string_view CUBE_LEFT_NAME = "left";
|
||||
static constexpr std::string_view CUBE_RIGHT_NAME = "right";
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
271
cocos/renderer/pipeline/custom/NativeRenderQueue.cpp
Normal file
271
cocos/renderer/pipeline/custom/NativeRenderQueue.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include "NativePipelineTypes.h"
|
||||
#include "cocos/renderer/pipeline/Define.h"
|
||||
#include "cocos/renderer/pipeline/InstancedBuffer.h"
|
||||
#include "cocos/renderer/pipeline/PipelineStateManager.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
LayoutGraphData::vertex_descriptor ProbeHelperQueue::getDefaultId(const LayoutGraphData &lg) {
|
||||
const auto passID = locate(LayoutGraphData::null_vertex(), "default", lg);
|
||||
CC_ENSURES(passID != LayoutGraphData::null_vertex());
|
||||
const auto phaseID = locate(passID, "default", lg);
|
||||
CC_ENSURES(phaseID != LayoutGraphData::null_vertex());
|
||||
return phaseID;
|
||||
}
|
||||
|
||||
void ProbeHelperQueue::removeMacro() const {
|
||||
for (auto *subModel : probeMap) {
|
||||
std::vector<cc::scene::IMacroPatch> patches;
|
||||
patches.insert(patches.end(), subModel->getPatches().begin(), subModel->getPatches().end());
|
||||
|
||||
for (int j = 0; j != patches.size(); ++j) {
|
||||
const cc::scene::IMacroPatch &patch = patches[j];
|
||||
if (patch.name == "CC_USE_RGBE_OUTPUT") {
|
||||
patches.erase(patches.begin() + j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
subModel->onMacroPatchesStateChanged(patches);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ProbeHelperQueue::getPassIndexFromLayout(
|
||||
const cc::IntrusivePtr<cc::scene::SubModel> &subModel,
|
||||
LayoutGraphData::vertex_descriptor phaseLayoutId) {
|
||||
const auto &passes = subModel->getPasses();
|
||||
for (uint32_t k = 0; k != passes->size(); ++k) {
|
||||
if (passes->at(k)->getPhaseID() == phaseLayoutId) {
|
||||
return static_cast<int>(k);
|
||||
}
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void ProbeHelperQueue::applyMacro(
|
||||
const LayoutGraphData &lg, const cc::scene::Model &model,
|
||||
LayoutGraphData::vertex_descriptor probeLayoutId) {
|
||||
const std::vector<cc::IntrusivePtr<cc::scene::SubModel>> &subModels = model.getSubModels();
|
||||
for (const auto &subModel : subModels) {
|
||||
const bool isTransparent = subModel->getPasses()->at(0)->getBlendState()->targets[0].blend;
|
||||
if (isTransparent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto passIdx = getPassIndexFromLayout(subModel, probeLayoutId);
|
||||
bool bUseReflectPass = true;
|
||||
if (passIdx < 0) {
|
||||
probeLayoutId = getDefaultId(lg);
|
||||
passIdx = getPassIndexFromLayout(subModel, probeLayoutId);
|
||||
bUseReflectPass = false;
|
||||
}
|
||||
if (passIdx < 0) {
|
||||
continue;
|
||||
}
|
||||
if (!bUseReflectPass) {
|
||||
std::vector<cc::scene::IMacroPatch> patches;
|
||||
patches.insert(patches.end(), subModel->getPatches().begin(), subModel->getPatches().end());
|
||||
const cc::scene::IMacroPatch useRGBEPatch = {"CC_USE_RGBE_OUTPUT", true};
|
||||
patches.emplace_back(useRGBEPatch);
|
||||
subModel->onMacroPatchesStateChanged(patches);
|
||||
probeMap.emplace_back(subModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
||||
void RenderDrawQueue::add(const scene::Model &model, float depth, uint32_t subModelIdx, uint32_t passIdx) {
|
||||
const auto *subModel = model.getSubModels()[subModelIdx].get();
|
||||
const auto *const pass = subModel->getPass(passIdx);
|
||||
|
||||
auto passPriority = static_cast<uint32_t>(pass->getPriority());
|
||||
auto modelPriority = static_cast<uint32_t>(subModel->getPriority());
|
||||
auto shaderId = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(subModel->getShader(passIdx)));
|
||||
const auto hash = (0 << 30) | (passPriority << 16) | (modelPriority << 8) | passIdx;
|
||||
const auto priority = model.getPriority();
|
||||
|
||||
instances.emplace_back(DrawInstance{subModel, priority, hash, depth, shaderId, passIdx});
|
||||
}
|
||||
|
||||
void RenderDrawQueue::sortOpaqueOrCutout() {
|
||||
std::sort(instances.begin(), instances.end(), [](const DrawInstance &lhs, const DrawInstance &rhs) {
|
||||
return std::forward_as_tuple(lhs.hash, lhs.depth, lhs.shaderID) <
|
||||
std::forward_as_tuple(rhs.hash, rhs.depth, rhs.shaderID);
|
||||
});
|
||||
}
|
||||
|
||||
void RenderDrawQueue::sortTransparent() {
|
||||
std::sort(instances.begin(), instances.end(), [](const DrawInstance &lhs, const DrawInstance &rhs) {
|
||||
return std::forward_as_tuple(lhs.priority, lhs.hash, -lhs.depth, lhs.shaderID) <
|
||||
std::forward_as_tuple(rhs.priority, rhs.hash, -rhs.depth, rhs.shaderID);
|
||||
});
|
||||
}
|
||||
|
||||
void RenderDrawQueue::recordCommandBuffer(
|
||||
gfx::RenderPass *renderPass, uint32_t subpassIndex,
|
||||
gfx::CommandBuffer *cmdBuff,
|
||||
uint32_t lightByteOffset) const {
|
||||
for (const auto &instance : instances) {
|
||||
const auto *subModel = instance.subModel;
|
||||
|
||||
const auto passIdx = instance.passIndex;
|
||||
auto *inputAssembler = subModel->getInputAssembler();
|
||||
const auto *pass = subModel->getPass(passIdx);
|
||||
auto *shader = subModel->getShader(passIdx);
|
||||
auto *pso = pipeline::PipelineStateManager::getOrCreatePipelineState(pass, shader, inputAssembler, renderPass, subpassIndex);
|
||||
|
||||
cmdBuff->bindPipelineState(pso);
|
||||
cmdBuff->bindDescriptorSet(pipeline::materialSet, pass->getDescriptorSet());
|
||||
if (lightByteOffset != 0xFFFFFFFF) {
|
||||
cmdBuff->bindDescriptorSet(pipeline::localSet, subModel->getDescriptorSet(), 1, &lightByteOffset);
|
||||
} else {
|
||||
cmdBuff->bindDescriptorSet(pipeline::localSet, subModel->getDescriptorSet());
|
||||
}
|
||||
cmdBuff->bindInputAssembler(inputAssembler);
|
||||
cmdBuff->draw(inputAssembler);
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderInstancingQueue::empty() const noexcept {
|
||||
CC_EXPECTS(!passInstances.empty() || sortedBatches.empty());
|
||||
return passInstances.empty();
|
||||
}
|
||||
|
||||
void RenderInstancingQueue::clear() {
|
||||
sortedBatches.clear();
|
||||
passInstances.clear();
|
||||
for (auto &buffer : instanceBuffers) {
|
||||
buffer->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderInstancingQueue::add(
|
||||
const scene::Pass &pass,
|
||||
scene::SubModel &submodel, uint32_t passID) {
|
||||
auto iter = passInstances.find(&pass);
|
||||
if (iter == passInstances.end()) {
|
||||
const auto instanceBufferID = static_cast<uint32_t>(passInstances.size());
|
||||
if (instanceBufferID >= instanceBuffers.size()) {
|
||||
CC_EXPECTS(instanceBufferID == instanceBuffers.size());
|
||||
instanceBuffers.emplace_back(ccnew pipeline::InstancedBuffer(nullptr));
|
||||
}
|
||||
bool added = false;
|
||||
std::tie(iter, added) = passInstances.emplace(&pass, instanceBufferID);
|
||||
CC_ENSURES(added);
|
||||
|
||||
CC_ENSURES(iter->second < instanceBuffers.size());
|
||||
const auto &instanceBuffer = instanceBuffers[iter->second];
|
||||
instanceBuffer->setPass(&pass);
|
||||
const auto &instances = instanceBuffer->getInstances();
|
||||
for (const auto &item : instances) {
|
||||
CC_EXPECTS(item.drawInfo.instanceCount == 0);
|
||||
}
|
||||
}
|
||||
auto &instancedBuffer = *instanceBuffers[iter->second];
|
||||
instancedBuffer.merge(&submodel, passID);
|
||||
}
|
||||
|
||||
void RenderInstancingQueue::sort() {
|
||||
sortedBatches.reserve(passInstances.size());
|
||||
for (const auto &[pass, bufferID] : passInstances) {
|
||||
sortedBatches.emplace_back(instanceBuffers[bufferID]);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderInstancingQueue::uploadBuffers(gfx::CommandBuffer *cmdBuffer) const {
|
||||
for (const auto &[pass, bufferID] : passInstances) {
|
||||
const auto &ib = instanceBuffers[bufferID];
|
||||
if (ib->hasPendingModels()) {
|
||||
ib->uploadBuffers(cmdBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderInstancingQueue::recordCommandBuffer(
|
||||
gfx::RenderPass *renderPass, uint32_t subpassIndex,
|
||||
gfx::CommandBuffer *cmdBuffer,
|
||||
uint32_t lightByteOffset) const { //
|
||||
const auto &renderQueue = sortedBatches;
|
||||
for (const auto *instanceBuffer : renderQueue) {
|
||||
if (!instanceBuffer->hasPendingModels()) {
|
||||
continue;
|
||||
}
|
||||
const auto &instances = instanceBuffer->getInstances();
|
||||
const auto *drawPass = instanceBuffer->getPass();
|
||||
cmdBuffer->bindDescriptorSet(pipeline::materialSet, drawPass->getDescriptorSet());
|
||||
gfx::PipelineState *lastPSO = nullptr;
|
||||
for (const auto &instance : instances) {
|
||||
if (!instance.drawInfo.instanceCount) {
|
||||
continue;
|
||||
}
|
||||
auto *pso = pipeline::PipelineStateManager::getOrCreatePipelineState(
|
||||
drawPass, instance.shader, instance.ia, renderPass, subpassIndex);
|
||||
if (lastPSO != pso) {
|
||||
cmdBuffer->bindPipelineState(pso);
|
||||
lastPSO = pso;
|
||||
}
|
||||
if (lightByteOffset != 0xFFFFFFFF) {
|
||||
cmdBuffer->bindDescriptorSet(pipeline::localSet, instance.descriptorSet, 1, &lightByteOffset);
|
||||
} else {
|
||||
cmdBuffer->bindDescriptorSet(pipeline::localSet, instance.descriptorSet, instanceBuffer->dynamicOffsets());
|
||||
}
|
||||
cmdBuffer->bindInputAssembler(instance.ia);
|
||||
cmdBuffer->draw(instance.ia);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeRenderQueue::sort() {
|
||||
opaqueQueue.sortOpaqueOrCutout();
|
||||
transparentQueue.sortTransparent();
|
||||
opaqueInstancingQueue.sort();
|
||||
transparentInstancingQueue.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);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
55
cocos/renderer/pipeline/custom/NativeRenderingModule.cpp
Normal file
55
cocos/renderer/pipeline/custom/NativeRenderingModule.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "LayoutGraphGraphs.h"
|
||||
#include "NativePipelineTypes.h"
|
||||
#include "details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
uint32_t NativeRenderingModule::getPassID(const ccstd::string &name) const {
|
||||
CC_EXPECTS(programLibrary);
|
||||
CC_EXPECTS(!name.empty());
|
||||
return locate(LayoutGraphData::null_vertex(), name, programLibrary->layoutGraph);
|
||||
}
|
||||
|
||||
uint32_t NativeRenderingModule::getSubpassID(uint32_t passID, const ccstd::string &name) const {
|
||||
CC_EXPECTS(programLibrary);
|
||||
CC_EXPECTS(!name.empty());
|
||||
CC_EXPECTS(passID != LayoutGraphData::null_vertex());
|
||||
return locate(passID, name, programLibrary->layoutGraph);
|
||||
}
|
||||
|
||||
uint32_t NativeRenderingModule::getPhaseID(uint32_t subpassOrPassID, const ccstd::string &name) const {
|
||||
CC_EXPECTS(programLibrary);
|
||||
CC_EXPECTS(!name.empty());
|
||||
CC_EXPECTS(subpassOrPassID != LayoutGraphData::null_vertex());
|
||||
return locate(subpassOrPassID, name, programLibrary->layoutGraph);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
455
cocos/renderer/pipeline/custom/NativeResourceGraph.cpp
Normal file
455
cocos/renderer/pipeline/custom/NativeResourceGraph.cpp
Normal file
@@ -0,0 +1,455 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
#include "NativePipelineTypes.h"
|
||||
#include "RenderGraphGraphs.h"
|
||||
#include "RenderGraphTypes.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDevice.h"
|
||||
#include "details/Range.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
#include "pipeline/custom/RenderCommonFwd.h"
|
||||
#include "cocos/scene/RenderWindow.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
ResourceGroup::~ResourceGroup() noexcept {
|
||||
for (const auto& buffer : instancingBuffers) {
|
||||
buffer->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramResource::syncResources() noexcept {
|
||||
for (auto&& [nameID, buffer] : uniformBuffers) {
|
||||
buffer.bufferPool.syncResources();
|
||||
}
|
||||
descriptorSetPool.syncDescriptorSets();
|
||||
}
|
||||
|
||||
void LayoutGraphNodeResource::syncResources() noexcept {
|
||||
for (auto&& [nameID, buffer] : uniformBuffers) {
|
||||
buffer.bufferPool.syncResources();
|
||||
}
|
||||
descriptorSetPool.syncDescriptorSets();
|
||||
for (auto&& [programName, programResource] : programResources) {
|
||||
programResource.syncResources();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeRenderContext::clearPreviousResources(uint64_t finishedFenceValue) noexcept {
|
||||
for (auto iter = resourceGroups.begin(); iter != resourceGroups.end();) {
|
||||
if (iter->first <= finishedFenceValue) {
|
||||
iter = resourceGroups.erase(iter);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto& node : layoutGraphResources) {
|
||||
node.syncResources();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
gfx::BufferInfo getBufferInfo(const ResourceDesc& desc) {
|
||||
using namespace gfx; // NOLINT(google-build-using-namespace)
|
||||
|
||||
BufferUsage usage = BufferUsage::TRANSFER_SRC | BufferUsage::TRANSFER_DST;
|
||||
if (any(desc.flags & ResourceFlags::UNIFORM)) {
|
||||
usage |= BufferUsage::UNIFORM;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::STORAGE)) {
|
||||
usage |= BufferUsage::STORAGE;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::INDIRECT)) {
|
||||
usage |= BufferUsage::INDIRECT;
|
||||
}
|
||||
|
||||
return {
|
||||
usage,
|
||||
MemoryUsage::DEVICE,
|
||||
desc.width,
|
||||
1U, // stride should not be used
|
||||
BufferFlagBit::NONE,
|
||||
};
|
||||
}
|
||||
|
||||
gfx::TextureInfo getTextureInfo(const ResourceDesc& desc) {
|
||||
using namespace gfx; // NOLINT(google-build-using-namespace)
|
||||
|
||||
// usage
|
||||
TextureUsage usage = TextureUsage::NONE;
|
||||
if (any(desc.flags & ResourceFlags::COLOR_ATTACHMENT)) {
|
||||
usage |= TextureUsage::COLOR_ATTACHMENT;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::DEPTH_STENCIL_ATTACHMENT)) {
|
||||
CC_EXPECTS(!any(desc.flags & ResourceFlags::COLOR_ATTACHMENT));
|
||||
usage |= TextureUsage::DEPTH_STENCIL_ATTACHMENT;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::INPUT_ATTACHMENT)) {
|
||||
usage |= TextureUsage::INPUT_ATTACHMENT;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::STORAGE)) {
|
||||
usage |= TextureUsage::STORAGE;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::SHADING_RATE)) {
|
||||
usage |= TextureUsage::SHADING_RATE;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::SAMPLED)) {
|
||||
usage |= TextureUsage::SAMPLED;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::TRANSFER_SRC)) {
|
||||
usage |= TextureUsage::TRANSFER_SRC;
|
||||
}
|
||||
if (any(desc.flags & ResourceFlags::TRANSFER_DST)) {
|
||||
usage |= TextureUsage::TRANSFER_DST;
|
||||
}
|
||||
|
||||
return {
|
||||
desc.viewType,
|
||||
usage,
|
||||
desc.format,
|
||||
desc.width,
|
||||
desc.height,
|
||||
desc.textureFlags,
|
||||
desc.viewType == TextureType::TEX3D ? 1U : desc.depthOrArraySize,
|
||||
desc.mipLevels,
|
||||
desc.sampleCount,
|
||||
desc.viewType == TextureType::TEX3D ? desc.depthOrArraySize : 1U,
|
||||
nullptr,
|
||||
};
|
||||
}
|
||||
|
||||
gfx::TextureViewInfo getTextureViewInfo(const SubresourceView& subresView, gfx::TextureType viewType) {
|
||||
using namespace gfx; // NOLINT(google-build-using-namespace)
|
||||
|
||||
return {
|
||||
nullptr,
|
||||
viewType,
|
||||
subresView.format,
|
||||
subresView.indexOrFirstMipLevel,
|
||||
subresView.numMipLevels,
|
||||
subresView.firstArraySlice,
|
||||
subresView.numArraySlices,
|
||||
subresView.firstPlane,
|
||||
subresView.numPlanes,
|
||||
};
|
||||
}
|
||||
|
||||
bool isTextureEqual(const gfx::Texture *texture, const ResourceDesc& desc) {
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
const auto& info = texture->getInfo();
|
||||
return desc.width == info.width && desc.height == info.height && desc.format == info.format;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ManagedTexture::checkResource(const ResourceDesc& desc) const {
|
||||
return isTextureEqual(texture.get(), desc);
|
||||
}
|
||||
|
||||
void ResourceGraph::validateSwapchains() {
|
||||
bool swapchainInvalidated = false;
|
||||
for (auto& sc : swapchains) {
|
||||
if (!sc.swapchain) {
|
||||
continue;
|
||||
}
|
||||
if (sc.generation != sc.swapchain->getGeneration()) {
|
||||
swapchainInvalidated = true;
|
||||
sc.generation = sc.swapchain->getGeneration();
|
||||
}
|
||||
}
|
||||
if (swapchainInvalidated) {
|
||||
renderPasses.clear();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::pair<SubresourceView, ResourceGraph::vertex_descriptor>
|
||||
getOriginView(const ResourceGraph& resg, ResourceGraph::vertex_descriptor vertID) {
|
||||
// copy origin view
|
||||
SubresourceView originView = get<SubresourceView>(vertID, resg);
|
||||
auto parentID = parent(vertID, resg);
|
||||
CC_EXPECTS(parentID != resg.null_vertex());
|
||||
while (resg.isTextureView(parentID)) {
|
||||
const auto& prtView = get(SubresourceViewTag{}, parentID, resg);
|
||||
originView.firstPlane += prtView.firstPlane;
|
||||
originView.firstArraySlice += prtView.firstArraySlice;
|
||||
originView.indexOrFirstMipLevel += prtView.indexOrFirstMipLevel;
|
||||
parentID = parent(parentID, resg);
|
||||
}
|
||||
CC_EXPECTS(parentID != resg.null_vertex());
|
||||
CC_EXPECTS(resg.isTexture(parentID));
|
||||
CC_ENSURES(!resg.isTextureView(parentID));
|
||||
return {originView, parentID};
|
||||
}
|
||||
|
||||
void recreateTextureView(
|
||||
gfx::Device* device,
|
||||
ResourceGraph& resg,
|
||||
const SubresourceView& originView,
|
||||
ResourceGraph::vertex_descriptor parentID,
|
||||
SubresourceView& view) {
|
||||
const auto& desc = get(ResourceGraph::DescTag{}, resg, parentID);
|
||||
auto textureViewInfo = getTextureViewInfo(originView, desc.viewType);
|
||||
const auto& parentTexture = resg.getTexture(parentID);
|
||||
CC_EXPECTS(parentTexture);
|
||||
textureViewInfo.texture = parentTexture;
|
||||
view.textureView = device->createTexture(textureViewInfo);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
void ResourceGraph::mount(gfx::Device* device, vertex_descriptor vertID) {
|
||||
std::ignore = device;
|
||||
auto& resg = *this;
|
||||
const auto& desc = get(ResourceGraph::DescTag{}, *this, vertID);
|
||||
visitObject(
|
||||
vertID, resg,
|
||||
[&](const ManagedResource& resource) {
|
||||
// to be removed
|
||||
},
|
||||
[&](ManagedBuffer& buffer) {
|
||||
if (!buffer.buffer) {
|
||||
auto info = getBufferInfo(desc);
|
||||
buffer.buffer = device->createBuffer(info);
|
||||
}
|
||||
CC_ENSURES(buffer.buffer);
|
||||
buffer.fenceValue = nextFenceValue;
|
||||
},
|
||||
[&](ManagedTexture& texture) {
|
||||
if (!texture.checkResource(desc)) {
|
||||
auto info = getTextureInfo(desc);
|
||||
texture.texture = device->createTexture(info);
|
||||
// recreate depth stencil views, currently is not recursive
|
||||
for (const auto& e : makeRange(children(vertID, *this))) {
|
||||
const auto childID = child(e, *this);
|
||||
auto* view = get_if<SubresourceView>(childID, this);
|
||||
if (view) {
|
||||
const auto [originView, parentID] = getOriginView(resg, childID);
|
||||
CC_ENSURES(parentID == vertID);
|
||||
recreateTextureView(device, *this, originView, parentID, *view);
|
||||
}
|
||||
}
|
||||
}
|
||||
CC_ENSURES(texture.texture);
|
||||
texture.fenceValue = nextFenceValue;
|
||||
},
|
||||
[&](const PersistentBuffer& buffer) {
|
||||
CC_EXPECTS(buffer.buffer);
|
||||
std::ignore = buffer;
|
||||
},
|
||||
[&](const PersistentTexture& texture) {
|
||||
CC_EXPECTS(texture.texture);
|
||||
std::ignore = texture;
|
||||
},
|
||||
[&](const IntrusivePtr<gfx::Framebuffer>& fb) {
|
||||
// deprecated
|
||||
CC_EXPECTS(false);
|
||||
CC_EXPECTS(fb);
|
||||
std::ignore = fb;
|
||||
},
|
||||
[&](const RenderSwapchain& window) {
|
||||
CC_EXPECTS(window.swapchain || window.renderWindow);
|
||||
std::ignore = window;
|
||||
},
|
||||
[&](const FormatView& view) { // NOLINT(misc-no-recursion)
|
||||
std::ignore = view;
|
||||
auto parentID = parent(vertID, resg);
|
||||
CC_EXPECTS(parentID != resg.null_vertex());
|
||||
while (resg.isTextureView(parentID)) {
|
||||
parentID = parent(parentID, resg);
|
||||
}
|
||||
CC_EXPECTS(parentID != resg.null_vertex());
|
||||
CC_EXPECTS(resg.isTexture(parentID));
|
||||
CC_ENSURES(!resg.isTextureView(parentID));
|
||||
mount(device, parentID);
|
||||
},
|
||||
[&](SubresourceView& view) { // NOLINT(misc-no-recursion)
|
||||
const auto [originView, parentID] = getOriginView(resg, vertID);
|
||||
mount(device, parentID); // NOLINT(misc-no-recursion)
|
||||
if (!isTextureEqual(view.textureView, desc)) {
|
||||
recreateTextureView(device, *this, originView, parentID, view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ResourceGraph::unmount(uint64_t completedFenceValue) {
|
||||
auto& resg = *this;
|
||||
for (const auto& vertID : makeRange(vertices(resg))) {
|
||||
// here msvc has strange behaviour when using visitObject
|
||||
// we use if-else instead.
|
||||
if (holds<ManagedBufferTag>(vertID, resg)) {
|
||||
auto& buffer = get(ManagedBufferTag{}, vertID, resg);
|
||||
if (buffer.buffer && buffer.fenceValue <= completedFenceValue) {
|
||||
buffer.buffer.reset();
|
||||
}
|
||||
} else if (holds<ManagedTextureTag>(vertID, resg)) {
|
||||
auto& texture = get(ManagedTextureTag{}, vertID, resg);
|
||||
if (texture.texture && texture.fenceValue <= completedFenceValue) {
|
||||
invalidatePersistentRenderPassAndFramebuffer(texture.texture.get());
|
||||
texture.texture.reset();
|
||||
const auto& traits = get(ResourceGraph::TraitsTag{}, resg, vertID);
|
||||
if (traits.hasSideEffects()) {
|
||||
auto& states = get(ResourceGraph::StatesTag{}, resg, vertID);
|
||||
states.states = cc::gfx::AccessFlagBit::NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ResourceGraph::isTexture(vertex_descriptor resID) const noexcept {
|
||||
return visitObject(
|
||||
resID, *this,
|
||||
[&](const ManagedBuffer& res) {
|
||||
std::ignore = res;
|
||||
return false;
|
||||
},
|
||||
[&](const IntrusivePtr<gfx::Buffer>& res) {
|
||||
std::ignore = res;
|
||||
return false;
|
||||
},
|
||||
[&](const auto& res) {
|
||||
std::ignore = res;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool ResourceGraph::isTextureView(vertex_descriptor resID) const noexcept {
|
||||
return visitObject(
|
||||
resID, *this,
|
||||
[&](const FormatView& view) {
|
||||
std::ignore = view;
|
||||
return true;
|
||||
},
|
||||
[&](const SubresourceView& view) {
|
||||
std::ignore = view;
|
||||
return true;
|
||||
},
|
||||
[&](const auto& res) {
|
||||
std::ignore = res;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
gfx::Buffer* ResourceGraph::getBuffer(vertex_descriptor resID) {
|
||||
gfx::Buffer* buffer = nullptr;
|
||||
visitObject(
|
||||
resID, *this,
|
||||
[&](const ManagedBuffer& res) {
|
||||
buffer = res.buffer.get();
|
||||
},
|
||||
[&](const IntrusivePtr<gfx::Buffer>& buf) {
|
||||
buffer = buf.get();
|
||||
},
|
||||
[&](const auto& buffer) {
|
||||
std::ignore = buffer;
|
||||
CC_EXPECTS(false);
|
||||
});
|
||||
CC_ENSURES(buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
gfx::Texture* ResourceGraph::getTexture(vertex_descriptor resID) {
|
||||
gfx::Texture* texture = nullptr;
|
||||
visitObject(
|
||||
resID, *this,
|
||||
[&](const ManagedTexture& res) {
|
||||
texture = res.texture.get();
|
||||
},
|
||||
[&](const IntrusivePtr<gfx::Texture>& tex) {
|
||||
texture = tex.get();
|
||||
},
|
||||
[&](const IntrusivePtr<gfx::Framebuffer>& fb) {
|
||||
// deprecated
|
||||
CC_EXPECTS(false);
|
||||
CC_EXPECTS(fb->getColorTextures().size() == 1);
|
||||
CC_EXPECTS(fb->getColorTextures().at(0));
|
||||
texture = fb->getColorTextures()[0];
|
||||
},
|
||||
[&](const RenderSwapchain& sc) {
|
||||
if (sc.swapchain) {
|
||||
texture = sc.swapchain->getColorTexture();
|
||||
} else {
|
||||
CC_EXPECTS(sc.renderWindow);
|
||||
const auto& fb = sc.renderWindow->getFramebuffer();
|
||||
CC_EXPECTS(fb);
|
||||
CC_EXPECTS(fb->getColorTextures().size() == 1);
|
||||
CC_EXPECTS(fb->getColorTextures().at(0));
|
||||
texture = fb->getColorTextures()[0];
|
||||
}
|
||||
},
|
||||
[&](const FormatView& view) {
|
||||
// TODO(zhouzhenglong): add ImageView support
|
||||
std::ignore = view;
|
||||
CC_EXPECTS(false);
|
||||
},
|
||||
[&](const SubresourceView& view) {
|
||||
// TODO(zhouzhenglong): add ImageView support
|
||||
texture = view.textureView;
|
||||
},
|
||||
[&](const auto& buffer) {
|
||||
std::ignore = buffer;
|
||||
CC_EXPECTS(false);
|
||||
});
|
||||
CC_ENSURES(texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void ResourceGraph::invalidatePersistentRenderPassAndFramebuffer(gfx::Texture* pTexture) {
|
||||
if (!pTexture) {
|
||||
return;
|
||||
}
|
||||
for (auto iter = renderPasses.begin(); iter != renderPasses.end();) {
|
||||
const auto& pass = iter->second;
|
||||
bool bErase = false;
|
||||
for (const auto& color : pass.framebuffer->getColorTextures()) {
|
||||
if (color == pTexture) {
|
||||
bErase = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pass.framebuffer->getDepthStencilTexture() == pTexture) {
|
||||
bErase = true;
|
||||
}
|
||||
if (bErase) {
|
||||
iter = renderPasses.erase(iter);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
816
cocos/renderer/pipeline/custom/NativeSceneCulling.cpp
Normal file
816
cocos/renderer/pipeline/custom/NativeSceneCulling.cpp
Normal file
@@ -0,0 +1,816 @@
|
||||
#include "cocos/renderer/pipeline/Define.h"
|
||||
#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/details/GslUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Range.h"
|
||||
#include "cocos/scene/Octree.h"
|
||||
#include "cocos/scene/ReflectionProbe.h"
|
||||
#include "cocos/scene/RenderScene.h"
|
||||
#include "cocos/scene/Skybox.h"
|
||||
#include "cocos/scene/SpotLight.h"
|
||||
|
||||
#include <boost/align/align_up.hpp>
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
const static uint32_t REFLECTION_PROBE_DEFAULT_MASK = ~static_cast<uint32_t>(pipeline::LayerList::UI_2D) & ~static_cast<uint32_t>(pipeline::LayerList::PROFILER) & ~static_cast<uint32_t>(pipeline::LayerList::UI_3D) & ~static_cast<uint32_t>(pipeline::LayerList::GIZMOS) & ~static_cast<uint32_t>(pipeline::LayerList::SCENE_GIZMO) & ~static_cast<uint32_t>(pipeline::LayerList::EDITOR);
|
||||
|
||||
void NativeRenderQueue::clear() noexcept {
|
||||
probeQueue.clear();
|
||||
opaqueQueue.instances.clear();
|
||||
transparentQueue.instances.clear();
|
||||
opaqueInstancingQueue.clear();
|
||||
transparentInstancingQueue.clear();
|
||||
sceneFlags = SceneFlags::NONE;
|
||||
subpassOrPassLayoutID = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
bool NativeRenderQueue::empty() const noexcept {
|
||||
return opaqueQueue.instances.empty() &&
|
||||
transparentQueue.instances.empty() &&
|
||||
opaqueInstancingQueue.empty() &&
|
||||
transparentInstancingQueue.empty();
|
||||
}
|
||||
|
||||
FrustumCullingID SceneCulling::getOrCreateFrustumCulling(const SceneData& sceneData) {
|
||||
const auto* const scene = sceneData.scene;
|
||||
// get or add scene to queries
|
||||
auto& queries = frustumCullings[scene];
|
||||
|
||||
// check cast shadow
|
||||
const bool bCastShadow = any(sceneData.flags & SceneFlags::SHADOW_CASTER);
|
||||
|
||||
// get or create query source
|
||||
// make query key
|
||||
const auto key = FrustumCullingKey{
|
||||
sceneData.camera,
|
||||
sceneData.light.probe,
|
||||
sceneData.light.light,
|
||||
sceneData.light.level,
|
||||
bCastShadow,
|
||||
};
|
||||
|
||||
// find query source
|
||||
auto iter = queries.resultIndex.find(key);
|
||||
if (iter == queries.resultIndex.end()) {
|
||||
// create query source
|
||||
// make query source id
|
||||
const FrustumCullingID frustomCulledResultID{numFrustumCulling++};
|
||||
if (numFrustumCulling > frustumCullingResults.size()) {
|
||||
// space is not enough, create query source
|
||||
CC_EXPECTS(numFrustumCulling == frustumCullingResults.size() + 1);
|
||||
frustumCullingResults.emplace_back();
|
||||
}
|
||||
// add query source to query index
|
||||
bool added = false;
|
||||
std::tie(iter, added) = queries.resultIndex.emplace(key, frustomCulledResultID);
|
||||
CC_ENSURES(added);
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
LightBoundsCullingID SceneCulling::getOrCreateLightBoundsCulling(
|
||||
const SceneData& sceneData, FrustumCullingID frustumCullingID) {
|
||||
if (!any(sceneData.cullingFlags & CullingFlags::LIGHT_BOUNDS)) {
|
||||
return {};
|
||||
}
|
||||
if (sceneData.shadingLight->getType() == scene::LightType::DIRECTIONAL) {
|
||||
return {};
|
||||
}
|
||||
if (!enableLightCulling) {
|
||||
return {};
|
||||
}
|
||||
|
||||
CC_EXPECTS(sceneData.shadingLight);
|
||||
const auto* const scene = sceneData.scene;
|
||||
CC_EXPECTS(scene);
|
||||
|
||||
auto& queries = lightBoundsCullings[scene];
|
||||
|
||||
// get or create query source
|
||||
// make query key
|
||||
const auto key = LightBoundsCullingKey{
|
||||
frustumCullingID,
|
||||
sceneData.camera,
|
||||
sceneData.light.probe,
|
||||
sceneData.shadingLight,
|
||||
};
|
||||
|
||||
// find query source
|
||||
auto iter = queries.resultIndex.find(key);
|
||||
if (iter == queries.resultIndex.end()) {
|
||||
// create query source
|
||||
// make query source id
|
||||
const LightBoundsCullingID lightBoundsCullingID{numLightBoundsCulling++};
|
||||
if (numLightBoundsCulling > lightBoundsCullingResults.size()) {
|
||||
// space is not enough, create query source
|
||||
CC_EXPECTS(numLightBoundsCulling == lightBoundsCullingResults.size() + 1);
|
||||
lightBoundsCullingResults.emplace_back();
|
||||
}
|
||||
// add query source to query index
|
||||
bool added = false;
|
||||
std::tie(iter, added) = queries.resultIndex.emplace(key, lightBoundsCullingID);
|
||||
CC_ENSURES(added);
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
NativeRenderQueueID SceneCulling::createRenderQueue(
|
||||
SceneFlags sceneFlags, LayoutGraphData::vertex_descriptor subpassOrPassLayoutID) {
|
||||
const auto targetID = numRenderQueues++;
|
||||
if (numRenderQueues > renderQueues.size()) {
|
||||
CC_EXPECTS(numRenderQueues == renderQueues.size() + 1);
|
||||
renderQueues.emplace_back();
|
||||
}
|
||||
CC_ENSURES(targetID < renderQueues.size());
|
||||
auto& rq = renderQueues[targetID];
|
||||
CC_EXPECTS(rq.empty());
|
||||
CC_EXPECTS(rq.sceneFlags == SceneFlags::NONE);
|
||||
CC_EXPECTS(rq.subpassOrPassLayoutID == 0xFFFFFFFF);
|
||||
rq.sceneFlags = sceneFlags;
|
||||
rq.subpassOrPassLayoutID = subpassOrPassLayoutID;
|
||||
return NativeRenderQueueID{targetID};
|
||||
}
|
||||
|
||||
void SceneCulling::collectCullingQueries(
|
||||
const RenderGraph& rg, const LayoutGraphData& lg) {
|
||||
for (const auto vertID : makeRange(vertices(rg))) {
|
||||
if (!holds<SceneTag>(vertID, rg)) {
|
||||
continue;
|
||||
}
|
||||
const auto& sceneData = get(SceneTag{}, vertID, rg);
|
||||
if (!sceneData.scene) {
|
||||
CC_EXPECTS(false);
|
||||
continue;
|
||||
}
|
||||
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(
|
||||
vertID,
|
||||
NativeRenderQueueDesc{
|
||||
frustomCulledResultID,
|
||||
lightBoundsCullingID,
|
||||
targetID,
|
||||
lightType,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pipeline::PipelineSceneData* kPipelineSceneData = nullptr;
|
||||
|
||||
const LayoutGraphData* kLayoutGraph = nullptr;
|
||||
|
||||
bool isNodeVisible(const Node* node, uint32_t visibility) {
|
||||
return node && ((visibility & node->getLayer()) == node->getLayer());
|
||||
}
|
||||
|
||||
uint32_t isModelVisible(const scene::Model& model, uint32_t visibility) {
|
||||
return visibility & static_cast<uint32_t>(model.getVisFlags());
|
||||
}
|
||||
|
||||
bool isReflectProbeMask(const scene::Model& model) {
|
||||
return ((model.getNode()->getLayer() & REFLECTION_PROBE_DEFAULT_MASK) == model.getNode()->getLayer()) || (REFLECTION_PROBE_DEFAULT_MASK & static_cast<uint32_t>(model.getVisFlags()));
|
||||
}
|
||||
|
||||
bool isIntersectAABB(const geometry::AABB& lAABB, const geometry::AABB& rAABB) {
|
||||
return !lAABB.aabbAabb(rAABB);
|
||||
}
|
||||
|
||||
bool isFrustumVisible(const scene::Model& model, const geometry::Frustum& frustum, bool castShadow) {
|
||||
const auto* const modelWorldBounds = model.getWorldBounds();
|
||||
if (!modelWorldBounds) {
|
||||
return false;
|
||||
}
|
||||
geometry::AABB transWorldBounds{};
|
||||
transWorldBounds.set(modelWorldBounds->getCenter(), modelWorldBounds->getHalfExtents());
|
||||
const scene::Shadows& shadows = *kPipelineSceneData->getShadows();
|
||||
if (shadows.getType() == scene::ShadowType::PLANAR && castShadow) {
|
||||
modelWorldBounds->transform(shadows.getMatLight(), &transWorldBounds);
|
||||
}
|
||||
return !transWorldBounds.aabbFrustum(frustum);
|
||||
}
|
||||
|
||||
void octreeCulling(
|
||||
const scene::Octree& octree,
|
||||
const scene::Model* skyboxModel,
|
||||
const scene::RenderScene& scene,
|
||||
const scene::Camera& camera,
|
||||
const geometry::Frustum& cameraOrLightFrustum,
|
||||
bool bCastShadow,
|
||||
ccstd::vector<const scene::Model*>& models) {
|
||||
const auto visibility = camera.getVisibility();
|
||||
const auto camSkyboxFlag = (static_cast<int32_t>(camera.getClearFlag()) & scene::Camera::SKYBOX_FLAG);
|
||||
if (!bCastShadow && skyboxModel && camSkyboxFlag) {
|
||||
models.emplace_back(skyboxModel);
|
||||
}
|
||||
// add instances without world bounds
|
||||
for (const auto& pModel : scene.getModels()) {
|
||||
CC_EXPECTS(pModel);
|
||||
const auto& model = *pModel;
|
||||
if (!model.isEnabled() || !model.getNode() || model.getWorldBounds() || (bCastShadow && !model.isCastShadow())) {
|
||||
continue;
|
||||
}
|
||||
// filter model by view visibility
|
||||
if (isNodeVisible(model.getNode(), visibility) || isModelVisible(model, visibility)) {
|
||||
models.emplace_back(&model);
|
||||
}
|
||||
}
|
||||
// add instances with world bounds
|
||||
octree.queryVisibility(&camera, cameraOrLightFrustum, bCastShadow, models);
|
||||
|
||||
// TODO(zhouzhenglong): move lod culling into octree query
|
||||
auto iter = std::remove_if(
|
||||
models.begin(), models.end(),
|
||||
[&](const scene::Model* model) {
|
||||
return scene.isCulledByLod(&camera, model);
|
||||
});
|
||||
models.erase(iter, models.end());
|
||||
}
|
||||
|
||||
void bruteForceCulling(
|
||||
const scene::Model* skyboxModel,
|
||||
const scene::RenderScene& scene,
|
||||
const scene::Camera& camera,
|
||||
const geometry::Frustum& cameraOrLightFrustum,
|
||||
bool bCastShadow,
|
||||
const scene::ReflectionProbe* probe,
|
||||
ccstd::vector<const scene::Model*>& models) {
|
||||
const auto visibility = camera.getVisibility();
|
||||
const auto camSkyboxFlag = (static_cast<int32_t>(camera.getClearFlag()) & scene::Camera::SKYBOX_FLAG);
|
||||
if (!bCastShadow && skyboxModel && camSkyboxFlag) {
|
||||
models.emplace_back(skyboxModel);
|
||||
}
|
||||
for (const auto& pModel : scene.getModels()) {
|
||||
CC_EXPECTS(pModel);
|
||||
const auto& model = *pModel;
|
||||
if (!model.isEnabled() || !model.getNode() || (bCastShadow && !model.isCastShadow())) {
|
||||
continue;
|
||||
}
|
||||
// lod culling
|
||||
if (scene.isCulledByLod(&camera, &model)) {
|
||||
continue;
|
||||
}
|
||||
if (!probe || (probe && probe->getProbeType() == cc::scene::ReflectionProbe::ProbeType::CUBE)) {
|
||||
// filter model by view visibility
|
||||
if (isNodeVisible(model.getNode(), visibility) || isModelVisible(model, visibility)) {
|
||||
const auto* const wBounds = model.getWorldBounds();
|
||||
// frustum culling
|
||||
if (wBounds && ((!probe && isFrustumVisible(model, cameraOrLightFrustum, bCastShadow)) ||
|
||||
(probe && isIntersectAABB(*wBounds, *probe->getBoundingBox())))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
models.emplace_back(&model);
|
||||
}
|
||||
} else if (isReflectProbeMask(model)) {
|
||||
models.emplace_back(&model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sceneCulling(
|
||||
const scene::Model* skyboxModel,
|
||||
const scene::RenderScene& scene,
|
||||
const scene::Camera& camera,
|
||||
const geometry::Frustum& cameraOrLightFrustum,
|
||||
bool bCastShadow,
|
||||
const scene::ReflectionProbe* probe,
|
||||
ccstd::vector<const scene::Model*>& models) {
|
||||
const auto* const octree = scene.getOctree();
|
||||
if (octree && octree->isEnabled() && !probe) {
|
||||
octreeCulling(
|
||||
*octree, skyboxModel,
|
||||
scene, camera, cameraOrLightFrustum, bCastShadow, models);
|
||||
} else {
|
||||
bruteForceCulling(
|
||||
skyboxModel,
|
||||
scene, camera, cameraOrLightFrustum, bCastShadow, probe, models);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SceneCulling::batchFrustumCulling(const NativePipeline& ppl) {
|
||||
const auto& pplSceneData = *ppl.getPipelineSceneData();
|
||||
const auto* const skybox = pplSceneData.getSkybox();
|
||||
const auto* const skyboxModel = skybox && skybox->isEnabled() ? skybox->getModel() : nullptr;
|
||||
|
||||
for (const auto& [scene, queries] : frustumCullings) {
|
||||
CC_ENSURES(scene);
|
||||
for (const auto& [key, frustomCulledResultID] : queries.resultIndex) {
|
||||
CC_EXPECTS(key.camera);
|
||||
CC_EXPECTS(key.camera->getScene() == scene);
|
||||
const auto* light = key.light;
|
||||
const auto level = key.lightLevel;
|
||||
const auto bCastShadow = key.castShadow;
|
||||
const auto* probe = key.probe;
|
||||
const auto& camera = probe ? *probe->getCamera() : *key.camera;
|
||||
CC_EXPECTS(frustomCulledResultID.value < frustumCullingResults.size());
|
||||
auto& models = frustumCullingResults[frustomCulledResultID.value];
|
||||
|
||||
if (probe) {
|
||||
sceneCulling(
|
||||
skyboxModel,
|
||||
*scene, camera,
|
||||
camera.getFrustum(),
|
||||
bCastShadow,
|
||||
probe,
|
||||
models);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (light) {
|
||||
switch (light->getType()) {
|
||||
case scene::LightType::SPOT:
|
||||
sceneCulling(
|
||||
skyboxModel,
|
||||
*scene, camera,
|
||||
dynamic_cast<const scene::SpotLight*>(light)->getFrustum(),
|
||||
bCastShadow,
|
||||
nullptr,
|
||||
models);
|
||||
break;
|
||||
case scene::LightType::DIRECTIONAL: {
|
||||
const auto* mainLight = dynamic_cast<const scene::DirectionalLight*>(light);
|
||||
const auto& frustum = getBuiltinShadowFrustum(ppl, camera, mainLight, level);
|
||||
sceneCulling(
|
||||
skyboxModel,
|
||||
*scene, camera,
|
||||
frustum,
|
||||
bCastShadow,
|
||||
nullptr,
|
||||
models);
|
||||
} break;
|
||||
default:
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sceneCulling(
|
||||
skyboxModel,
|
||||
*scene, camera,
|
||||
camera.getFrustum(),
|
||||
bCastShadow,
|
||||
nullptr,
|
||||
models);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void executeSphereLightCulling(
|
||||
const scene::SphereLight& light,
|
||||
const ccstd::vector<const scene::Model*>& frustumCullingResult,
|
||||
ccstd::vector<const scene::Model*>& lightBoundsCullingResult) {
|
||||
const auto& lightAABB = light.getAABB();
|
||||
for (const auto* const model : frustumCullingResult) {
|
||||
CC_EXPECTS(model);
|
||||
const auto* const modelBounds = model->getWorldBounds();
|
||||
if (!modelBounds || modelBounds->aabbAabb(lightAABB)) {
|
||||
lightBoundsCullingResult.emplace_back(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void executeSpotLightCulling(
|
||||
const scene::SpotLight& light,
|
||||
const ccstd::vector<const scene::Model*>& frustumCullingResult,
|
||||
ccstd::vector<const scene::Model*>& lightBoundsCullingResult) {
|
||||
const auto& lightAABB = light.getAABB();
|
||||
const auto& lightFrustum = light.getFrustum();
|
||||
for (const auto* const model : frustumCullingResult) {
|
||||
CC_EXPECTS(model);
|
||||
const auto* const modelBounds = model->getWorldBounds();
|
||||
if (!modelBounds || (modelBounds->aabbAabb(lightAABB) && modelBounds->aabbFrustum(lightFrustum))) {
|
||||
lightBoundsCullingResult.emplace_back(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void executePointLightCulling(
|
||||
const scene::PointLight& light,
|
||||
const ccstd::vector<const scene::Model*>& frustumCullingResult,
|
||||
ccstd::vector<const scene::Model*>& lightBoundsCullingResult) {
|
||||
const auto& lightAABB = light.getAABB();
|
||||
for (const auto* const model : frustumCullingResult) {
|
||||
CC_EXPECTS(model);
|
||||
const auto* const modelBounds = model->getWorldBounds();
|
||||
if (!modelBounds || modelBounds->aabbAabb(lightAABB)) {
|
||||
lightBoundsCullingResult.emplace_back(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void executeRangedDirectionalLightCulling(
|
||||
const scene::RangedDirectionalLight& light,
|
||||
const ccstd::vector<const scene::Model*>& frustumCullingResult,
|
||||
ccstd::vector<const scene::Model*>& lightBoundsCullingResult) {
|
||||
const geometry::AABB rangedDirLightBoundingBox(0.0F, 0.0F, 0.0F, 0.5F, 0.5F, 0.5F);
|
||||
// when execute render graph, we should never update world matrix
|
||||
// light->getNode()->updateWorldTransform();
|
||||
geometry::AABB lightAABB{};
|
||||
rangedDirLightBoundingBox.transform(light.getNode()->getWorldMatrix(), &lightAABB);
|
||||
for (const auto* const model : frustumCullingResult) {
|
||||
CC_EXPECTS(model);
|
||||
const auto* const modelBounds = model->getWorldBounds();
|
||||
if (!modelBounds || modelBounds->aabbAabb(lightAABB)) {
|
||||
lightBoundsCullingResult.emplace_back(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SceneCulling::batchLightBoundsCulling() {
|
||||
for (const auto& [scene, queries] : lightBoundsCullings) {
|
||||
CC_ENSURES(scene);
|
||||
for (const auto& [key, cullingID] : queries.resultIndex) {
|
||||
CC_EXPECTS(key.camera);
|
||||
CC_EXPECTS(key.camera->getScene() == scene);
|
||||
const auto& frustumCullingResult = frustumCullingResults.at(key.frustumCullingID.value);
|
||||
auto& lightBoundsCullingResult = lightBoundsCullingResults.at(cullingID.value);
|
||||
CC_EXPECTS(lightBoundsCullingResult.instances.empty());
|
||||
switch (key.cullingLight->getType()) {
|
||||
case scene::LightType::SPHERE: {
|
||||
const auto* light = dynamic_cast<const scene::SphereLight*>(key.cullingLight);
|
||||
CC_ENSURES(light);
|
||||
executeSphereLightCulling(*light, frustumCullingResult, lightBoundsCullingResult.instances);
|
||||
} break;
|
||||
case scene::LightType::SPOT: {
|
||||
const auto* light = dynamic_cast<const scene::SpotLight*>(key.cullingLight);
|
||||
CC_ENSURES(light);
|
||||
executeSpotLightCulling(*light, frustumCullingResult, lightBoundsCullingResult.instances);
|
||||
} break;
|
||||
case scene::LightType::POINT: {
|
||||
const auto* light = dynamic_cast<const scene::PointLight*>(key.cullingLight);
|
||||
CC_ENSURES(light);
|
||||
executePointLightCulling(*light, frustumCullingResult, lightBoundsCullingResult.instances);
|
||||
} break;
|
||||
case scene::LightType::RANGED_DIRECTIONAL: {
|
||||
const auto* light = dynamic_cast<const scene::RangedDirectionalLight*>(key.cullingLight);
|
||||
CC_ENSURES(light);
|
||||
executeRangedDirectionalLightCulling(*light, frustumCullingResult, lightBoundsCullingResult.instances);
|
||||
} break;
|
||||
case scene::LightType::DIRECTIONAL:
|
||||
case scene::LightType::UNKNOWN:
|
||||
default:
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool isBlend(const scene::Pass& pass) {
|
||||
bool bBlend = false;
|
||||
for (const auto& target : pass.getBlendState()->targets) {
|
||||
if (target.blend) {
|
||||
bBlend = true;
|
||||
}
|
||||
}
|
||||
return bBlend;
|
||||
}
|
||||
|
||||
float computeSortingDepth(const scene::Camera& camera, const scene::Model& model) {
|
||||
float depth = 0;
|
||||
if (model.getNode()) {
|
||||
const auto* node = model.getTransform();
|
||||
Vec3 position;
|
||||
const auto* bounds = model.getWorldBounds();
|
||||
Vec3::subtract(bounds ? bounds->center : node->getWorldPosition(), camera.getPosition(), &position);
|
||||
depth = position.dot(camera.getForward());
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
void addRenderObject(
|
||||
LayoutGraphData::vertex_descriptor phaseLayoutID,
|
||||
const bool bDrawOpaqueOrMask,
|
||||
const bool bDrawBlend,
|
||||
const bool bDrawProbe,
|
||||
const scene::Camera& camera,
|
||||
const scene::Model& model,
|
||||
NativeRenderQueue& queue) {
|
||||
if (bDrawProbe) {
|
||||
queue.probeQueue.applyMacro(*kLayoutGraph, model, phaseLayoutID);
|
||||
}
|
||||
const auto& subModels = model.getSubModels();
|
||||
const auto subModelCount = subModels.size();
|
||||
for (uint32_t subModelIdx = 0; subModelIdx < subModelCount; ++subModelIdx) {
|
||||
const auto& subModel = subModels[subModelIdx];
|
||||
const auto& passes = *(subModel->getPasses());
|
||||
const auto passCount = passes.size();
|
||||
auto probeIt = std::find(queue.probeQueue.probeMap.begin(), queue.probeQueue.probeMap.end(), subModel.get());
|
||||
if (probeIt != queue.probeQueue.probeMap.end()) {
|
||||
phaseLayoutID = ProbeHelperQueue::getDefaultId(*kLayoutGraph);
|
||||
}
|
||||
for (uint32_t passIdx = 0; passIdx < passCount; ++passIdx) {
|
||||
auto& pass = *passes[passIdx];
|
||||
// check phase
|
||||
const bool bRenderPhaseAllowed = phaseLayoutID == pass.getPhaseID();
|
||||
if (!bRenderPhaseAllowed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check scene flags
|
||||
const bool bBlend = isBlend(pass);
|
||||
const bool bOpaqueOrMask = !bBlend;
|
||||
if (!bDrawBlend && bBlend) {
|
||||
// skip transparent object
|
||||
continue;
|
||||
}
|
||||
if (!bDrawOpaqueOrMask && bOpaqueOrMask) {
|
||||
// skip opaque object
|
||||
continue;
|
||||
}
|
||||
|
||||
// add object to queue
|
||||
if (pass.getBatchingScheme() == scene::BatchingSchemes::INSTANCING) {
|
||||
if (bBlend) {
|
||||
queue.transparentInstancingQueue.add(pass, *subModel, passIdx);
|
||||
} else {
|
||||
queue.opaqueInstancingQueue.add(pass, *subModel, passIdx);
|
||||
}
|
||||
} else {
|
||||
// TODO(zhouzhenglong): change camera to frustum
|
||||
const float depth = computeSortingDepth(camera, model);
|
||||
if (bBlend) {
|
||||
queue.transparentQueue.add(model, depth, subModelIdx, passIdx);
|
||||
} else {
|
||||
queue.opaqueQueue.add(model, depth, subModelIdx, passIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SceneCulling::fillRenderQueues(
|
||||
const RenderGraph& rg, const pipeline::PipelineSceneData& pplSceneData) {
|
||||
const auto* const skybox = pplSceneData.getSkybox();
|
||||
for (auto&& [sceneID, desc] : renderQueueIndex) {
|
||||
CC_EXPECTS(holds<SceneTag>(sceneID, rg));
|
||||
const auto frustomCulledResultID = desc.frustumCulledResultID;
|
||||
const auto lightBoundsCullingID = desc.lightBoundsCulledResultID;
|
||||
const auto targetID = desc.renderQueueTarget;
|
||||
const auto& sceneData = get(SceneTag{}, sceneID, rg);
|
||||
|
||||
// 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);
|
||||
if (!bDrawShadowCaster && !bDrawBlend && !bDrawOpaqueOrMask && !bDrawProbe) {
|
||||
// nothing to draw
|
||||
continue;
|
||||
}
|
||||
|
||||
// render queue info
|
||||
const auto renderQueueID = parent(sceneID, rg);
|
||||
CC_EXPECTS(holds<QueueTag>(renderQueueID, rg));
|
||||
const auto& renderQueue = get(QueueTag{}, renderQueueID, rg);
|
||||
const auto phaseLayoutID = renderQueue.phaseID;
|
||||
CC_EXPECTS(phaseLayoutID != LayoutGraphData::null_vertex());
|
||||
|
||||
// culling source
|
||||
CC_EXPECTS(frustomCulledResultID.value < frustumCullingResults.size());
|
||||
const auto& sourceModels = [&]() -> const auto& {
|
||||
// is culled by light bounds
|
||||
if (lightBoundsCullingID.value != 0xFFFFFFFF) {
|
||||
CC_EXPECTS(lightBoundsCullingID.value < lightBoundsCullingResults.size());
|
||||
return lightBoundsCullingResults.at(lightBoundsCullingID.value).instances;
|
||||
}
|
||||
// not culled by light bounds
|
||||
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;
|
||||
CC_EXPECTS(camera);
|
||||
|
||||
// fill native queue
|
||||
for (const auto* const model : sourceModels) {
|
||||
addRenderObject(
|
||||
phaseLayoutID, bDrawOpaqueOrMask, bDrawBlend,
|
||||
bDrawProbe, *sceneData.camera, *model, nativeQueue);
|
||||
}
|
||||
|
||||
// post-processing
|
||||
nativeQueue.sort();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneCulling::buildRenderQueues(
|
||||
const RenderGraph& rg, const LayoutGraphData& lg,
|
||||
const NativePipeline& ppl) {
|
||||
kPipelineSceneData = ppl.pipelineSceneData;
|
||||
kLayoutGraph = ≶
|
||||
collectCullingQueries(rg, lg);
|
||||
batchFrustumCulling(ppl);
|
||||
batchLightBoundsCulling(); // cull frustum-culling's results by light bounds
|
||||
fillRenderQueues(rg, *ppl.pipelineSceneData);
|
||||
}
|
||||
|
||||
void SceneCulling::clear() noexcept {
|
||||
// frustum culling
|
||||
frustumCullings.clear();
|
||||
for (auto& c : frustumCullingResults) {
|
||||
c.clear();
|
||||
}
|
||||
// light bounds culling
|
||||
lightBoundsCullings.clear();
|
||||
for (auto& c : lightBoundsCullingResults) {
|
||||
c.instances.clear();
|
||||
c.lightByteOffset = 0xFFFFFFFF;
|
||||
}
|
||||
// native render queues
|
||||
for (auto& q : renderQueues) {
|
||||
q.clear();
|
||||
}
|
||||
|
||||
// clear render graph scene vertex query index
|
||||
renderQueueIndex.clear();
|
||||
// do not clear this->renderQueues, it is reused to avoid memory allocation
|
||||
|
||||
// reset all counters
|
||||
numFrustumCulling = 0;
|
||||
numLightBoundsCulling = 0;
|
||||
numRenderQueues = 0;
|
||||
}
|
||||
|
||||
void LightResource::init(const NativeProgramLibrary& programLib, gfx::Device* deviceIn, uint32_t maxNumLightsIn) {
|
||||
CC_EXPECTS(!device);
|
||||
device = deviceIn;
|
||||
programLibrary = &programLib;
|
||||
|
||||
const auto& instanceLayout = programLibrary->localLayoutData;
|
||||
const auto attrID = at(programLib.layoutGraph.attributeIndex, std::string_view{"CCForwardLight"});
|
||||
const auto& uniformBlock = instanceLayout.uniformBlocks.at(attrID);
|
||||
|
||||
elementSize = boost::alignment::align_up(
|
||||
getUniformBlockSize(uniformBlock.members),
|
||||
device->getCapabilities().uboOffsetAlignment);
|
||||
maxNumLights = maxNumLightsIn;
|
||||
binding = programLib.localLayoutData.bindingMap.at(attrID);
|
||||
|
||||
const auto bufferSize = elementSize * maxNumLights;
|
||||
|
||||
lightBuffer = device->createBuffer(gfx::BufferInfo{
|
||||
gfx::BufferUsageBit::UNIFORM | gfx::BufferUsageBit::TRANSFER_DST,
|
||||
gfx::MemoryUsageBit::HOST | gfx::MemoryUsageBit::DEVICE,
|
||||
bufferSize,
|
||||
elementSize,
|
||||
});
|
||||
firstLightBufferView = device->createBuffer({lightBuffer, 0, elementSize});
|
||||
|
||||
cpuBuffer.resize(bufferSize);
|
||||
lights.reserve(maxNumLights);
|
||||
lightIndex.reserve(maxNumLights);
|
||||
|
||||
CC_ENSURES(elementSize);
|
||||
CC_ENSURES(maxNumLights);
|
||||
|
||||
resized = true;
|
||||
}
|
||||
|
||||
uint32_t LightResource::addLight(
|
||||
const scene::Light* light,
|
||||
bool bHDR,
|
||||
float exposure,
|
||||
const scene::Shadows* shadowInfo) {
|
||||
// already added
|
||||
auto iter = lightIndex.find(light);
|
||||
if (iter != lightIndex.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
// resize buffer
|
||||
if (lights.size() == maxNumLights) {
|
||||
resized = true;
|
||||
maxNumLights *= 2;
|
||||
const auto bufferSize = elementSize * maxNumLights;
|
||||
lightBuffer->resize(bufferSize);
|
||||
firstLightBufferView = device->createBuffer({lightBuffer, 0, elementSize});
|
||||
cpuBuffer.resize(bufferSize);
|
||||
lights.reserve(maxNumLights);
|
||||
lightIndex.reserve(maxNumLights);
|
||||
}
|
||||
CC_ENSURES(lights.size() < maxNumLights);
|
||||
|
||||
// add light
|
||||
const auto lightID = static_cast<uint32_t>(lights.size());
|
||||
lights.emplace_back(light);
|
||||
auto res = lightIndex.emplace(light, lightID);
|
||||
CC_ENSURES(res.second);
|
||||
|
||||
// update buffer
|
||||
const auto offset = elementSize * lightID;
|
||||
setLightUBO(light, bHDR, exposure, shadowInfo, cpuBuffer.data() + offset, elementSize);
|
||||
|
||||
return lightID * elementSize;
|
||||
}
|
||||
|
||||
void LightResource::buildLights(
|
||||
SceneCulling& sceneCulling,
|
||||
bool bHDR,
|
||||
const scene::Shadows* shadowInfo) {
|
||||
// build light buffer
|
||||
for (const auto& [scene, lightBoundsCullings] : sceneCulling.lightBoundsCullings) {
|
||||
for (const auto& [key, lightBoundsCullingID] : lightBoundsCullings.resultIndex) {
|
||||
float exposure = 1.0F;
|
||||
if (key.camera) {
|
||||
exposure = key.camera->getExposure();
|
||||
} else if (key.probe && key.probe->getCamera()) {
|
||||
exposure = key.probe->getCamera()->getExposure();
|
||||
} else {
|
||||
CC_EXPECTS(false);
|
||||
}
|
||||
const auto lightByteOffset = addLight(
|
||||
key.cullingLight,
|
||||
bHDR,
|
||||
exposure,
|
||||
shadowInfo);
|
||||
|
||||
// save light byte offset for each light bounds culling
|
||||
auto& result = sceneCulling.lightBoundsCullingResults.at(lightBoundsCullingID.value);
|
||||
result.lightByteOffset = lightByteOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// assign light byte offset to each queue
|
||||
for (const auto& [sceneID, desc] : sceneCulling.renderQueueIndex) {
|
||||
if (desc.lightBoundsCulledResultID.value == 0xFFFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
const auto lightByteOffset = sceneCulling.lightBoundsCullingResults.at(
|
||||
desc.lightBoundsCulledResultID.value)
|
||||
.lightByteOffset;
|
||||
|
||||
sceneCulling.renderQueues.at(desc.renderQueueTarget.value).lightByteOffset = lightByteOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void LightResource::clear() {
|
||||
std::fill(cpuBuffer.begin(), cpuBuffer.end(), 0);
|
||||
lights.clear();
|
||||
lightIndex.clear();
|
||||
}
|
||||
|
||||
void LightResource::buildLightBuffer(gfx::CommandBuffer* cmdBuffer) const {
|
||||
if (lights.empty()) {
|
||||
return;
|
||||
}
|
||||
cmdBuffer->updateBuffer(
|
||||
lightBuffer,
|
||||
cpuBuffer.data(),
|
||||
static_cast<uint32_t>(lights.size()) * elementSize);
|
||||
}
|
||||
|
||||
void LightResource::tryUpdateRenderSceneLocalDescriptorSet(const SceneCulling& sceneCulling) {
|
||||
if (sceneCulling.lightBoundsCullingResults.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& [scene, culling] : sceneCulling.frustumCullings) {
|
||||
for (const auto& model : scene->getModels()) {
|
||||
CC_EXPECTS(model);
|
||||
for (const auto& submodel : model->getSubModels()) {
|
||||
auto* set = submodel->getDescriptorSet();
|
||||
const auto& prev = set->getBuffer(binding);
|
||||
if (resized || prev != firstLightBufferView) {
|
||||
set->bindBuffer(binding, firstLightBufferView);
|
||||
set->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resized = false;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
335
cocos/renderer/pipeline/custom/NativeSetter.cpp
Normal file
335
cocos/renderer/pipeline/custom/NativeSetter.cpp
Normal file
@@ -0,0 +1,335 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h"
|
||||
#include "cocos/scene/Light.h"
|
||||
#include "cocos/scene/RenderScene.h"
|
||||
#include "cocos/scene/SpotLight.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
void NativeSetter::setMat4(const ccstd::string &name, const Mat4 &mat) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setMat4Impl(data, *layoutGraph, name, mat);
|
||||
}
|
||||
|
||||
void NativeSetter::setQuaternion(const ccstd::string &name, const Quaternion &quat) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setQuaternionImpl(data, *layoutGraph, name, quat);
|
||||
}
|
||||
|
||||
void NativeSetter::setColor(const ccstd::string &name, const gfx::Color &color) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setColorImpl(data, *layoutGraph, name, color);
|
||||
}
|
||||
|
||||
void NativeSetter::setVec4(const ccstd::string &name, const Vec4 &vec) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setVec4Impl(data, *layoutGraph, name, vec);
|
||||
}
|
||||
|
||||
void NativeSetter::setVec2(const ccstd::string &name, const Vec2 &vec) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setVec2Impl(data, *layoutGraph, name, vec);
|
||||
}
|
||||
|
||||
void NativeSetter::setFloat(const ccstd::string &name, float v) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setFloatImpl(data, *layoutGraph, name, v);
|
||||
}
|
||||
|
||||
void NativeSetter::setArrayBuffer(const ccstd::string &name, const ArrayBuffer *buffer) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setArrayBufferImpl(data, *layoutGraph, name, *buffer);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuffer(const ccstd::string &name, gfx::Buffer *buffer) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setBufferImpl(data, *layoutGraph, name, buffer);
|
||||
}
|
||||
|
||||
void NativeSetter::setTexture(const ccstd::string &name, gfx::Texture *texture) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setTextureImpl(data, *layoutGraph, name, texture);
|
||||
}
|
||||
|
||||
void NativeSetter::setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setReadWriteBufferImpl(data, *layoutGraph, name, buffer);
|
||||
}
|
||||
|
||||
void NativeSetter::setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setReadWriteTextureImpl(data, *layoutGraph, name, texture);
|
||||
}
|
||||
|
||||
void NativeSetter::setSampler(const ccstd::string &name, gfx::Sampler *sampler) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setSamplerImpl(data, *layoutGraph, name, sampler);
|
||||
}
|
||||
|
||||
void NativeSetter::setVec4ArraySize(const ccstd::string &name, uint32_t sz) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setVec4ArraySizeImpl(data, *layoutGraph, name, sz);
|
||||
}
|
||||
|
||||
void NativeSetter::setVec4ArrayElem(const ccstd::string &name, const cc::Vec4 &vec, uint32_t id) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setVec4ArrayElemImpl(data, *layoutGraph, name, vec, id);
|
||||
}
|
||||
|
||||
void NativeSetter::setMat4ArraySize(const ccstd::string &name, uint32_t sz) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setMat4ArraySizeImpl(data, *layoutGraph, name, sz);
|
||||
}
|
||||
|
||||
void NativeSetter::setMat4ArrayElem(const ccstd::string &name, const cc::Mat4 &mat, uint32_t id) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setMat4ArrayElemImpl(data, *layoutGraph, name, mat, id);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinCameraConstants(const scene::Camera *camera) {
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setCameraUBOValues(
|
||||
*camera,
|
||||
*layoutGraph,
|
||||
*pipelineRuntime->getPipelineSceneData(),
|
||||
camera->getScene()->getMainLight(), data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinDirectionalLightFrustumConstants(
|
||||
const scene::Camera *camera,
|
||||
const scene::DirectionalLight *light, uint32_t level) {
|
||||
CC_EXPECTS(light);
|
||||
// if csm is actually activated, csm is not nullptr
|
||||
// update and get csm
|
||||
const auto *csm = getBuiltinShadowCSM(*pipelineRuntime, *camera, light);
|
||||
|
||||
// set data
|
||||
auto *device = pipelineRuntime->getDevice();
|
||||
const auto &sceneData = *pipelineRuntime->getPipelineSceneData();
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setShadowUBOLightView(device, *layoutGraph, sceneData, csm, *light, level, data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinSpotLightFrustumConstants(const scene::SpotLight *light) {
|
||||
CC_EXPECTS(light);
|
||||
auto *device = pipelineRuntime->getDevice();
|
||||
const auto &sceneData = *pipelineRuntime->getPipelineSceneData();
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setShadowUBOLightView(device, *layoutGraph, sceneData, nullptr, *light, 0, data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinShadowMapConstants(
|
||||
const scene::DirectionalLight *light) {
|
||||
CC_EXPECTS(light);
|
||||
auto *device = pipelineRuntime->getDevice();
|
||||
const auto &sceneData = *pipelineRuntime->getPipelineSceneData();
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
setShadowUBOView(*device, *layoutGraph, sceneData, *light, data);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float LIGHT_METER_SCALE = 10000.0F;
|
||||
constexpr bool ENABLE_NEW_MULTI_LIGHT = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
void NativeSetter::setBuiltinDirectionalLightConstants(const scene::DirectionalLight *light, const scene::Camera *camera) {
|
||||
std::ignore = camera;
|
||||
setBuiltinShadowMapConstants(light);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinSphereLightConstants(
|
||||
const scene::SphereLight *light, const scene::Camera *camera) {
|
||||
CC_EXPECTS(light);
|
||||
const auto &sceneData = *pipelineRuntime->getPipelineSceneData();
|
||||
const auto &shadowInfo = *sceneData.getShadows();
|
||||
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
|
||||
if constexpr (ENABLE_NEW_MULTI_LIGHT) {
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightPos",
|
||||
toVec4(light->getPosition(), static_cast<float>(scene::LightType::SPHERE)));
|
||||
auto color = toVec4(light->getColor());
|
||||
if (light->isUseColorTemperature()) {
|
||||
const auto &rgb = light->getColorTemperatureRGB();
|
||||
color.x *= rgb.x;
|
||||
color.y *= rgb.y;
|
||||
color.z *= rgb.z;
|
||||
}
|
||||
if (sceneData.isHDR()) {
|
||||
color.w = light->getLuminance() * camera->getExposure() * LIGHT_METER_SCALE;
|
||||
} else {
|
||||
color.w = light->getLuminance();
|
||||
}
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightColor", color);
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightSizeRangeAngle",
|
||||
Vec4(
|
||||
light->getSize(),
|
||||
light->getRange(),
|
||||
0.F,
|
||||
0.F));
|
||||
}
|
||||
setPunctualLightShadowUBO(
|
||||
pipelineRuntime->getDevice(), *layoutGraph, sceneData,
|
||||
camera->getScene()->getMainLight(), *light, data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinSpotLightConstants(const scene::SpotLight *light, const scene::Camera *camera) {
|
||||
CC_EXPECTS(light);
|
||||
const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData();
|
||||
const auto &shadowInfo = *sceneData.getShadows();
|
||||
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
|
||||
if constexpr (ENABLE_NEW_MULTI_LIGHT) {
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightPos",
|
||||
toVec4(light->getPosition(), static_cast<float>(scene::LightType::SPOT)));
|
||||
|
||||
auto color = toVec4(light->getColor());
|
||||
if (light->isUseColorTemperature()) {
|
||||
const auto &rgb = light->getColorTemperatureRGB();
|
||||
color.x *= rgb.x;
|
||||
color.y *= rgb.y;
|
||||
color.z *= rgb.z;
|
||||
}
|
||||
if (sceneData.isHDR()) {
|
||||
color.w = light->getLuminance() * camera->getExposure() * LIGHT_METER_SCALE;
|
||||
} else {
|
||||
color.w = light->getLuminance();
|
||||
}
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightColor", color);
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightSizeRangeAngle",
|
||||
Vec4(
|
||||
light->getSize(),
|
||||
light->getRange(),
|
||||
light->getSpotAngle(),
|
||||
shadowInfo.isEnabled() &&
|
||||
light->isShadowEnabled() &&
|
||||
shadowInfo.getType() == scene::ShadowType::SHADOW_MAP
|
||||
? 1.0F
|
||||
: 0.0F));
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightDir",
|
||||
toVec4(light->getDirection()));
|
||||
}
|
||||
setPunctualLightShadowUBO(
|
||||
pipelineRuntime->getDevice(), *layoutGraph, sceneData,
|
||||
camera->getScene()->getMainLight(), *light, data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinPointLightConstants(const scene::PointLight *light, const scene::Camera *camera) {
|
||||
CC_EXPECTS(light);
|
||||
const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData();
|
||||
const auto &shadowInfo = *sceneData.getShadows();
|
||||
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
|
||||
if constexpr (ENABLE_NEW_MULTI_LIGHT) {
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightPos",
|
||||
toVec4(light->getPosition(), static_cast<float>(scene::LightType::POINT)));
|
||||
auto color = toVec4(light->getColor());
|
||||
if (light->isUseColorTemperature()) {
|
||||
const auto &rgb = light->getColorTemperatureRGB();
|
||||
color.x *= rgb.x;
|
||||
color.y *= rgb.y;
|
||||
color.z *= rgb.z;
|
||||
}
|
||||
if (sceneData.isHDR()) {
|
||||
color.w = light->getLuminance() * camera->getExposure() * LIGHT_METER_SCALE;
|
||||
} else {
|
||||
color.w = light->getLuminance();
|
||||
}
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightColor", color);
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightSizeRangeAngle",
|
||||
Vec4(
|
||||
0.F,
|
||||
light->getRange(),
|
||||
0.F,
|
||||
0.F));
|
||||
}
|
||||
setPunctualLightShadowUBO(
|
||||
pipelineRuntime->getDevice(), *layoutGraph, sceneData,
|
||||
camera->getScene()->getMainLight(), *light, data);
|
||||
}
|
||||
|
||||
void NativeSetter::setBuiltinRangedDirectionalLightConstants(const scene::RangedDirectionalLight *light, const scene::Camera *camera) {
|
||||
const auto &sceneData = *this->pipelineRuntime->getPipelineSceneData();
|
||||
const auto &shadowInfo = *sceneData.getShadows();
|
||||
|
||||
auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID);
|
||||
|
||||
if constexpr (ENABLE_NEW_MULTI_LIGHT) {
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightPos",
|
||||
toVec4(light->getPosition(), static_cast<float>(scene::LightType::RANGED_DIRECTIONAL)));
|
||||
auto color = toVec4(light->getColor());
|
||||
if (light->isUseColorTemperature()) {
|
||||
const auto &rgb = light->getColorTemperatureRGB();
|
||||
color.x *= rgb.x;
|
||||
color.y *= rgb.y;
|
||||
color.z *= rgb.z;
|
||||
}
|
||||
if (sceneData.isHDR()) {
|
||||
color.w = light->getIlluminance() * camera->getExposure();
|
||||
} else {
|
||||
color.w = light->getIlluminance();
|
||||
}
|
||||
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightColor", color);
|
||||
setVec4Impl(
|
||||
data, *layoutGraph, "cc_lightSizeRangeAngle",
|
||||
Vec4(
|
||||
light->getRight().x,
|
||||
light->getRight().y,
|
||||
light->getRight().z,
|
||||
0.F));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
77
cocos/renderer/pipeline/custom/NativeTypes.cpp
Normal file
77
cocos/renderer/pipeline/custom/NativeTypes.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "NativeTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
ProgramInfo::ProgramInfo(const allocator_type& alloc) noexcept
|
||||
: attributes(alloc) {}
|
||||
|
||||
ProgramInfo::ProgramInfo(IProgramInfo programInfoIn, gfx::ShaderInfo shaderInfoIn, ccstd::pmr::vector<gfx::Attribute> attributesIn, ccstd::vector<signed> blockSizesIn, ccstd::unordered_map<ccstd::string, uint32_t> handleMapIn, const allocator_type& alloc) noexcept
|
||||
: programInfo(std::move(programInfoIn)),
|
||||
shaderInfo(std::move(shaderInfoIn)),
|
||||
attributes(std::move(attributesIn), alloc),
|
||||
blockSizes(std::move(blockSizesIn)),
|
||||
handleMap(std::move(handleMapIn)) {}
|
||||
|
||||
ProgramInfo::ProgramInfo(ProgramInfo&& rhs, const allocator_type& alloc)
|
||||
: programInfo(std::move(rhs.programInfo)),
|
||||
shaderInfo(std::move(rhs.shaderInfo)),
|
||||
attributes(std::move(rhs.attributes), alloc),
|
||||
blockSizes(std::move(rhs.blockSizes)),
|
||||
handleMap(std::move(rhs.handleMap)) {}
|
||||
|
||||
ProgramInfo::ProgramInfo(ProgramInfo const& rhs, const allocator_type& alloc)
|
||||
: programInfo(rhs.programInfo),
|
||||
shaderInfo(rhs.shaderInfo),
|
||||
attributes(rhs.attributes, alloc),
|
||||
blockSizes(rhs.blockSizes),
|
||||
handleMap(rhs.handleMap) {}
|
||||
|
||||
ProgramGroup::ProgramGroup(const allocator_type& alloc) noexcept
|
||||
: programInfos(alloc),
|
||||
programProxies(alloc) {}
|
||||
|
||||
ProgramGroup::ProgramGroup(ProgramGroup&& rhs, const allocator_type& alloc)
|
||||
: programInfos(std::move(rhs.programInfos), alloc),
|
||||
programProxies(std::move(rhs.programProxies), alloc) {}
|
||||
|
||||
ProgramGroup::ProgramGroup(ProgramGroup const& rhs, const allocator_type& alloc)
|
||||
: programInfos(rhs.programInfos, alloc),
|
||||
programProxies(rhs.programProxies, alloc) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
91
cocos/renderer/pipeline/custom/NativeTypes.h
Normal file
91
cocos/renderer/pipeline/custom/NativeTypes.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/renderer/gfx-base/GFXRenderPass.h"
|
||||
#include "cocos/renderer/pipeline/GlobalDescriptorSetManager.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativeFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/PrivateTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Map.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct ProgramInfo {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {attributes.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ProgramInfo(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ProgramInfo(IProgramInfo programInfoIn, gfx::ShaderInfo shaderInfoIn, ccstd::pmr::vector<gfx::Attribute> attributesIn, ccstd::vector<signed> blockSizesIn, ccstd::unordered_map<ccstd::string, uint32_t> handleMapIn, const allocator_type& alloc) noexcept;
|
||||
ProgramInfo(ProgramInfo&& rhs, const allocator_type& alloc);
|
||||
ProgramInfo(ProgramInfo const& rhs, const allocator_type& alloc);
|
||||
|
||||
ProgramInfo(ProgramInfo&& rhs) noexcept = default;
|
||||
ProgramInfo(ProgramInfo const& rhs) = delete;
|
||||
ProgramInfo& operator=(ProgramInfo&& rhs) = default;
|
||||
ProgramInfo& operator=(ProgramInfo const& rhs) = default;
|
||||
|
||||
IProgramInfo programInfo;
|
||||
gfx::ShaderInfo shaderInfo;
|
||||
ccstd::pmr::vector<gfx::Attribute> attributes;
|
||||
ccstd::vector<signed> blockSizes;
|
||||
ccstd::unordered_map<ccstd::string, uint32_t> handleMap;
|
||||
};
|
||||
|
||||
struct ProgramGroup {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {programInfos.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ProgramGroup(const allocator_type& alloc) noexcept; // NOLINT
|
||||
ProgramGroup(ProgramGroup&& rhs, const allocator_type& alloc);
|
||||
ProgramGroup(ProgramGroup const& rhs, const allocator_type& alloc);
|
||||
|
||||
ProgramGroup(ProgramGroup&& rhs) noexcept = default;
|
||||
ProgramGroup(ProgramGroup const& rhs) = delete;
|
||||
ProgramGroup& operator=(ProgramGroup&& rhs) = default;
|
||||
ProgramGroup& operator=(ProgramGroup const& rhs) = default;
|
||||
|
||||
PmrTransparentMap<ccstd::pmr::string, ProgramInfo> programInfos;
|
||||
PmrFlatMap<ccstd::pmr::string, IntrusivePtr<ProgramProxy>> programProxies;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
168
cocos/renderer/pipeline/custom/NativeUtils.cpp
Normal file
168
cocos/renderer/pipeline/custom/NativeUtils.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "cocos/renderer/pipeline/custom/NativeUtils.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace {
|
||||
|
||||
render::NameLocalID getNameID(
|
||||
const PmrFlatMap<ccstd::pmr::string, render::NameLocalID> &index,
|
||||
std::string_view name) {
|
||||
auto iter = index.find(name);
|
||||
CC_EXPECTS(iter != index.end());
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setMat4Impl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const cc::Mat4 &v) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Mat4) == 16 * 4, "sizeof(Mat4) is not 64 bytes");
|
||||
data.constants[nameID.value].resize(sizeof(Mat4));
|
||||
memcpy(data.constants[nameID.value].data(), v.m, sizeof(v));
|
||||
}
|
||||
|
||||
void setMat4ArrayElemImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const cc::Mat4 &v, uint32_t i) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Mat4) == 16 * 4, "sizeof(Mat4) is not 64 bytes");
|
||||
auto &dst = data.constants[nameID.value];
|
||||
CC_EXPECTS(sizeof(Mat4) * (i + 1) <= dst.size());
|
||||
memcpy(dst.data() + sizeof(Mat4) * i, v.m, sizeof(v));
|
||||
}
|
||||
|
||||
void setMat4ArraySizeImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
uint32_t sz) {
|
||||
CC_EXPECTS(sz);
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Mat4) == 16 * 4, "sizeof(Mat4) is not 64 bytes");
|
||||
data.constants[nameID.value].resize(sizeof(Mat4) * sz);
|
||||
}
|
||||
|
||||
void setQuaternionImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Quaternion &quat) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Quaternion) == 4 * 4, "sizeof(Quaternion) is not 16 bytes");
|
||||
static_assert(std::is_trivially_copyable<Quaternion>::value, "Quaternion is not trivially copyable");
|
||||
data.constants[nameID.value].resize(sizeof(Quaternion));
|
||||
memcpy(data.constants[nameID.value].data(), &quat, sizeof(quat));
|
||||
}
|
||||
|
||||
void setColorImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const gfx::Color &color) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(gfx::Color) == 4 * 4, "sizeof(Color) is not 16 bytes");
|
||||
static_assert(std::is_trivially_copyable<gfx::Color>::value, "Color is not trivially copyable");
|
||||
data.constants[nameID.value].resize(sizeof(gfx::Color));
|
||||
memcpy(data.constants[nameID.value].data(), &color, sizeof(color));
|
||||
}
|
||||
|
||||
void setVec4Impl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Vec4 &vec) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Vec4) == 4 * 4, "sizeof(Vec4) is not 16 bytes");
|
||||
// static_assert(std::is_trivially_copyable<Vec4>::value, "Vec4 is not trivially copyable");
|
||||
data.constants[nameID.value].resize(sizeof(Vec4));
|
||||
memcpy(data.constants[nameID.value].data(), &vec.x, sizeof(vec));
|
||||
}
|
||||
|
||||
void setVec4ArrayElemImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name,
|
||||
const Vec4 &vec, uint32_t i) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Vec4) == 4 * 4, "sizeof(Vec4) is not 16 bytes");
|
||||
// static_assert(std::is_trivially_copyable<Vec4>::value, "Vec4 is not trivially copyable");
|
||||
auto &dst = data.constants[nameID.value];
|
||||
CC_EXPECTS(sizeof(Vec4) * (i + 1) <= dst.size());
|
||||
memcpy(dst.data() + sizeof(Vec4) * i, &vec.x, sizeof(vec));
|
||||
}
|
||||
|
||||
void setVec4ArraySizeImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name,
|
||||
uint32_t sz) {
|
||||
CC_EXPECTS(sz);
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Vec4) == 4 * 4, "sizeof(Vec4) is not 16 bytes");
|
||||
// static_assert(std::is_trivially_copyable<Vec4>::value, "Vec4 is not trivially copyable");
|
||||
data.constants[nameID.value].resize(sizeof(Vec4) * sz);
|
||||
}
|
||||
|
||||
void setVec2Impl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Vec2 &vec) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(Vec2) == 2 * 4, "sizeof(Vec2) is not 8 bytes");
|
||||
// static_assert(std::is_trivially_copyable<Vec4>::value, "Vec2 is not trivially copyable");
|
||||
data.constants[nameID.value].resize(sizeof(Vec2));
|
||||
memcpy(data.constants[nameID.value].data(), &vec.x, sizeof(vec));
|
||||
}
|
||||
|
||||
void setFloatImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, float v) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
static_assert(sizeof(float) == 4, "sizeof(float) is not 4 bytes");
|
||||
data.constants[nameID.value].resize(sizeof(float));
|
||||
memcpy(data.constants[nameID.value].data(), &v, sizeof(v));
|
||||
}
|
||||
|
||||
void setArrayBufferImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const ArrayBuffer &buffer) {
|
||||
auto nameID = getNameID(lg.constantIndex, name);
|
||||
data.constants[nameID.value].resize(buffer.byteLength());
|
||||
memcpy(data.constants[nameID.value].data(), buffer.getData(), buffer.byteLength());
|
||||
}
|
||||
|
||||
void setBufferImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Buffer *buffer) {
|
||||
auto nameID = getNameID(lg.attributeIndex, name);
|
||||
data.buffers[nameID.value] = IntrusivePtr<gfx::Buffer>(buffer);
|
||||
}
|
||||
|
||||
void setTextureImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Texture *texture) {
|
||||
auto nameID = getNameID(lg.attributeIndex, name);
|
||||
data.textures[nameID.value] = IntrusivePtr<gfx::Texture>(texture);
|
||||
}
|
||||
|
||||
void setReadWriteBufferImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Buffer *buffer) {
|
||||
auto nameID = getNameID(lg.attributeIndex, name);
|
||||
data.buffers[nameID.value] = IntrusivePtr<gfx::Buffer>(buffer);
|
||||
}
|
||||
|
||||
void setReadWriteTextureImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Texture *texture) {
|
||||
auto nameID = getNameID(lg.attributeIndex, name);
|
||||
data.textures[nameID.value] = IntrusivePtr<gfx::Texture>(texture);
|
||||
}
|
||||
|
||||
void setSamplerImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Sampler *sampler) {
|
||||
auto nameID = getNameID(lg.attributeIndex, name);
|
||||
data.samplers[nameID.value] = sampler;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
87
cocos/renderer/pipeline/custom/NativeUtils.h
Normal file
87
cocos/renderer/pipeline/custom/NativeUtils.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "cocos/core/ArrayBuffer.h"
|
||||
#include "cocos/math/Vec2.h"
|
||||
#include "cocos/math/Vec3.h"
|
||||
#include "cocos/math/Vec4.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDef-common.h"
|
||||
#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderGraphFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderInterfaceFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
void setMat4Impl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const cc::Mat4 &v);
|
||||
|
||||
void setMat4ArrayElemImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const cc::Mat4 &v, uint32_t i);
|
||||
|
||||
void setMat4ArraySizeImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
uint32_t sz);
|
||||
|
||||
void setQuaternionImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Quaternion &quat);
|
||||
|
||||
void setColorImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const gfx::Color &color);
|
||||
|
||||
void setVec4Impl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Vec4 &vec);
|
||||
|
||||
void setVec4ArrayElemImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name,
|
||||
const Vec4 &vec, uint32_t i);
|
||||
|
||||
void setVec4ArraySizeImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name,
|
||||
uint32_t sz);
|
||||
|
||||
void setVec2Impl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, const Vec2 &vec);
|
||||
|
||||
void setFloatImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, float v);
|
||||
|
||||
void setArrayBufferImpl(
|
||||
RenderData &data, const LayoutGraphData &lg, std::string_view name,
|
||||
const ArrayBuffer &buffer);
|
||||
|
||||
void setBufferImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Buffer *buffer);
|
||||
|
||||
void setTextureImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Texture *texture);
|
||||
|
||||
void setReadWriteBufferImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Buffer *buffer);
|
||||
|
||||
void setReadWriteTextureImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Texture *texture);
|
||||
|
||||
void setSamplerImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Sampler *sampler);
|
||||
|
||||
inline Vec4 toVec4(const Vec3 &vec, float w = 0.0F) noexcept {
|
||||
return {vec.x, vec.y, vec.z, w};
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
46
cocos/renderer/pipeline/custom/PrivateFwd.h
Normal file
46
cocos/renderer/pipeline/custom/PrivateFwd.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderInterfaceFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class ProgramProxy;
|
||||
class ProgramLibrary;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
41
cocos/renderer/pipeline/custom/PrivateTypes.cpp
Normal file
41
cocos/renderer/pipeline/custom/PrivateTypes.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "PrivateTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
90
cocos/renderer/pipeline/custom/PrivateTypes.h
Normal file
90
cocos/renderer/pipeline/custom/PrivateTypes.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/renderer/core/ProgramLib.h"
|
||||
#include "cocos/renderer/pipeline/custom/PrivateFwd.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderInterfaceTypes.h"
|
||||
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class ProgramProxy : public RefCounted {
|
||||
public:
|
||||
ProgramProxy() = default;
|
||||
ProgramProxy(ProgramProxy&& rhs) = delete;
|
||||
ProgramProxy(ProgramProxy const& rhs) = delete;
|
||||
ProgramProxy& operator=(ProgramProxy&& rhs) = delete;
|
||||
ProgramProxy& operator=(ProgramProxy const& rhs) = delete;
|
||||
~ProgramProxy() noexcept override = default;
|
||||
|
||||
virtual const ccstd::string &getName() const noexcept = 0;
|
||||
virtual gfx::Shader *getShader() const noexcept = 0;
|
||||
};
|
||||
|
||||
class ProgramLibrary {
|
||||
public:
|
||||
ProgramLibrary() noexcept = default;
|
||||
ProgramLibrary(ProgramLibrary&& rhs) = delete;
|
||||
ProgramLibrary(ProgramLibrary const& rhs) = delete;
|
||||
ProgramLibrary& operator=(ProgramLibrary&& rhs) = delete;
|
||||
ProgramLibrary& operator=(ProgramLibrary const& rhs) = delete;
|
||||
virtual ~ProgramLibrary() noexcept = default;
|
||||
|
||||
virtual void addEffect(const EffectAsset *effectAsset) = 0;
|
||||
virtual void precompileEffect(gfx::Device *device, EffectAsset *effectAsset) = 0;
|
||||
virtual ccstd::string getKey(uint32_t phaseID, const ccstd::string &programName, const MacroRecord &defines) const = 0;
|
||||
virtual IntrusivePtr<gfx::PipelineLayout> getPipelineLayout(gfx::Device *device, uint32_t phaseID, const ccstd::string &programName) = 0;
|
||||
virtual const gfx::DescriptorSetLayout &getMaterialDescriptorSetLayout(gfx::Device *device, uint32_t phaseID, const ccstd::string &programName) = 0;
|
||||
virtual const gfx::DescriptorSetLayout &getLocalDescriptorSetLayout(gfx::Device *device, uint32_t phaseID, const ccstd::string &programName) = 0;
|
||||
virtual const IProgramInfo &getProgramInfo(uint32_t phaseID, const ccstd::string &programName) const = 0;
|
||||
virtual const gfx::ShaderInfo &getShaderInfo(uint32_t phaseID, const ccstd::string &programName) const = 0;
|
||||
virtual ProgramProxy *getProgramVariant(gfx::Device *device, uint32_t phaseID, const ccstd::string &name, MacroRecord &defines, const ccstd::pmr::string *key) = 0;
|
||||
virtual gfx::PipelineState *getComputePipelineState(gfx::Device *device, uint32_t phaseID, const ccstd::string &name, MacroRecord &defines, const ccstd::pmr::string *key) = 0;
|
||||
virtual const ccstd::vector<int> &getBlockSizes(uint32_t phaseID, const ccstd::string &programName) const = 0;
|
||||
virtual const ccstd::unordered_map<ccstd::string, uint32_t> &getHandleMap(uint32_t phaseID, const ccstd::string &programName) const = 0;
|
||||
virtual uint32_t getProgramID(uint32_t phaseID, const ccstd::pmr::string &programName) = 0;
|
||||
virtual uint32_t getDescriptorNameID(const ccstd::pmr::string &name) = 0;
|
||||
virtual const ccstd::pmr::string &getDescriptorName(uint32_t nameID) = 0;
|
||||
ProgramProxy *getProgramVariant(gfx::Device *device, uint32_t phaseID, const ccstd::string &name, MacroRecord &defines) {
|
||||
return getProgramVariant(device, phaseID, name, defines, nullptr);
|
||||
}
|
||||
gfx::PipelineState *getComputePipelineState(gfx::Device *device, uint32_t phaseID, const ccstd::string &name, MacroRecord &defines) {
|
||||
return getComputePipelineState(device, phaseID, name, defines, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
96
cocos/renderer/pipeline/custom/RenderCommonFwd.h
Normal file
96
cocos/renderer/pipeline/custom/RenderCommonFwd.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/base/std/variant.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
enum class UpdateFrequency;
|
||||
enum class ParameterType;
|
||||
|
||||
struct RasterPassTag;
|
||||
struct RasterSubpassTag;
|
||||
struct ComputeSubpassTag;
|
||||
struct ComputeTag;
|
||||
struct ResolveTag;
|
||||
struct CopyTag;
|
||||
struct MoveTag;
|
||||
struct RaytraceTag;
|
||||
|
||||
enum class ResourceResidency;
|
||||
enum class QueueHint;
|
||||
enum class ResourceDimension;
|
||||
enum class ResourceFlags : uint32_t;
|
||||
|
||||
struct BufferTag;
|
||||
struct TextureTag;
|
||||
|
||||
enum class TaskType;
|
||||
enum class SceneFlags : uint32_t;
|
||||
enum class LightingMode : uint32_t;
|
||||
enum class AttachmentType;
|
||||
enum class AccessType;
|
||||
enum class ClearValueType;
|
||||
|
||||
struct LightInfo;
|
||||
|
||||
enum class DescriptorTypeOrder;
|
||||
|
||||
struct Descriptor;
|
||||
struct DescriptorBlock;
|
||||
struct DescriptorBlockFlattened;
|
||||
struct DescriptorBlockIndex;
|
||||
|
||||
enum class ResolveFlags : uint32_t;
|
||||
|
||||
struct ResolvePair;
|
||||
struct CopyPair;
|
||||
struct UploadPair;
|
||||
struct MovePair;
|
||||
struct PipelineStatistics;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::ResolvePair> {
|
||||
hash_t operator()(const cc::render::ResolvePair& val) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
496
cocos/renderer/pipeline/custom/RenderCommonJsb.cpp
Normal file
496
cocos/renderer/pipeline/custom/RenderCommonJsb.cpp
Normal file
@@ -0,0 +1,496 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "cocos/bindings/auto/jsb_gfx_auto.h"
|
||||
#include "cocos/bindings/auto/jsb_scene_auto.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonJsb.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/JsbConversion.h"
|
||||
|
||||
bool nativevalue_to_se(const cc::render::LightInfo &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.light, tmp, ctx);
|
||||
obj->setProperty("light", tmp);
|
||||
|
||||
nativevalue_to_se(from.probe, tmp, ctx);
|
||||
obj->setProperty("probe", tmp);
|
||||
|
||||
nativevalue_to_se(from.level, tmp, ctx);
|
||||
obj->setProperty("level", tmp);
|
||||
|
||||
nativevalue_to_se(from.culledByLight, tmp, ctx);
|
||||
obj->setProperty("culledByLight", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::Descriptor &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.type, tmp, ctx);
|
||||
obj->setProperty("type", tmp);
|
||||
|
||||
nativevalue_to_se(from.count, tmp, ctx);
|
||||
obj->setProperty("count", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::DescriptorBlockFlattened &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.descriptorNames, tmp, ctx);
|
||||
obj->setProperty("descriptorNames", tmp);
|
||||
|
||||
nativevalue_to_se(from.uniformBlockNames, tmp, ctx);
|
||||
obj->setProperty("uniformBlockNames", tmp);
|
||||
|
||||
nativevalue_to_se(from.descriptors, tmp, ctx);
|
||||
obj->setProperty("descriptors", tmp);
|
||||
|
||||
nativevalue_to_se(from.uniformBlocks, tmp, ctx);
|
||||
obj->setProperty("uniformBlocks", tmp);
|
||||
|
||||
nativevalue_to_se(from.capacity, tmp, ctx);
|
||||
obj->setProperty("capacity", tmp);
|
||||
|
||||
nativevalue_to_se(from.count, tmp, ctx);
|
||||
obj->setProperty("count", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::DescriptorBlockIndex &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.updateFrequency, tmp, ctx);
|
||||
obj->setProperty("updateFrequency", tmp);
|
||||
|
||||
nativevalue_to_se(from.parameterType, tmp, ctx);
|
||||
obj->setProperty("parameterType", tmp);
|
||||
|
||||
nativevalue_to_se(from.descriptorType, tmp, ctx);
|
||||
obj->setProperty("descriptorType", tmp);
|
||||
|
||||
nativevalue_to_se(from.visibility, tmp, ctx);
|
||||
obj->setProperty("visibility", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::ResolvePair &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.source, tmp, ctx);
|
||||
obj->setProperty("source", tmp);
|
||||
|
||||
nativevalue_to_se(from.target, tmp, ctx);
|
||||
obj->setProperty("target", tmp);
|
||||
|
||||
nativevalue_to_se(from.resolveFlags, tmp, ctx);
|
||||
obj->setProperty("resolveFlags", tmp);
|
||||
|
||||
nativevalue_to_se(from.mode, tmp, ctx);
|
||||
obj->setProperty("mode", tmp);
|
||||
|
||||
nativevalue_to_se(from.mode1, tmp, ctx);
|
||||
obj->setProperty("mode1", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::CopyPair &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.source, tmp, ctx);
|
||||
obj->setProperty("source", tmp);
|
||||
|
||||
nativevalue_to_se(from.target, tmp, ctx);
|
||||
obj->setProperty("target", tmp);
|
||||
|
||||
nativevalue_to_se(from.mipLevels, tmp, ctx);
|
||||
obj->setProperty("mipLevels", tmp);
|
||||
|
||||
nativevalue_to_se(from.numSlices, tmp, ctx);
|
||||
obj->setProperty("numSlices", tmp);
|
||||
|
||||
nativevalue_to_se(from.sourceMostDetailedMip, tmp, ctx);
|
||||
obj->setProperty("sourceMostDetailedMip", tmp);
|
||||
|
||||
nativevalue_to_se(from.sourceFirstSlice, tmp, ctx);
|
||||
obj->setProperty("sourceFirstSlice", tmp);
|
||||
|
||||
nativevalue_to_se(from.sourcePlaneSlice, tmp, ctx);
|
||||
obj->setProperty("sourcePlaneSlice", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetMostDetailedMip, tmp, ctx);
|
||||
obj->setProperty("targetMostDetailedMip", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetFirstSlice, tmp, ctx);
|
||||
obj->setProperty("targetFirstSlice", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetPlaneSlice, tmp, ctx);
|
||||
obj->setProperty("targetPlaneSlice", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::UploadPair &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.source, tmp, ctx);
|
||||
obj->setProperty("source", tmp);
|
||||
|
||||
nativevalue_to_se(from.target, tmp, ctx);
|
||||
obj->setProperty("target", tmp);
|
||||
|
||||
nativevalue_to_se(from.mipLevels, tmp, ctx);
|
||||
obj->setProperty("mipLevels", tmp);
|
||||
|
||||
nativevalue_to_se(from.numSlices, tmp, ctx);
|
||||
obj->setProperty("numSlices", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetMostDetailedMip, tmp, ctx);
|
||||
obj->setProperty("targetMostDetailedMip", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetFirstSlice, tmp, ctx);
|
||||
obj->setProperty("targetFirstSlice", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetPlaneSlice, tmp, ctx);
|
||||
obj->setProperty("targetPlaneSlice", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nativevalue_to_se(const cc::render::MovePair &from, se::Value &to, se::Object *ctx) { // NOLINT
|
||||
se::HandleObject obj(se::Object::createPlainObject());
|
||||
se::Value tmp;
|
||||
|
||||
nativevalue_to_se(from.source, tmp, ctx);
|
||||
obj->setProperty("source", tmp);
|
||||
|
||||
nativevalue_to_se(from.target, tmp, ctx);
|
||||
obj->setProperty("target", tmp);
|
||||
|
||||
nativevalue_to_se(from.mipLevels, tmp, ctx);
|
||||
obj->setProperty("mipLevels", tmp);
|
||||
|
||||
nativevalue_to_se(from.numSlices, tmp, ctx);
|
||||
obj->setProperty("numSlices", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetMostDetailedMip, tmp, ctx);
|
||||
obj->setProperty("targetMostDetailedMip", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetFirstSlice, tmp, ctx);
|
||||
obj->setProperty("targetFirstSlice", tmp);
|
||||
|
||||
nativevalue_to_se(from.targetPlaneSlice, tmp, ctx);
|
||||
obj->setProperty("targetPlaneSlice", tmp);
|
||||
|
||||
to.setObject(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::LightInfo>(const se::Value &from, cc::render::LightInfo *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to LightInfo failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("light", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->light), ctx);
|
||||
}
|
||||
obj->getProperty("probe", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->probe), ctx);
|
||||
}
|
||||
obj->getProperty("level", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->level), ctx);
|
||||
}
|
||||
obj->getProperty("culledByLight", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->culledByLight), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::Descriptor>(const se::Value &from, cc::render::Descriptor *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to Descriptor failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("type", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->type), ctx);
|
||||
}
|
||||
obj->getProperty("count", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->count), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::DescriptorBlockFlattened>(const se::Value &from, cc::render::DescriptorBlockFlattened *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to DescriptorBlockFlattened failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("descriptorNames", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->descriptorNames), ctx);
|
||||
}
|
||||
obj->getProperty("uniformBlockNames", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->uniformBlockNames), ctx);
|
||||
}
|
||||
obj->getProperty("descriptors", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->descriptors), ctx);
|
||||
}
|
||||
obj->getProperty("uniformBlocks", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->uniformBlocks), ctx);
|
||||
}
|
||||
obj->getProperty("capacity", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->capacity), ctx);
|
||||
}
|
||||
obj->getProperty("count", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->count), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::DescriptorBlockIndex>(const se::Value &from, cc::render::DescriptorBlockIndex *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to DescriptorBlockIndex failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("updateFrequency", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->updateFrequency), ctx);
|
||||
}
|
||||
obj->getProperty("parameterType", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->parameterType), ctx);
|
||||
}
|
||||
obj->getProperty("descriptorType", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->descriptorType), ctx);
|
||||
}
|
||||
obj->getProperty("visibility", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->visibility), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::ResolvePair>(const se::Value &from, cc::render::ResolvePair *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to ResolvePair failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("source", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->source), ctx);
|
||||
}
|
||||
obj->getProperty("target", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->target), ctx);
|
||||
}
|
||||
obj->getProperty("resolveFlags", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->resolveFlags), ctx);
|
||||
}
|
||||
obj->getProperty("mode", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->mode), ctx);
|
||||
}
|
||||
obj->getProperty("mode1", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->mode1), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::CopyPair>(const se::Value &from, cc::render::CopyPair *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to CopyPair failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("source", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->source), ctx);
|
||||
}
|
||||
obj->getProperty("target", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->target), ctx);
|
||||
}
|
||||
obj->getProperty("mipLevels", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->mipLevels), ctx);
|
||||
}
|
||||
obj->getProperty("numSlices", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->numSlices), ctx);
|
||||
}
|
||||
obj->getProperty("sourceMostDetailedMip", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->sourceMostDetailedMip), ctx);
|
||||
}
|
||||
obj->getProperty("sourceFirstSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->sourceFirstSlice), ctx);
|
||||
}
|
||||
obj->getProperty("sourcePlaneSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->sourcePlaneSlice), ctx);
|
||||
}
|
||||
obj->getProperty("targetMostDetailedMip", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetMostDetailedMip), ctx);
|
||||
}
|
||||
obj->getProperty("targetFirstSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetFirstSlice), ctx);
|
||||
}
|
||||
obj->getProperty("targetPlaneSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetPlaneSlice), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::UploadPair>(const se::Value &from, cc::render::UploadPair *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to UploadPair failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("source", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->source), ctx);
|
||||
}
|
||||
obj->getProperty("target", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->target), ctx);
|
||||
}
|
||||
obj->getProperty("mipLevels", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->mipLevels), ctx);
|
||||
}
|
||||
obj->getProperty("numSlices", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->numSlices), ctx);
|
||||
}
|
||||
obj->getProperty("targetMostDetailedMip", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetMostDetailedMip), ctx);
|
||||
}
|
||||
obj->getProperty("targetFirstSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetFirstSlice), ctx);
|
||||
}
|
||||
obj->getProperty("targetPlaneSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetPlaneSlice), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native<cc::render::MovePair>(const se::Value &from, cc::render::MovePair *to, se::Object *ctx) { // NOLINT
|
||||
SE_PRECONDITION2(from.isObject(), false, " Convert parameter to MovePair failed !");
|
||||
|
||||
auto *obj = const_cast<se::Object *>(from.toObject());
|
||||
bool ok = true;
|
||||
se::Value field;
|
||||
obj->getProperty("source", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->source), ctx);
|
||||
}
|
||||
obj->getProperty("target", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->target), ctx);
|
||||
}
|
||||
obj->getProperty("mipLevels", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->mipLevels), ctx);
|
||||
}
|
||||
obj->getProperty("numSlices", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->numSlices), ctx);
|
||||
}
|
||||
obj->getProperty("targetMostDetailedMip", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetMostDetailedMip), ctx);
|
||||
}
|
||||
obj->getProperty("targetFirstSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetFirstSlice), ctx);
|
||||
}
|
||||
obj->getProperty("targetPlaneSlice", &field, true);
|
||||
if(!field.isNullOrUndefined()) {
|
||||
ok &= sevalue_to_native(field, &(to->targetPlaneSlice), ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
76
cocos/renderer/pipeline/custom/RenderCommonJsb.h
Normal file
76
cocos/renderer/pipeline/custom/RenderCommonJsb.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/bindings/manual/jsb_conversions.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonFwd.h"
|
||||
|
||||
bool nativevalue_to_se(const cc::render::LightInfo &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::Descriptor &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::DescriptorBlockFlattened &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::DescriptorBlockIndex &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::ResolvePair &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::CopyPair &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::UploadPair &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
bool nativevalue_to_se(const cc::render::MovePair &from, se::Value &to, se::Object *ctx); // NOLINT
|
||||
|
||||
// if function overload is used, android build fails
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::LightInfo *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::Descriptor *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::DescriptorBlockFlattened *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::DescriptorBlockIndex *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::ResolvePair *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::CopyPair *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::UploadPair *to, se::Object *ctx); // NOLINT
|
||||
|
||||
template <>
|
||||
bool sevalue_to_native(const se::Value &from, cc::render::MovePair *to, se::Object *ctx); // NOLINT
|
||||
|
||||
// clang-format on
|
||||
165
cocos/renderer/pipeline/custom/RenderCommonNames.h
Normal file
165
cocos/renderer/pipeline/custom/RenderCommonNames.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
inline const char* getName(UpdateFrequency e) noexcept {
|
||||
switch (e) {
|
||||
case UpdateFrequency::PER_INSTANCE: return "PER_INSTANCE";
|
||||
case UpdateFrequency::PER_BATCH: return "PER_BATCH";
|
||||
case UpdateFrequency::PER_PHASE: return "PER_PHASE";
|
||||
case UpdateFrequency::PER_PASS: return "PER_PASS";
|
||||
case UpdateFrequency::COUNT: return "COUNT";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(ParameterType e) noexcept {
|
||||
switch (e) {
|
||||
case ParameterType::CONSTANTS: return "CONSTANTS";
|
||||
case ParameterType::CBV: return "CBV";
|
||||
case ParameterType::UAV: return "UAV";
|
||||
case ParameterType::SRV: return "SRV";
|
||||
case ParameterType::TABLE: return "TABLE";
|
||||
case ParameterType::SSV: return "SSV";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(const RasterPassTag& /*v*/) noexcept { return "RasterPass"; }
|
||||
inline const char* getName(const RasterSubpassTag& /*v*/) noexcept { return "RasterSubpass"; }
|
||||
inline const char* getName(const ComputeSubpassTag& /*v*/) noexcept { return "ComputeSubpass"; }
|
||||
inline const char* getName(const ComputeTag& /*v*/) noexcept { return "Compute"; }
|
||||
inline const char* getName(const ResolveTag& /*v*/) noexcept { return "Resolve"; }
|
||||
inline const char* getName(const CopyTag& /*v*/) noexcept { return "Copy"; }
|
||||
inline const char* getName(const MoveTag& /*v*/) noexcept { return "Move"; }
|
||||
inline const char* getName(const RaytraceTag& /*v*/) noexcept { return "Raytrace"; }
|
||||
inline const char* getName(ResourceResidency e) noexcept {
|
||||
switch (e) {
|
||||
case ResourceResidency::MANAGED: return "MANAGED";
|
||||
case ResourceResidency::MEMORYLESS: return "MEMORYLESS";
|
||||
case ResourceResidency::PERSISTENT: return "PERSISTENT";
|
||||
case ResourceResidency::EXTERNAL: return "EXTERNAL";
|
||||
case ResourceResidency::BACKBUFFER: return "BACKBUFFER";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(QueueHint e) noexcept {
|
||||
switch (e) {
|
||||
case QueueHint::NONE: return "NONE";
|
||||
case QueueHint::OPAQUE: return "OPAQUE";
|
||||
case QueueHint::MASK: return "MASK";
|
||||
case QueueHint::BLEND: return "BLEND";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(ResourceDimension e) noexcept {
|
||||
switch (e) {
|
||||
case ResourceDimension::BUFFER: return "BUFFER";
|
||||
case ResourceDimension::TEXTURE1D: return "TEXTURE1D";
|
||||
case ResourceDimension::TEXTURE2D: return "TEXTURE2D";
|
||||
case ResourceDimension::TEXTURE3D: return "TEXTURE3D";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(const BufferTag& /*v*/) noexcept { return "Buffer"; }
|
||||
inline const char* getName(const TextureTag& /*v*/) noexcept { return "Texture"; }
|
||||
inline const char* getName(TaskType e) noexcept {
|
||||
switch (e) {
|
||||
case TaskType::SYNC: return "SYNC";
|
||||
case TaskType::ASYNC: return "ASYNC";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(LightingMode e) noexcept {
|
||||
switch (e) {
|
||||
case LightingMode::NONE: return "NONE";
|
||||
case LightingMode::DEFAULT: return "DEFAULT";
|
||||
case LightingMode::CLUSTERED: return "CLUSTERED";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(AttachmentType e) noexcept {
|
||||
switch (e) {
|
||||
case AttachmentType::RENDER_TARGET: return "RENDER_TARGET";
|
||||
case AttachmentType::DEPTH_STENCIL: return "DEPTH_STENCIL";
|
||||
case AttachmentType::SHADING_RATE: return "SHADING_RATE";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(AccessType e) noexcept {
|
||||
switch (e) {
|
||||
case AccessType::READ: return "READ";
|
||||
case AccessType::READ_WRITE: return "READ_WRITE";
|
||||
case AccessType::WRITE: return "WRITE";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(ClearValueType e) noexcept {
|
||||
switch (e) {
|
||||
case ClearValueType::NONE: return "NONE";
|
||||
case ClearValueType::FLOAT_TYPE: return "FLOAT_TYPE";
|
||||
case ClearValueType::INT_TYPE: return "INT_TYPE";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(const LightInfo& /*v*/) noexcept { return "LightInfo"; }
|
||||
inline const char* getName(DescriptorTypeOrder e) noexcept {
|
||||
switch (e) {
|
||||
case DescriptorTypeOrder::UNIFORM_BUFFER: return "UNIFORM_BUFFER";
|
||||
case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER: return "DYNAMIC_UNIFORM_BUFFER";
|
||||
case DescriptorTypeOrder::SAMPLER_TEXTURE: return "SAMPLER_TEXTURE";
|
||||
case DescriptorTypeOrder::SAMPLER: return "SAMPLER";
|
||||
case DescriptorTypeOrder::TEXTURE: return "TEXTURE";
|
||||
case DescriptorTypeOrder::STORAGE_BUFFER: return "STORAGE_BUFFER";
|
||||
case DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER: return "DYNAMIC_STORAGE_BUFFER";
|
||||
case DescriptorTypeOrder::STORAGE_IMAGE: return "STORAGE_IMAGE";
|
||||
case DescriptorTypeOrder::INPUT_ATTACHMENT: return "INPUT_ATTACHMENT";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
inline const char* getName(const Descriptor& /*v*/) noexcept { return "Descriptor"; }
|
||||
inline const char* getName(const DescriptorBlock& /*v*/) noexcept { return "DescriptorBlock"; }
|
||||
inline const char* getName(const DescriptorBlockFlattened& /*v*/) noexcept { return "DescriptorBlockFlattened"; }
|
||||
inline const char* getName(const DescriptorBlockIndex& /*v*/) noexcept { return "DescriptorBlockIndex"; }
|
||||
inline const char* getName(const ResolvePair& /*v*/) noexcept { return "ResolvePair"; }
|
||||
inline const char* getName(const CopyPair& /*v*/) noexcept { return "CopyPair"; }
|
||||
inline const char* getName(const UploadPair& /*v*/) noexcept { return "UploadPair"; }
|
||||
inline const char* getName(const MovePair& /*v*/) noexcept { return "MovePair"; }
|
||||
inline const char* getName(const PipelineStatistics& /*v*/) noexcept { return "PipelineStatistics"; }
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
202
cocos/renderer/pipeline/custom/RenderCommonSerialization.h
Normal file
202
cocos/renderer/pipeline/custom/RenderCommonSerialization.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/ArchiveTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Range.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/SerializationUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
inline void save(OutputArchive& ar, const LightInfo& v) {
|
||||
// skip, light: IntrusivePtr<scene::Light>
|
||||
// skip, probe: scene::ReflectionProbe
|
||||
save(ar, v.level);
|
||||
save(ar, v.culledByLight);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, LightInfo& v) {
|
||||
// skip, light: IntrusivePtr<scene::Light>
|
||||
// skip, probe: scene::ReflectionProbe
|
||||
load(ar, v.level);
|
||||
load(ar, v.culledByLight);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const Descriptor& v) {
|
||||
save(ar, v.type);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, Descriptor& v) {
|
||||
load(ar, v.type);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorBlock& v) {
|
||||
save(ar, v.descriptors);
|
||||
save(ar, v.uniformBlocks);
|
||||
save(ar, v.capacity);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorBlock& v) {
|
||||
load(ar, v.descriptors);
|
||||
load(ar, v.uniformBlocks);
|
||||
load(ar, v.capacity);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorBlockFlattened& v) {
|
||||
save(ar, v.descriptorNames);
|
||||
save(ar, v.uniformBlockNames);
|
||||
save(ar, v.descriptors);
|
||||
save(ar, v.uniformBlocks);
|
||||
save(ar, v.capacity);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorBlockFlattened& v) {
|
||||
load(ar, v.descriptorNames);
|
||||
load(ar, v.uniformBlockNames);
|
||||
load(ar, v.descriptors);
|
||||
load(ar, v.uniformBlocks);
|
||||
load(ar, v.capacity);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const DescriptorBlockIndex& v) {
|
||||
save(ar, v.updateFrequency);
|
||||
save(ar, v.parameterType);
|
||||
save(ar, v.descriptorType);
|
||||
save(ar, v.visibility);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, DescriptorBlockIndex& v) {
|
||||
load(ar, v.updateFrequency);
|
||||
load(ar, v.parameterType);
|
||||
load(ar, v.descriptorType);
|
||||
load(ar, v.visibility);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const ResolvePair& v) {
|
||||
save(ar, v.source);
|
||||
save(ar, v.target);
|
||||
save(ar, v.resolveFlags);
|
||||
save(ar, v.mode);
|
||||
save(ar, v.mode1);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, ResolvePair& v) {
|
||||
load(ar, v.source);
|
||||
load(ar, v.target);
|
||||
load(ar, v.resolveFlags);
|
||||
load(ar, v.mode);
|
||||
load(ar, v.mode1);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const CopyPair& v) {
|
||||
save(ar, v.source);
|
||||
save(ar, v.target);
|
||||
save(ar, v.mipLevels);
|
||||
save(ar, v.numSlices);
|
||||
save(ar, v.sourceMostDetailedMip);
|
||||
save(ar, v.sourceFirstSlice);
|
||||
save(ar, v.sourcePlaneSlice);
|
||||
save(ar, v.targetMostDetailedMip);
|
||||
save(ar, v.targetFirstSlice);
|
||||
save(ar, v.targetPlaneSlice);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, CopyPair& v) {
|
||||
load(ar, v.source);
|
||||
load(ar, v.target);
|
||||
load(ar, v.mipLevels);
|
||||
load(ar, v.numSlices);
|
||||
load(ar, v.sourceMostDetailedMip);
|
||||
load(ar, v.sourceFirstSlice);
|
||||
load(ar, v.sourcePlaneSlice);
|
||||
load(ar, v.targetMostDetailedMip);
|
||||
load(ar, v.targetFirstSlice);
|
||||
load(ar, v.targetPlaneSlice);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const MovePair& v) {
|
||||
save(ar, v.source);
|
||||
save(ar, v.target);
|
||||
save(ar, v.mipLevels);
|
||||
save(ar, v.numSlices);
|
||||
save(ar, v.targetMostDetailedMip);
|
||||
save(ar, v.targetFirstSlice);
|
||||
save(ar, v.targetPlaneSlice);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, MovePair& v) {
|
||||
load(ar, v.source);
|
||||
load(ar, v.target);
|
||||
load(ar, v.mipLevels);
|
||||
load(ar, v.numSlices);
|
||||
load(ar, v.targetMostDetailedMip);
|
||||
load(ar, v.targetFirstSlice);
|
||||
load(ar, v.targetPlaneSlice);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const PipelineStatistics& v) {
|
||||
save(ar, v.numRenderPasses);
|
||||
save(ar, v.numManagedTextures);
|
||||
save(ar, v.totalManagedTextures);
|
||||
save(ar, v.numUploadBuffers);
|
||||
save(ar, v.numUploadBufferViews);
|
||||
save(ar, v.numFreeUploadBuffers);
|
||||
save(ar, v.numFreeUploadBufferViews);
|
||||
save(ar, v.numDescriptorSets);
|
||||
save(ar, v.numFreeDescriptorSets);
|
||||
save(ar, v.numInstancingBuffers);
|
||||
save(ar, v.numInstancingUniformBlocks);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, PipelineStatistics& v) {
|
||||
load(ar, v.numRenderPasses);
|
||||
load(ar, v.numManagedTextures);
|
||||
load(ar, v.totalManagedTextures);
|
||||
load(ar, v.numUploadBuffers);
|
||||
load(ar, v.numUploadBufferViews);
|
||||
load(ar, v.numFreeUploadBuffers);
|
||||
load(ar, v.numFreeUploadBufferViews);
|
||||
load(ar, v.numDescriptorSets);
|
||||
load(ar, v.numFreeDescriptorSets);
|
||||
load(ar, v.numInstancingBuffers);
|
||||
load(ar, v.numInstancingUniformBlocks);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
158
cocos/renderer/pipeline/custom/RenderCommonTypes.cpp
Normal file
158
cocos/renderer/pipeline/custom/RenderCommonTypes.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "RenderCommonTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
ResolvePair::ResolvePair(const allocator_type& alloc) noexcept
|
||||
: source(alloc),
|
||||
target(alloc) {}
|
||||
|
||||
ResolvePair::ResolvePair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, ResolveFlags resolveFlagsIn, gfx::ResolveMode modeIn, gfx::ResolveMode mode1In, const allocator_type& alloc) noexcept // NOLINT
|
||||
: source(std::move(sourceIn), alloc),
|
||||
target(std::move(targetIn), alloc),
|
||||
resolveFlags(resolveFlagsIn),
|
||||
mode(modeIn),
|
||||
mode1(mode1In) {}
|
||||
|
||||
ResolvePair::ResolvePair(ResolvePair&& rhs, const allocator_type& alloc)
|
||||
: source(std::move(rhs.source), alloc),
|
||||
target(std::move(rhs.target), alloc),
|
||||
resolveFlags(rhs.resolveFlags),
|
||||
mode(rhs.mode),
|
||||
mode1(rhs.mode1) {}
|
||||
|
||||
ResolvePair::ResolvePair(ResolvePair const& rhs, const allocator_type& alloc)
|
||||
: source(rhs.source, alloc),
|
||||
target(rhs.target, alloc),
|
||||
resolveFlags(rhs.resolveFlags),
|
||||
mode(rhs.mode),
|
||||
mode1(rhs.mode1) {}
|
||||
|
||||
CopyPair::CopyPair(const allocator_type& alloc) noexcept
|
||||
: source(alloc),
|
||||
target(alloc) {}
|
||||
|
||||
CopyPair::CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t sourceMostDetailedMipIn, uint32_t sourceFirstSliceIn, uint32_t sourcePlaneSliceIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: source(std::move(sourceIn), alloc),
|
||||
target(std::move(targetIn), alloc),
|
||||
mipLevels(mipLevelsIn),
|
||||
numSlices(numSlicesIn),
|
||||
sourceMostDetailedMip(sourceMostDetailedMipIn),
|
||||
sourceFirstSlice(sourceFirstSliceIn),
|
||||
sourcePlaneSlice(sourcePlaneSliceIn),
|
||||
targetMostDetailedMip(targetMostDetailedMipIn),
|
||||
targetFirstSlice(targetFirstSliceIn),
|
||||
targetPlaneSlice(targetPlaneSliceIn) {}
|
||||
|
||||
CopyPair::CopyPair(CopyPair&& rhs, const allocator_type& alloc)
|
||||
: source(std::move(rhs.source), alloc),
|
||||
target(std::move(rhs.target), alloc),
|
||||
mipLevels(rhs.mipLevels),
|
||||
numSlices(rhs.numSlices),
|
||||
sourceMostDetailedMip(rhs.sourceMostDetailedMip),
|
||||
sourceFirstSlice(rhs.sourceFirstSlice),
|
||||
sourcePlaneSlice(rhs.sourcePlaneSlice),
|
||||
targetMostDetailedMip(rhs.targetMostDetailedMip),
|
||||
targetFirstSlice(rhs.targetFirstSlice),
|
||||
targetPlaneSlice(rhs.targetPlaneSlice) {}
|
||||
|
||||
CopyPair::CopyPair(CopyPair const& rhs, const allocator_type& alloc)
|
||||
: source(rhs.source, alloc),
|
||||
target(rhs.target, alloc),
|
||||
mipLevels(rhs.mipLevels),
|
||||
numSlices(rhs.numSlices),
|
||||
sourceMostDetailedMip(rhs.sourceMostDetailedMip),
|
||||
sourceFirstSlice(rhs.sourceFirstSlice),
|
||||
sourcePlaneSlice(rhs.sourcePlaneSlice),
|
||||
targetMostDetailedMip(rhs.targetMostDetailedMip),
|
||||
targetFirstSlice(rhs.targetFirstSlice),
|
||||
targetPlaneSlice(rhs.targetPlaneSlice) {}
|
||||
|
||||
UploadPair::UploadPair(const allocator_type& alloc) noexcept
|
||||
: target(alloc) {}
|
||||
|
||||
UploadPair::UploadPair(ccstd::vector<uint8_t> sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: source(std::move(sourceIn)),
|
||||
target(std::move(targetIn), alloc),
|
||||
mipLevels(mipLevelsIn),
|
||||
numSlices(numSlicesIn),
|
||||
targetMostDetailedMip(targetMostDetailedMipIn),
|
||||
targetFirstSlice(targetFirstSliceIn),
|
||||
targetPlaneSlice(targetPlaneSliceIn) {}
|
||||
|
||||
UploadPair::UploadPair(UploadPair&& rhs, const allocator_type& alloc)
|
||||
: source(std::move(rhs.source)),
|
||||
target(std::move(rhs.target), alloc),
|
||||
mipLevels(rhs.mipLevels),
|
||||
numSlices(rhs.numSlices),
|
||||
targetMostDetailedMip(rhs.targetMostDetailedMip),
|
||||
targetFirstSlice(rhs.targetFirstSlice),
|
||||
targetPlaneSlice(rhs.targetPlaneSlice) {}
|
||||
|
||||
MovePair::MovePair(const allocator_type& alloc) noexcept
|
||||
: source(alloc),
|
||||
target(alloc) {}
|
||||
|
||||
MovePair::MovePair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc) noexcept // NOLINT
|
||||
: source(std::move(sourceIn), alloc),
|
||||
target(std::move(targetIn), alloc),
|
||||
mipLevels(mipLevelsIn),
|
||||
numSlices(numSlicesIn),
|
||||
targetMostDetailedMip(targetMostDetailedMipIn),
|
||||
targetFirstSlice(targetFirstSliceIn),
|
||||
targetPlaneSlice(targetPlaneSliceIn) {}
|
||||
|
||||
MovePair::MovePair(MovePair&& rhs, const allocator_type& alloc)
|
||||
: source(std::move(rhs.source), alloc),
|
||||
target(std::move(rhs.target), alloc),
|
||||
mipLevels(rhs.mipLevels),
|
||||
numSlices(rhs.numSlices),
|
||||
targetMostDetailedMip(rhs.targetMostDetailedMip),
|
||||
targetFirstSlice(rhs.targetFirstSlice),
|
||||
targetPlaneSlice(rhs.targetPlaneSlice) {}
|
||||
|
||||
MovePair::MovePair(MovePair const& rhs, const allocator_type& alloc)
|
||||
: source(rhs.source, alloc),
|
||||
target(rhs.target, alloc),
|
||||
mipLevels(rhs.mipLevels),
|
||||
numSlices(rhs.numSlices),
|
||||
targetMostDetailedMip(rhs.targetMostDetailedMip),
|
||||
targetFirstSlice(rhs.targetFirstSlice),
|
||||
targetPlaneSlice(rhs.targetPlaneSlice) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
480
cocos/renderer/pipeline/custom/RenderCommonTypes.h
Normal file
480
cocos/renderer/pipeline/custom/RenderCommonTypes.h
Normal file
@@ -0,0 +1,480 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/Ptr.h"
|
||||
#include "cocos/base/std/container/map.h"
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/renderer/gfx-base/GFXDef-common.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonFwd.h"
|
||||
#include "cocos/scene/Light.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace scene {
|
||||
|
||||
class ReflectionProbe;
|
||||
|
||||
} // namespace scene
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
enum class UpdateFrequency {
|
||||
PER_INSTANCE,
|
||||
PER_BATCH,
|
||||
PER_PHASE,
|
||||
PER_PASS,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
enum class ParameterType {
|
||||
CONSTANTS,
|
||||
CBV,
|
||||
UAV,
|
||||
SRV,
|
||||
TABLE,
|
||||
SSV,
|
||||
};
|
||||
|
||||
struct RasterPassTag {};
|
||||
struct RasterSubpassTag {};
|
||||
struct ComputeSubpassTag {};
|
||||
struct ComputeTag {};
|
||||
struct ResolveTag {};
|
||||
struct CopyTag {};
|
||||
struct MoveTag {};
|
||||
struct RaytraceTag {};
|
||||
|
||||
enum class ResourceResidency {
|
||||
MANAGED,
|
||||
MEMORYLESS,
|
||||
PERSISTENT,
|
||||
EXTERNAL,
|
||||
BACKBUFFER,
|
||||
};
|
||||
|
||||
enum class QueueHint {
|
||||
NONE,
|
||||
OPAQUE,
|
||||
MASK,
|
||||
BLEND,
|
||||
RENDER_OPAQUE = OPAQUE,
|
||||
RENDER_CUTOUT = MASK,
|
||||
RENDER_TRANSPARENT = BLEND,
|
||||
};
|
||||
|
||||
enum class ResourceDimension {
|
||||
BUFFER,
|
||||
TEXTURE1D,
|
||||
TEXTURE2D,
|
||||
TEXTURE3D,
|
||||
};
|
||||
|
||||
enum class ResourceFlags : uint32_t {
|
||||
NONE = 0,
|
||||
UNIFORM = 0x1,
|
||||
INDIRECT = 0x2,
|
||||
STORAGE = 0x4,
|
||||
SAMPLED = 0x8,
|
||||
COLOR_ATTACHMENT = 0x10,
|
||||
DEPTH_STENCIL_ATTACHMENT = 0x20,
|
||||
INPUT_ATTACHMENT = 0x40,
|
||||
SHADING_RATE = 0x80,
|
||||
TRANSFER_SRC = 0x100,
|
||||
TRANSFER_DST = 0x200,
|
||||
};
|
||||
|
||||
constexpr ResourceFlags operator|(const ResourceFlags lhs, const ResourceFlags rhs) noexcept {
|
||||
return static_cast<ResourceFlags>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr ResourceFlags operator&(const ResourceFlags lhs, const ResourceFlags rhs) noexcept {
|
||||
return static_cast<ResourceFlags>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr ResourceFlags& operator|=(ResourceFlags& lhs, const ResourceFlags rhs) noexcept {
|
||||
return lhs = lhs | rhs;
|
||||
}
|
||||
|
||||
constexpr ResourceFlags& operator&=(ResourceFlags& lhs, const ResourceFlags rhs) noexcept {
|
||||
return lhs = lhs & rhs;
|
||||
}
|
||||
|
||||
constexpr bool operator!(ResourceFlags e) noexcept {
|
||||
return e == static_cast<ResourceFlags>(0);
|
||||
}
|
||||
|
||||
constexpr ResourceFlags operator~(ResourceFlags e) noexcept {
|
||||
return static_cast<ResourceFlags>(~static_cast<std::underlying_type_t<ResourceFlags>>(e));
|
||||
}
|
||||
|
||||
constexpr bool any(ResourceFlags e) noexcept {
|
||||
return !!e;
|
||||
}
|
||||
|
||||
struct BufferTag {};
|
||||
struct TextureTag {};
|
||||
|
||||
enum class TaskType {
|
||||
SYNC,
|
||||
ASYNC,
|
||||
};
|
||||
|
||||
enum class SceneFlags : uint32_t {
|
||||
NONE = 0,
|
||||
OPAQUE = 0x1,
|
||||
MASK = 0x2,
|
||||
BLEND = 0x4,
|
||||
OPAQUE_OBJECT = OPAQUE,
|
||||
CUTOUT_OBJECT = MASK,
|
||||
TRANSPARENT_OBJECT = BLEND,
|
||||
SHADOW_CASTER = 0x8,
|
||||
UI = 0x10,
|
||||
DEFAULT_LIGHTING = 0x20,
|
||||
VOLUMETRIC_LIGHTING = 0x40,
|
||||
CLUSTERED_LIGHTING = 0x80,
|
||||
PLANAR_SHADOW = 0x100,
|
||||
GEOMETRY = 0x200,
|
||||
PROFILER = 0x400,
|
||||
DRAW_INSTANCING = 0x800,
|
||||
DRAW_NON_INSTANCING = 0x1000,
|
||||
REFLECTION_PROBE = 0x2000,
|
||||
GPU_DRIVEN = 0x4000,
|
||||
NON_BUILTIN = 0x8000,
|
||||
ALL = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
constexpr SceneFlags operator|(const SceneFlags lhs, const SceneFlags rhs) noexcept {
|
||||
return static_cast<SceneFlags>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr SceneFlags operator&(const SceneFlags lhs, const SceneFlags rhs) noexcept {
|
||||
return static_cast<SceneFlags>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr SceneFlags& operator|=(SceneFlags& lhs, const SceneFlags rhs) noexcept {
|
||||
return lhs = lhs | rhs;
|
||||
}
|
||||
|
||||
constexpr SceneFlags& operator&=(SceneFlags& lhs, const SceneFlags rhs) noexcept {
|
||||
return lhs = lhs & rhs;
|
||||
}
|
||||
|
||||
constexpr bool operator!(SceneFlags e) noexcept {
|
||||
return e == static_cast<SceneFlags>(0);
|
||||
}
|
||||
|
||||
constexpr SceneFlags operator~(SceneFlags e) noexcept {
|
||||
return static_cast<SceneFlags>(~static_cast<std::underlying_type_t<SceneFlags>>(e));
|
||||
}
|
||||
|
||||
constexpr bool any(SceneFlags e) noexcept {
|
||||
return !!e;
|
||||
}
|
||||
|
||||
enum class LightingMode : uint32_t {
|
||||
NONE,
|
||||
DEFAULT,
|
||||
CLUSTERED,
|
||||
};
|
||||
|
||||
enum class AttachmentType {
|
||||
RENDER_TARGET,
|
||||
DEPTH_STENCIL,
|
||||
SHADING_RATE,
|
||||
};
|
||||
|
||||
enum class AccessType {
|
||||
READ,
|
||||
READ_WRITE,
|
||||
WRITE,
|
||||
};
|
||||
|
||||
enum class ClearValueType {
|
||||
NONE,
|
||||
FLOAT_TYPE,
|
||||
INT_TYPE,
|
||||
};
|
||||
|
||||
struct LightInfo {
|
||||
LightInfo() = default;
|
||||
LightInfo(IntrusivePtr<scene::Light> lightIn, uint32_t levelIn, bool culledByLightIn, scene::ReflectionProbe* probeIn) noexcept
|
||||
: light(std::move(lightIn)),
|
||||
probe(probeIn),
|
||||
level(levelIn),
|
||||
culledByLight(culledByLightIn) {}
|
||||
LightInfo(IntrusivePtr<scene::Light> lightIn, uint32_t levelIn) noexcept
|
||||
: light(std::move(lightIn)),
|
||||
level(levelIn) {}
|
||||
|
||||
IntrusivePtr<scene::Light> light;
|
||||
scene::ReflectionProbe* probe{nullptr};
|
||||
uint32_t level{0};
|
||||
bool culledByLight{false};
|
||||
};
|
||||
|
||||
enum class DescriptorTypeOrder {
|
||||
UNIFORM_BUFFER,
|
||||
DYNAMIC_UNIFORM_BUFFER,
|
||||
SAMPLER_TEXTURE,
|
||||
SAMPLER,
|
||||
TEXTURE,
|
||||
STORAGE_BUFFER,
|
||||
DYNAMIC_STORAGE_BUFFER,
|
||||
STORAGE_IMAGE,
|
||||
INPUT_ATTACHMENT,
|
||||
};
|
||||
|
||||
struct Descriptor {
|
||||
Descriptor() = default;
|
||||
Descriptor(gfx::Type typeIn) noexcept // NOLINT
|
||||
: type(typeIn) {}
|
||||
|
||||
gfx::Type type{gfx::Type::UNKNOWN};
|
||||
uint32_t count{1};
|
||||
};
|
||||
|
||||
struct DescriptorBlock {
|
||||
ccstd::map<ccstd::string, Descriptor> descriptors;
|
||||
ccstd::map<ccstd::string, gfx::UniformBlock> uniformBlocks;
|
||||
uint32_t capacity{0};
|
||||
uint32_t count{0};
|
||||
};
|
||||
|
||||
struct DescriptorBlockFlattened {
|
||||
ccstd::vector<ccstd::string> descriptorNames;
|
||||
ccstd::vector<ccstd::string> uniformBlockNames;
|
||||
ccstd::vector<Descriptor> descriptors;
|
||||
ccstd::vector<gfx::UniformBlock> uniformBlocks;
|
||||
uint32_t capacity{0};
|
||||
uint32_t count{0};
|
||||
};
|
||||
|
||||
struct DescriptorBlockIndex {
|
||||
DescriptorBlockIndex() = default;
|
||||
DescriptorBlockIndex(UpdateFrequency updateFrequencyIn, ParameterType parameterTypeIn, DescriptorTypeOrder descriptorTypeIn, gfx::ShaderStageFlagBit visibilityIn) noexcept
|
||||
: updateFrequency(updateFrequencyIn),
|
||||
parameterType(parameterTypeIn),
|
||||
descriptorType(descriptorTypeIn),
|
||||
visibility(visibilityIn) {}
|
||||
|
||||
UpdateFrequency updateFrequency{UpdateFrequency::PER_INSTANCE};
|
||||
ParameterType parameterType{ParameterType::CONSTANTS};
|
||||
DescriptorTypeOrder descriptorType{DescriptorTypeOrder::UNIFORM_BUFFER};
|
||||
gfx::ShaderStageFlagBit visibility{gfx::ShaderStageFlagBit::NONE};
|
||||
};
|
||||
|
||||
inline bool operator<(const DescriptorBlockIndex& lhs, const DescriptorBlockIndex& rhs) noexcept {
|
||||
return std::forward_as_tuple(lhs.updateFrequency, lhs.parameterType, lhs.descriptorType, lhs.visibility) <
|
||||
std::forward_as_tuple(rhs.updateFrequency, rhs.parameterType, rhs.descriptorType, rhs.visibility);
|
||||
}
|
||||
|
||||
enum class ResolveFlags : uint32_t {
|
||||
NONE = 0,
|
||||
COLOR = 1 << 0,
|
||||
DEPTH = 1 << 1,
|
||||
STENCIL = 1 << 2,
|
||||
};
|
||||
|
||||
constexpr ResolveFlags operator|(const ResolveFlags lhs, const ResolveFlags rhs) noexcept {
|
||||
return static_cast<ResolveFlags>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr ResolveFlags operator&(const ResolveFlags lhs, const ResolveFlags rhs) noexcept {
|
||||
return static_cast<ResolveFlags>(static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs));
|
||||
}
|
||||
|
||||
constexpr ResolveFlags& operator|=(ResolveFlags& lhs, const ResolveFlags rhs) noexcept {
|
||||
return lhs = lhs | rhs;
|
||||
}
|
||||
|
||||
constexpr ResolveFlags& operator&=(ResolveFlags& lhs, const ResolveFlags rhs) noexcept {
|
||||
return lhs = lhs & rhs;
|
||||
}
|
||||
|
||||
constexpr bool operator!(ResolveFlags e) noexcept {
|
||||
return e == static_cast<ResolveFlags>(0);
|
||||
}
|
||||
|
||||
constexpr ResolveFlags operator~(ResolveFlags e) noexcept {
|
||||
return static_cast<ResolveFlags>(~static_cast<std::underlying_type_t<ResolveFlags>>(e));
|
||||
}
|
||||
|
||||
constexpr bool any(ResolveFlags e) noexcept {
|
||||
return !!e;
|
||||
}
|
||||
|
||||
struct ResolvePair {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {source.get_allocator().resource()};
|
||||
}
|
||||
|
||||
ResolvePair(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT
|
||||
ResolvePair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, ResolveFlags resolveFlagsIn, gfx::ResolveMode modeIn, gfx::ResolveMode mode1In, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept;
|
||||
ResolvePair(ResolvePair&& rhs, const allocator_type& alloc);
|
||||
ResolvePair(ResolvePair const& rhs, const allocator_type& alloc);
|
||||
|
||||
ResolvePair(ResolvePair&& rhs) noexcept = default;
|
||||
ResolvePair(ResolvePair const& rhs) = delete;
|
||||
ResolvePair& operator=(ResolvePair&& rhs) = default;
|
||||
ResolvePair& operator=(ResolvePair const& rhs) = default;
|
||||
|
||||
ccstd::pmr::string source;
|
||||
ccstd::pmr::string target;
|
||||
ResolveFlags resolveFlags{ResolveFlags::NONE};
|
||||
gfx::ResolveMode mode{gfx::ResolveMode::SAMPLE_ZERO};
|
||||
gfx::ResolveMode mode1{gfx::ResolveMode::SAMPLE_ZERO};
|
||||
};
|
||||
|
||||
inline bool operator==(const ResolvePair& lhs, const ResolvePair& rhs) noexcept {
|
||||
return std::forward_as_tuple(lhs.source, lhs.target, lhs.resolveFlags, lhs.mode, lhs.mode1) ==
|
||||
std::forward_as_tuple(rhs.source, rhs.target, rhs.resolveFlags, rhs.mode, rhs.mode1);
|
||||
}
|
||||
|
||||
inline bool operator!=(const ResolvePair& lhs, const ResolvePair& rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
struct CopyPair {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {source.get_allocator().resource()};
|
||||
}
|
||||
|
||||
CopyPair(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT
|
||||
CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t sourceMostDetailedMipIn, uint32_t sourceFirstSliceIn, uint32_t sourcePlaneSliceIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept;
|
||||
CopyPair(CopyPair&& rhs, const allocator_type& alloc);
|
||||
CopyPair(CopyPair const& rhs, const allocator_type& alloc);
|
||||
|
||||
CopyPair(CopyPair&& rhs) noexcept = default;
|
||||
CopyPair(CopyPair const& rhs) = delete;
|
||||
CopyPair& operator=(CopyPair&& rhs) = default;
|
||||
CopyPair& operator=(CopyPair const& rhs) = default;
|
||||
|
||||
ccstd::pmr::string source;
|
||||
ccstd::pmr::string target;
|
||||
uint32_t mipLevels{0xFFFFFFFF};
|
||||
uint32_t numSlices{0xFFFFFFFF};
|
||||
uint32_t sourceMostDetailedMip{0};
|
||||
uint32_t sourceFirstSlice{0};
|
||||
uint32_t sourcePlaneSlice{0};
|
||||
uint32_t targetMostDetailedMip{0};
|
||||
uint32_t targetFirstSlice{0};
|
||||
uint32_t targetPlaneSlice{0};
|
||||
};
|
||||
|
||||
struct UploadPair {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {target.get_allocator().resource()};
|
||||
}
|
||||
|
||||
UploadPair(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT
|
||||
UploadPair(ccstd::vector<uint8_t> sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept;
|
||||
UploadPair(UploadPair&& rhs, const allocator_type& alloc);
|
||||
|
||||
UploadPair(UploadPair&& rhs) noexcept = default;
|
||||
UploadPair(UploadPair const& rhs) = delete;
|
||||
UploadPair& operator=(UploadPair&& rhs) = default;
|
||||
UploadPair& operator=(UploadPair const& rhs) = delete;
|
||||
|
||||
ccstd::vector<uint8_t> source;
|
||||
ccstd::pmr::string target;
|
||||
uint32_t mipLevels{0xFFFFFFFF};
|
||||
uint32_t numSlices{0xFFFFFFFF};
|
||||
uint32_t targetMostDetailedMip{0};
|
||||
uint32_t targetFirstSlice{0};
|
||||
uint32_t targetPlaneSlice{0};
|
||||
};
|
||||
|
||||
struct MovePair {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return {source.get_allocator().resource()};
|
||||
}
|
||||
|
||||
MovePair(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT
|
||||
MovePair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept;
|
||||
MovePair(MovePair&& rhs, const allocator_type& alloc);
|
||||
MovePair(MovePair const& rhs, const allocator_type& alloc);
|
||||
|
||||
MovePair(MovePair&& rhs) noexcept = default;
|
||||
MovePair(MovePair const& rhs) = delete;
|
||||
MovePair& operator=(MovePair&& rhs) = default;
|
||||
MovePair& operator=(MovePair const& rhs) = default;
|
||||
|
||||
ccstd::pmr::string source;
|
||||
ccstd::pmr::string target;
|
||||
uint32_t mipLevels{0xFFFFFFFF};
|
||||
uint32_t numSlices{0xFFFFFFFF};
|
||||
uint32_t targetMostDetailedMip{0};
|
||||
uint32_t targetFirstSlice{0};
|
||||
uint32_t targetPlaneSlice{0};
|
||||
};
|
||||
|
||||
struct PipelineStatistics {
|
||||
uint32_t numRenderPasses{0};
|
||||
uint32_t numManagedTextures{0};
|
||||
uint32_t totalManagedTextures{0};
|
||||
uint32_t numUploadBuffers{0};
|
||||
uint32_t numUploadBufferViews{0};
|
||||
uint32_t numFreeUploadBuffers{0};
|
||||
uint32_t numFreeUploadBufferViews{0};
|
||||
uint32_t numDescriptorSets{0};
|
||||
uint32_t numFreeDescriptorSets{0};
|
||||
uint32_t numInstancingBuffers{0};
|
||||
uint32_t numInstancingUniformBlocks{0};
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
inline hash_t hash<cc::render::ResolvePair>::operator()(const cc::render::ResolvePair& val) const noexcept {
|
||||
hash_t seed = 0;
|
||||
hash_combine(seed, val.source);
|
||||
hash_combine(seed, val.target);
|
||||
hash_combine(seed, val.resolveFlags);
|
||||
hash_combine(seed, val.mode);
|
||||
hash_combine(seed, val.mode1);
|
||||
return seed;
|
||||
}
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
131
cocos/renderer/pipeline/custom/RenderGraphFwd.h
Normal file
131
cocos/renderer/pipeline/custom/RenderGraphFwd.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/hash/hash.h"
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/RenderCommonFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
struct ClearValue;
|
||||
struct RasterView;
|
||||
struct ComputeView;
|
||||
struct ResourceDesc;
|
||||
struct ResourceTraits;
|
||||
struct RenderSwapchain;
|
||||
struct ResourceStates;
|
||||
struct ManagedBuffer;
|
||||
struct PersistentBuffer;
|
||||
struct ManagedTexture;
|
||||
struct PersistentTexture;
|
||||
struct ManagedResource;
|
||||
struct Subpass;
|
||||
struct SubpassGraph;
|
||||
struct RasterSubpass;
|
||||
struct ComputeSubpass;
|
||||
struct RasterPass;
|
||||
struct PersistentRenderPassAndFramebuffer;
|
||||
struct ManagedTag;
|
||||
struct ManagedBufferTag;
|
||||
struct ManagedTextureTag;
|
||||
struct PersistentBufferTag;
|
||||
struct PersistentTextureTag;
|
||||
struct FramebufferTag;
|
||||
struct SwapchainTag;
|
||||
struct SamplerTag;
|
||||
struct FormatViewTag;
|
||||
struct SubresourceViewTag;
|
||||
struct FormatView;
|
||||
struct SubresourceView;
|
||||
struct ResourceGraph;
|
||||
struct ComputePass;
|
||||
struct ResolvePass;
|
||||
struct CopyPass;
|
||||
struct MovePass;
|
||||
struct RaytracePass;
|
||||
struct QueueTag;
|
||||
struct SceneTag;
|
||||
struct DispatchTag;
|
||||
struct BlitTag;
|
||||
struct ClearTag;
|
||||
struct ViewportTag;
|
||||
struct ClearView;
|
||||
struct RenderQueue;
|
||||
|
||||
enum class CullingFlags : uint32_t;
|
||||
|
||||
struct SceneData;
|
||||
struct Dispatch;
|
||||
struct Blit;
|
||||
struct RenderData;
|
||||
struct RenderGraph;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::ClearValue> {
|
||||
hash_t operator()(const cc::render::ClearValue& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::RasterView> {
|
||||
hash_t operator()(const cc::render::RasterView& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::ComputeView> {
|
||||
hash_t operator()(const cc::render::ComputeView& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::Subpass> {
|
||||
hash_t operator()(const cc::render::Subpass& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::SubpassGraph> {
|
||||
hash_t operator()(const cc::render::SubpassGraph& val) const noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<cc::render::RasterPass> {
|
||||
hash_t operator()(const cc::render::RasterPass& val) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace ccstd
|
||||
|
||||
// clang-format on
|
||||
4746
cocos/renderer/pipeline/custom/RenderGraphGraphs.h
Normal file
4746
cocos/renderer/pipeline/custom/RenderGraphGraphs.h
Normal file
File diff suppressed because it is too large
Load Diff
498
cocos/renderer/pipeline/custom/RenderGraphTypes.cpp
Normal file
498
cocos/renderer/pipeline/custom/RenderGraphTypes.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "RenderGraphTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
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
|
||||
: slotName(std::move(slotNameIn), alloc),
|
||||
slotName1(alloc),
|
||||
accessType(accessTypeIn),
|
||||
attachmentType(attachmentTypeIn),
|
||||
loadOp(loadOpIn),
|
||||
storeOp(storeOpIn),
|
||||
clearFlags(clearFlagsIn),
|
||||
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
|
||||
: slotName(std::move(slotNameIn), alloc),
|
||||
slotName1(std::move(slotName1In), alloc),
|
||||
accessType(accessTypeIn),
|
||||
attachmentType(attachmentTypeIn),
|
||||
loadOp(loadOpIn),
|
||||
storeOp(storeOpIn),
|
||||
clearFlags(clearFlagsIn),
|
||||
clearColor(clearColorIn),
|
||||
shaderStageFlags(shaderStageFlagsIn) {}
|
||||
|
||||
RasterView::RasterView(RasterView&& rhs, const allocator_type& alloc)
|
||||
: slotName(std::move(rhs.slotName), alloc),
|
||||
slotName1(std::move(rhs.slotName1), alloc),
|
||||
accessType(rhs.accessType),
|
||||
attachmentType(rhs.attachmentType),
|
||||
loadOp(rhs.loadOp),
|
||||
storeOp(rhs.storeOp),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearColor(rhs.clearColor),
|
||||
slotID(rhs.slotID),
|
||||
shaderStageFlags(rhs.shaderStageFlags) {}
|
||||
|
||||
RasterView::RasterView(RasterView const& rhs, const allocator_type& alloc)
|
||||
: slotName(rhs.slotName, alloc),
|
||||
slotName1(rhs.slotName1, alloc),
|
||||
accessType(rhs.accessType),
|
||||
attachmentType(rhs.attachmentType),
|
||||
loadOp(rhs.loadOp),
|
||||
storeOp(rhs.storeOp),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearColor(rhs.clearColor),
|
||||
slotID(rhs.slotID),
|
||||
shaderStageFlags(rhs.shaderStageFlags) {}
|
||||
|
||||
ComputeView::ComputeView(const allocator_type& alloc) noexcept
|
||||
: name(alloc) {}
|
||||
|
||||
ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept
|
||||
: name(std::move(nameIn), alloc),
|
||||
accessType(accessTypeIn),
|
||||
clearFlags(clearFlagsIn),
|
||||
clearValueType(clearValueTypeIn),
|
||||
clearValue(clearValueIn),
|
||||
shaderStageFlags(shaderStageFlagsIn) {}
|
||||
|
||||
ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, uint32_t planeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept
|
||||
: name(std::move(nameIn), alloc),
|
||||
accessType(accessTypeIn),
|
||||
plane(planeIn),
|
||||
clearFlags(clearFlagsIn),
|
||||
clearValueType(clearValueTypeIn),
|
||||
clearValue(clearValueIn),
|
||||
shaderStageFlags(shaderStageFlagsIn) {}
|
||||
|
||||
ComputeView::ComputeView(ComputeView&& rhs, const allocator_type& alloc)
|
||||
: name(std::move(rhs.name), alloc),
|
||||
accessType(rhs.accessType),
|
||||
plane(rhs.plane),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearValueType(rhs.clearValueType),
|
||||
clearValue(rhs.clearValue),
|
||||
shaderStageFlags(rhs.shaderStageFlags) {}
|
||||
|
||||
ComputeView::ComputeView(ComputeView const& rhs, const allocator_type& alloc)
|
||||
: name(rhs.name, alloc),
|
||||
accessType(rhs.accessType),
|
||||
plane(rhs.plane),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearValueType(rhs.clearValueType),
|
||||
clearValue(rhs.clearValue),
|
||||
shaderStageFlags(rhs.shaderStageFlags) {}
|
||||
|
||||
Subpass::Subpass(const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc),
|
||||
resolvePairs(alloc) {}
|
||||
|
||||
Subpass::Subpass(Subpass&& rhs, const allocator_type& alloc)
|
||||
: rasterViews(std::move(rhs.rasterViews), alloc),
|
||||
computeViews(std::move(rhs.computeViews), alloc),
|
||||
resolvePairs(std::move(rhs.resolvePairs), alloc) {}
|
||||
|
||||
Subpass::Subpass(Subpass const& rhs, const allocator_type& alloc)
|
||||
: rasterViews(rhs.rasterViews, alloc),
|
||||
computeViews(rhs.computeViews, alloc),
|
||||
resolvePairs(rhs.resolvePairs, alloc) {}
|
||||
|
||||
SubpassGraph::SubpassGraph(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
names(alloc),
|
||||
subpasses(alloc) {}
|
||||
|
||||
SubpassGraph::SubpassGraph(SubpassGraph&& rhs, const allocator_type& alloc)
|
||||
: _vertices(std::move(rhs._vertices), alloc),
|
||||
names(std::move(rhs.names), alloc),
|
||||
subpasses(std::move(rhs.subpasses), alloc) {}
|
||||
|
||||
SubpassGraph::SubpassGraph(SubpassGraph const& rhs, const allocator_type& alloc)
|
||||
: _vertices(rhs._vertices, alloc),
|
||||
names(rhs.names, alloc),
|
||||
subpasses(rhs.subpasses, alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void SubpassGraph::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
names.reserve(sz);
|
||||
subpasses.reserve(sz);
|
||||
}
|
||||
|
||||
SubpassGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
SubpassGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc) {}
|
||||
|
||||
SubpassGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc) {}
|
||||
|
||||
RasterSubpass::RasterSubpass(const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc),
|
||||
resolvePairs(alloc) {}
|
||||
|
||||
RasterSubpass::RasterSubpass(uint32_t subpassIDIn, uint32_t countIn, uint32_t qualityIn, const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc),
|
||||
resolvePairs(alloc),
|
||||
subpassID(subpassIDIn),
|
||||
count(countIn),
|
||||
quality(qualityIn) {}
|
||||
|
||||
RasterSubpass::RasterSubpass(RasterSubpass&& rhs, const allocator_type& alloc)
|
||||
: rasterViews(std::move(rhs.rasterViews), alloc),
|
||||
computeViews(std::move(rhs.computeViews), alloc),
|
||||
resolvePairs(std::move(rhs.resolvePairs), alloc),
|
||||
viewport(rhs.viewport),
|
||||
subpassID(rhs.subpassID),
|
||||
count(rhs.count),
|
||||
quality(rhs.quality),
|
||||
showStatistics(rhs.showStatistics) {}
|
||||
|
||||
RasterSubpass::RasterSubpass(RasterSubpass const& rhs, const allocator_type& alloc)
|
||||
: rasterViews(rhs.rasterViews, alloc),
|
||||
computeViews(rhs.computeViews, alloc),
|
||||
resolvePairs(rhs.resolvePairs, alloc),
|
||||
viewport(rhs.viewport),
|
||||
subpassID(rhs.subpassID),
|
||||
count(rhs.count),
|
||||
quality(rhs.quality),
|
||||
showStatistics(rhs.showStatistics) {}
|
||||
|
||||
ComputeSubpass::ComputeSubpass(const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc) {}
|
||||
|
||||
ComputeSubpass::ComputeSubpass(uint32_t subpassIDIn, const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc),
|
||||
subpassID(subpassIDIn) {}
|
||||
|
||||
ComputeSubpass::ComputeSubpass(ComputeSubpass&& rhs, const allocator_type& alloc)
|
||||
: rasterViews(std::move(rhs.rasterViews), alloc),
|
||||
computeViews(std::move(rhs.computeViews), alloc),
|
||||
subpassID(rhs.subpassID) {}
|
||||
|
||||
ComputeSubpass::ComputeSubpass(ComputeSubpass const& rhs, const allocator_type& alloc)
|
||||
: rasterViews(rhs.rasterViews, alloc),
|
||||
computeViews(rhs.computeViews, alloc),
|
||||
subpassID(rhs.subpassID) {}
|
||||
|
||||
RasterPass::RasterPass(const allocator_type& alloc) noexcept
|
||||
: rasterViews(alloc),
|
||||
computeViews(alloc),
|
||||
attachmentIndexMap(alloc),
|
||||
textures(alloc),
|
||||
subpassGraph(alloc),
|
||||
versionName(alloc) {}
|
||||
|
||||
RasterPass::RasterPass(RasterPass&& rhs, const allocator_type& alloc)
|
||||
: rasterViews(std::move(rhs.rasterViews), alloc),
|
||||
computeViews(std::move(rhs.computeViews), alloc),
|
||||
attachmentIndexMap(std::move(rhs.attachmentIndexMap), alloc),
|
||||
textures(std::move(rhs.textures), alloc),
|
||||
subpassGraph(std::move(rhs.subpassGraph), alloc),
|
||||
width(rhs.width),
|
||||
height(rhs.height),
|
||||
count(rhs.count),
|
||||
quality(rhs.quality),
|
||||
viewport(rhs.viewport),
|
||||
versionName(std::move(rhs.versionName), alloc),
|
||||
version(rhs.version),
|
||||
hashValue(rhs.hashValue),
|
||||
showStatistics(rhs.showStatistics) {}
|
||||
|
||||
RasterPass::RasterPass(RasterPass const& rhs, const allocator_type& alloc)
|
||||
: rasterViews(rhs.rasterViews, alloc),
|
||||
computeViews(rhs.computeViews, alloc),
|
||||
attachmentIndexMap(rhs.attachmentIndexMap, alloc),
|
||||
textures(rhs.textures, alloc),
|
||||
subpassGraph(rhs.subpassGraph, alloc),
|
||||
width(rhs.width),
|
||||
height(rhs.height),
|
||||
count(rhs.count),
|
||||
quality(rhs.quality),
|
||||
viewport(rhs.viewport),
|
||||
versionName(rhs.versionName, alloc),
|
||||
version(rhs.version),
|
||||
hashValue(rhs.hashValue),
|
||||
showStatistics(rhs.showStatistics) {}
|
||||
|
||||
PersistentRenderPassAndFramebuffer::PersistentRenderPassAndFramebuffer(const allocator_type& alloc) noexcept
|
||||
: clearColors(alloc) {}
|
||||
|
||||
PersistentRenderPassAndFramebuffer::PersistentRenderPassAndFramebuffer(IntrusivePtr<gfx::RenderPass> renderPassIn, IntrusivePtr<gfx::Framebuffer> framebufferIn, const allocator_type& alloc) noexcept
|
||||
: renderPass(std::move(renderPassIn)),
|
||||
framebuffer(std::move(framebufferIn)),
|
||||
clearColors(alloc) {}
|
||||
|
||||
PersistentRenderPassAndFramebuffer::PersistentRenderPassAndFramebuffer(PersistentRenderPassAndFramebuffer&& rhs, const allocator_type& alloc)
|
||||
: renderPass(std::move(rhs.renderPass)),
|
||||
framebuffer(std::move(rhs.framebuffer)),
|
||||
clearColors(std::move(rhs.clearColors), alloc),
|
||||
clearDepth(rhs.clearDepth),
|
||||
clearStencil(rhs.clearStencil) {}
|
||||
|
||||
PersistentRenderPassAndFramebuffer::PersistentRenderPassAndFramebuffer(PersistentRenderPassAndFramebuffer const& rhs, const allocator_type& alloc)
|
||||
: renderPass(rhs.renderPass),
|
||||
framebuffer(rhs.framebuffer),
|
||||
clearColors(rhs.clearColors, alloc),
|
||||
clearDepth(rhs.clearDepth),
|
||||
clearStencil(rhs.clearStencil) {}
|
||||
|
||||
ResourceGraph::ResourceGraph(const allocator_type& alloc) noexcept
|
||||
: _vertices(alloc),
|
||||
names(alloc),
|
||||
descs(alloc),
|
||||
traits(alloc),
|
||||
states(alloc),
|
||||
samplerInfo(alloc),
|
||||
resources(alloc),
|
||||
managedBuffers(alloc),
|
||||
managedTextures(alloc),
|
||||
buffers(alloc),
|
||||
textures(alloc),
|
||||
framebuffers(alloc),
|
||||
swapchains(alloc),
|
||||
formatViews(alloc),
|
||||
subresourceViews(alloc),
|
||||
valueIndex(alloc),
|
||||
renderPasses(alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void ResourceGraph::reserve(vertices_size_type sz) {
|
||||
_vertices.reserve(sz);
|
||||
names.reserve(sz);
|
||||
descs.reserve(sz);
|
||||
traits.reserve(sz);
|
||||
states.reserve(sz);
|
||||
samplerInfo.reserve(sz);
|
||||
}
|
||||
|
||||
ResourceGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
ResourceGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc),
|
||||
handle(std::move(rhs.handle)) {}
|
||||
|
||||
ResourceGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc),
|
||||
handle(rhs.handle) {}
|
||||
|
||||
ComputePass::ComputePass(const allocator_type& alloc) noexcept
|
||||
: computeViews(alloc),
|
||||
textures(alloc) {}
|
||||
|
||||
ComputePass::ComputePass(ComputePass&& rhs, const allocator_type& alloc)
|
||||
: computeViews(std::move(rhs.computeViews), alloc),
|
||||
textures(std::move(rhs.textures), alloc) {}
|
||||
|
||||
ComputePass::ComputePass(ComputePass const& rhs, const allocator_type& alloc)
|
||||
: computeViews(rhs.computeViews, alloc),
|
||||
textures(rhs.textures, alloc) {}
|
||||
|
||||
ResolvePass::ResolvePass(const allocator_type& alloc) noexcept
|
||||
: resolvePairs(alloc) {}
|
||||
|
||||
ResolvePass::ResolvePass(ResolvePass&& rhs, const allocator_type& alloc)
|
||||
: resolvePairs(std::move(rhs.resolvePairs), alloc) {}
|
||||
|
||||
ResolvePass::ResolvePass(ResolvePass const& rhs, const allocator_type& alloc)
|
||||
: resolvePairs(rhs.resolvePairs, alloc) {}
|
||||
|
||||
CopyPass::CopyPass(const allocator_type& alloc) noexcept
|
||||
: copyPairs(alloc),
|
||||
uploadPairs(alloc) {}
|
||||
|
||||
CopyPass::CopyPass(CopyPass&& rhs, const allocator_type& alloc)
|
||||
: copyPairs(std::move(rhs.copyPairs), alloc),
|
||||
uploadPairs(std::move(rhs.uploadPairs), alloc) {}
|
||||
|
||||
MovePass::MovePass(const allocator_type& alloc) noexcept
|
||||
: movePairs(alloc) {}
|
||||
|
||||
MovePass::MovePass(MovePass&& rhs, const allocator_type& alloc)
|
||||
: movePairs(std::move(rhs.movePairs), alloc) {}
|
||||
|
||||
MovePass::MovePass(MovePass const& rhs, const allocator_type& alloc)
|
||||
: movePairs(rhs.movePairs, alloc) {}
|
||||
|
||||
RaytracePass::RaytracePass(const allocator_type& alloc) noexcept
|
||||
: computeViews(alloc) {}
|
||||
|
||||
RaytracePass::RaytracePass(RaytracePass&& rhs, const allocator_type& alloc)
|
||||
: computeViews(std::move(rhs.computeViews), alloc) {}
|
||||
|
||||
RaytracePass::RaytracePass(RaytracePass const& rhs, const allocator_type& alloc)
|
||||
: computeViews(rhs.computeViews, 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
|
||||
: slotName(std::move(slotNameIn), alloc),
|
||||
clearFlags(clearFlagsIn),
|
||||
clearColor(clearColorIn) {}
|
||||
|
||||
ClearView::ClearView(ClearView&& rhs, const allocator_type& alloc)
|
||||
: slotName(std::move(rhs.slotName), alloc),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearColor(rhs.clearColor) {}
|
||||
|
||||
ClearView::ClearView(ClearView const& rhs, const allocator_type& alloc)
|
||||
: slotName(rhs.slotName, alloc),
|
||||
clearFlags(rhs.clearFlags),
|
||||
clearColor(rhs.clearColor) {}
|
||||
|
||||
RenderData::RenderData(const allocator_type& alloc) noexcept
|
||||
: constants(alloc),
|
||||
buffers(alloc),
|
||||
textures(alloc),
|
||||
samplers(alloc),
|
||||
custom(alloc) {}
|
||||
|
||||
RenderData::RenderData(RenderData&& rhs, const allocator_type& alloc)
|
||||
: constants(std::move(rhs.constants), alloc),
|
||||
buffers(std::move(rhs.buffers), alloc),
|
||||
textures(std::move(rhs.textures), alloc),
|
||||
samplers(std::move(rhs.samplers), alloc),
|
||||
custom(std::move(rhs.custom), alloc) {}
|
||||
|
||||
RenderGraph::RenderGraph(const allocator_type& alloc) noexcept
|
||||
: objects(alloc),
|
||||
_vertices(alloc),
|
||||
names(alloc),
|
||||
layoutNodes(alloc),
|
||||
data(alloc),
|
||||
valid(alloc),
|
||||
rasterPasses(alloc),
|
||||
rasterSubpasses(alloc),
|
||||
computeSubpasses(alloc),
|
||||
computePasses(alloc),
|
||||
resolvePasses(alloc),
|
||||
copyPasses(alloc),
|
||||
movePasses(alloc),
|
||||
raytracePasses(alloc),
|
||||
renderQueues(alloc),
|
||||
scenes(alloc),
|
||||
blits(alloc),
|
||||
dispatches(alloc),
|
||||
clearViews(alloc),
|
||||
viewports(alloc),
|
||||
index(alloc),
|
||||
sortedVertices(alloc) {}
|
||||
|
||||
RenderGraph::RenderGraph(RenderGraph&& rhs, const allocator_type& alloc)
|
||||
: objects(std::move(rhs.objects), alloc),
|
||||
_vertices(std::move(rhs._vertices), alloc),
|
||||
names(std::move(rhs.names), alloc),
|
||||
layoutNodes(std::move(rhs.layoutNodes), alloc),
|
||||
data(std::move(rhs.data), alloc),
|
||||
valid(std::move(rhs.valid), alloc),
|
||||
rasterPasses(std::move(rhs.rasterPasses), alloc),
|
||||
rasterSubpasses(std::move(rhs.rasterSubpasses), alloc),
|
||||
computeSubpasses(std::move(rhs.computeSubpasses), alloc),
|
||||
computePasses(std::move(rhs.computePasses), alloc),
|
||||
resolvePasses(std::move(rhs.resolvePasses), alloc),
|
||||
copyPasses(std::move(rhs.copyPasses), alloc),
|
||||
movePasses(std::move(rhs.movePasses), alloc),
|
||||
raytracePasses(std::move(rhs.raytracePasses), alloc),
|
||||
renderQueues(std::move(rhs.renderQueues), alloc),
|
||||
scenes(std::move(rhs.scenes), alloc),
|
||||
blits(std::move(rhs.blits), alloc),
|
||||
dispatches(std::move(rhs.dispatches), alloc),
|
||||
clearViews(std::move(rhs.clearViews), alloc),
|
||||
viewports(std::move(rhs.viewports), alloc),
|
||||
index(std::move(rhs.index), alloc),
|
||||
sortedVertices(std::move(rhs.sortedVertices), alloc) {}
|
||||
|
||||
// ContinuousContainer
|
||||
void RenderGraph::reserve(vertices_size_type sz) {
|
||||
objects.reserve(sz);
|
||||
_vertices.reserve(sz);
|
||||
names.reserve(sz);
|
||||
layoutNodes.reserve(sz);
|
||||
data.reserve(sz);
|
||||
valid.reserve(sz);
|
||||
}
|
||||
|
||||
RenderGraph::Object::Object(const allocator_type& alloc) noexcept
|
||||
: children(alloc),
|
||||
parents(alloc) {}
|
||||
|
||||
RenderGraph::Object::Object(Object&& rhs, const allocator_type& alloc)
|
||||
: children(std::move(rhs.children), alloc),
|
||||
parents(std::move(rhs.parents), alloc) {}
|
||||
|
||||
RenderGraph::Object::Object(Object const& rhs, const allocator_type& alloc)
|
||||
: children(rhs.children, alloc),
|
||||
parents(rhs.parents, alloc) {}
|
||||
|
||||
RenderGraph::Vertex::Vertex(const allocator_type& alloc) noexcept
|
||||
: outEdges(alloc),
|
||||
inEdges(alloc) {}
|
||||
|
||||
RenderGraph::Vertex::Vertex(Vertex&& rhs, const allocator_type& alloc)
|
||||
: outEdges(std::move(rhs.outEdges), alloc),
|
||||
inEdges(std::move(rhs.inEdges), alloc),
|
||||
handle(std::move(rhs.handle)) {}
|
||||
|
||||
RenderGraph::Vertex::Vertex(Vertex const& rhs, const allocator_type& alloc)
|
||||
: outEdges(rhs.outEdges, alloc),
|
||||
inEdges(rhs.inEdges, alloc),
|
||||
handle(rhs.handle) {}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
1262
cocos/renderer/pipeline/custom/RenderGraphTypes.h
Normal file
1262
cocos/renderer/pipeline/custom/RenderGraphTypes.h
Normal file
File diff suppressed because it is too large
Load Diff
68
cocos/renderer/pipeline/custom/RenderInterfaceFwd.h
Normal file
68
cocos/renderer/pipeline/custom/RenderInterfaceFwd.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#pragma once
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/CustomFwd.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
class PipelineRuntime;
|
||||
|
||||
enum class PipelineType;
|
||||
enum class SubpassCapabilities : uint32_t;
|
||||
|
||||
struct PipelineCapabilities;
|
||||
class RenderNode;
|
||||
class Setter;
|
||||
class SceneBuilder;
|
||||
class RenderQueueBuilder;
|
||||
class BasicRenderPassBuilder;
|
||||
class BasicMultisampleRenderPassBuilder;
|
||||
class BasicPipeline;
|
||||
class RenderSubpassBuilder;
|
||||
class MultisampleRenderSubpassBuilder;
|
||||
class ComputeQueueBuilder;
|
||||
class ComputeSubpassBuilder;
|
||||
class RenderPassBuilder;
|
||||
class MultisampleRenderPassBuilder;
|
||||
class ComputePassBuilder;
|
||||
class Pipeline;
|
||||
class PipelineBuilder;
|
||||
class RenderingModule;
|
||||
class Factory;
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
41
cocos/renderer/pipeline/custom/RenderInterfaceTypes.cpp
Normal file
41
cocos/renderer/pipeline/custom/RenderInterfaceTypes.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
* The following section is auto-generated.
|
||||
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
|
||||
*/
|
||||
// clang-format off
|
||||
#include "RenderInterfaceTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
// clang-format on
|
||||
1805
cocos/renderer/pipeline/custom/RenderInterfaceTypes.h
Normal file
1805
cocos/renderer/pipeline/custom/RenderInterfaceTypes.h
Normal file
File diff suppressed because it is too large
Load Diff
37
cocos/renderer/pipeline/custom/RenderingModule.h
Normal file
37
cocos/renderer/pipeline/custom/RenderingModule.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "cocos/renderer/pipeline/custom/PrivateTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
ProgramLibrary* getProgramLibrary();
|
||||
RenderingModule* getRenderingModule();
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
164
cocos/renderer/pipeline/custom/details/DebugUtils.h
Normal file
164
cocos/renderer/pipeline/custom/details/DebugUtils.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include "cocos/base/std/container/string.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class String>
|
||||
class Indent {
|
||||
public:
|
||||
explicit Indent(String& indent)
|
||||
: mIndent(&indent) {
|
||||
mIndent->append(" ");
|
||||
}
|
||||
~Indent() {
|
||||
reset();
|
||||
}
|
||||
Indent(Indent&& rhs) noexcept
|
||||
: mIndent(rhs.mIndent) {
|
||||
rhs.mIndent = nullptr;
|
||||
}
|
||||
Indent& operator=(Indent&& rhs) noexcept {
|
||||
mIndent = rhs.mIndent;
|
||||
rhs.mIndent = nullptr;
|
||||
return *this;
|
||||
}
|
||||
void reset() {
|
||||
if (mIndent) {
|
||||
mIndent->erase(mIndent->size() - 4);
|
||||
mIndent = nullptr;
|
||||
}
|
||||
}
|
||||
String* mIndent = nullptr;
|
||||
};
|
||||
|
||||
inline void indent(ccstd::string& str) {
|
||||
str.append(" ");
|
||||
}
|
||||
|
||||
inline void indent(ccstd::pmr::string& str) {
|
||||
str.append(" ");
|
||||
}
|
||||
|
||||
inline void unindent(ccstd::string& str) noexcept {
|
||||
auto sz = str.size() < static_cast<size_t>(4) ? str.size() : static_cast<size_t>(4);
|
||||
str.erase(str.size() - sz);
|
||||
}
|
||||
|
||||
inline void unindent(ccstd::pmr::string& str) noexcept {
|
||||
auto sz = str.size() < static_cast<size_t>(4) ? str.size() : static_cast<size_t>(4);
|
||||
str.erase(str.size() - sz);
|
||||
}
|
||||
|
||||
inline void copyString(
|
||||
std::ostream& os,
|
||||
std::string_view space, std::string_view str, // NOLINT(bugprone-easily-swappable-parameters)
|
||||
bool append = false) {
|
||||
std::istringstream iss{ccstd::string(str)};
|
||||
ccstd::string line;
|
||||
int count = 0;
|
||||
while (std::getline(iss, line)) {
|
||||
if (line.empty()) {
|
||||
os << '\n';
|
||||
} else if (line[0] == '#') {
|
||||
os << line << '\n';
|
||||
} else {
|
||||
if (append) {
|
||||
if (count == 0) {
|
||||
os << line;
|
||||
} else {
|
||||
os << '\n'
|
||||
<< space << line;
|
||||
}
|
||||
} else {
|
||||
os << space << line << '\n';
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
inline void copyString(std::ostream& os, std::string_view str) {
|
||||
std::istringstream iss{ccstd::string(str)};
|
||||
ccstd::string line;
|
||||
while (std::getline(iss, line)) {
|
||||
if (line.empty()) {
|
||||
os << '\n';
|
||||
} else {
|
||||
os << line << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void copyCppString(
|
||||
std::ostream& os,
|
||||
std::string_view space, std::string_view str, // NOLINT(bugprone-easily-swappable-parameters)
|
||||
bool append = false) {
|
||||
std::istringstream iss{ccstd::string(str)};
|
||||
ccstd::string line;
|
||||
int count = 0;
|
||||
while (std::getline(iss, line)) {
|
||||
if (line.empty()) {
|
||||
os << '\n';
|
||||
} else if (line[0] == '#') {
|
||||
os << line << '\n';
|
||||
} else if (*line.rbegin() == ':') {
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1920
|
||||
os << space << line << '\n';
|
||||
#else
|
||||
os << space.substr(0, std::max(static_cast<size_t>(4), space.size()) - 4) << line << "\n";
|
||||
#endif
|
||||
} else {
|
||||
if (append) {
|
||||
if (count == 0) {
|
||||
os << line;
|
||||
} else {
|
||||
os << '\n'
|
||||
<< space << line;
|
||||
}
|
||||
} else {
|
||||
os << space << line << '\n';
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
#define OSS oss << space
|
||||
|
||||
#define INDENT(...) Indent<std::remove_reference_t<decltype(space)>> ind_##__VA_ARGS__(space)
|
||||
#define UNINDENT(...) ind_##__VA_ARGS__.reset()
|
||||
|
||||
#define INDENT_BEG() space.append(" ")
|
||||
#define INDENT_END() space.erase(std::max(space.size(), size_t(4)) - 4)
|
||||
678
cocos/renderer/pipeline/custom/details/GraphImpl.h
Normal file
678
cocos/renderer/pipeline/custom/details/GraphImpl.h
Normal file
@@ -0,0 +1,678 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <functional>
|
||||
#include "cocos/base/std/container/vector.h"
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GraphTypes.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace impl {
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// PropertyMap
|
||||
//--------------------------------------------------------------------
|
||||
template <class Category, class Graph, class Value, class Reference>
|
||||
struct VectorVertexBundlePropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexBundlePropertyMap<Category, Graph, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexBundlePropertyMap(Graph &g) noexcept // NOLINT(google-explicit-constructor)
|
||||
: graph(&g) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return graph->mVertices[v].property;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Value, class Reference>
|
||||
struct PointerVertexBundlePropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, PointerVertexBundlePropertyMap<Category, Graph, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
PointerVertexBundlePropertyMap(Graph &g) noexcept // NOLINT(google-explicit-constructor)
|
||||
: graph(&g) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
auto *sv = static_cast<typename Graph::vertex_type *>(v);
|
||||
return sv->property;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Value, class Reference, class MemberPointer>
|
||||
struct VectorVertexBundleMemberPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexBundleMemberPropertyMap<Category, Graph, Value, Reference, MemberPointer>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexBundleMemberPropertyMap(Graph &g, MemberPointer ptr) noexcept
|
||||
: graph(&g), memberPointer(ptr) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return graph->mVertices[v].property.*memberPointer;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
MemberPointer memberPointer{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Value, class Reference, class MemberPointer>
|
||||
struct PointerVertexBundleMemberPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, PointerVertexBundleMemberPropertyMap<Category, Graph, Value, Reference, MemberPointer>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
PointerVertexBundleMemberPropertyMap(Graph &g, MemberPointer ptr) noexcept
|
||||
: graph(&g), memberPointer(ptr) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
auto *sv = static_cast<typename Graph::vertex_type *>(v);
|
||||
return sv->property.*memberPointer;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
MemberPointer memberPointer{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Container, class Value, class Reference>
|
||||
struct VectorVertexComponentPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexComponentPropertyMap<Category, Graph, Container, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexComponentPropertyMap(Container &c) noexcept // NOLINT(google-explicit-constructor)
|
||||
: container(&c) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return (*container)[v];
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Container *container{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Container, class Value, class Reference, class MemberPointer>
|
||||
struct VectorVertexComponentMemberPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexComponentMemberPropertyMap<Category, Graph, Container, Value, Reference, MemberPointer>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexComponentMemberPropertyMap(Container &c, MemberPointer ptr) noexcept
|
||||
: container(&c), memberPointer(ptr) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return (*container)[v].*memberPointer;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Container *container{};
|
||||
MemberPointer memberPointer{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class ComponentPointer, class Value, class Reference>
|
||||
struct VectorVertexIteratorComponentPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexIteratorComponentPropertyMap<Category, Graph, ComponentPointer, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexIteratorComponentPropertyMap(Graph &g, ComponentPointer component) noexcept
|
||||
: graph(&g), componentPointer(component) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return *(graph->mVertices[v].*componentPointer);
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
ComponentPointer componentPointer{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class ComponentPointer, class Value, class Reference, class MemberPointer>
|
||||
struct VectorVertexIteratorComponentMemberPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorVertexIteratorComponentMemberPropertyMap<Category, Graph, ComponentPointer, Value, Reference, MemberPointer>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::vertex_descriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorVertexIteratorComponentMemberPropertyMap(Graph &g, ComponentPointer component, MemberPointer ptr) noexcept
|
||||
: graph(&g), componentPointer(component), memberPointer(ptr) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return (*(graph->mVertices[v].*componentPointer)).*memberPointer;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
ComponentPointer componentPointer{};
|
||||
MemberPointer memberPointer{};
|
||||
};
|
||||
|
||||
template <class Category, class VertexDescriptor, class Container, class Value, class Reference>
|
||||
struct VectorPathPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, VectorPathPropertyMap<Category, VertexDescriptor, Container, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = VertexDescriptor;
|
||||
using category = Category;
|
||||
|
||||
VectorPathPropertyMap(Container &c) noexcept // NOLINT(google-explicit-constructor)
|
||||
: container(&c) {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return (*container)[v].mPathIterator->first;
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
Container *container{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Value, class Reference>
|
||||
struct EdgeBundlePropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, EdgeBundlePropertyMap<Category, Graph, Value, Reference>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::edge_descriptor;
|
||||
using category = Category;
|
||||
|
||||
EdgeBundlePropertyMap(Graph &g) noexcept // NOLINT(google-explicit-constructor)
|
||||
: graph(&g) {}
|
||||
|
||||
inline reference operator[](const key_type &e) const noexcept {
|
||||
return *static_cast<typename Graph::edge_property_type *>(e.get_property());
|
||||
}
|
||||
inline reference operator()(const key_type &e) const noexcept {
|
||||
return operator[](e);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
};
|
||||
|
||||
template <class Category, class Graph, class Value, class Reference, class MemberPointer>
|
||||
struct EdgeBundleMemberPropertyMap
|
||||
: public boost::put_get_helper<
|
||||
Reference, EdgeBundleMemberPropertyMap<Category, Graph, Value, Reference, MemberPointer>> {
|
||||
using value_type = Value;
|
||||
using reference = Reference;
|
||||
using key_type = typename Graph::edge_descriptor;
|
||||
using category = Category;
|
||||
|
||||
EdgeBundleMemberPropertyMap(Graph &g, MemberPointer ptr) noexcept
|
||||
: graph(&g), memberPointer(ptr) {}
|
||||
|
||||
inline reference operator[](const key_type &e) const noexcept {
|
||||
auto &p = *static_cast<typename Graph::edge_property_type *>(e.get_property());
|
||||
return p.*memberPointer;
|
||||
}
|
||||
inline reference operator()(const key_type &e) const noexcept {
|
||||
return operator[](e);
|
||||
}
|
||||
|
||||
Graph *graph{};
|
||||
MemberPointer memberPointer{};
|
||||
};
|
||||
|
||||
template <class Sequence, class Predicate>
|
||||
void sequenceEraseIf(Sequence &c, Predicate &&p) noexcept {
|
||||
if (!c.empty()) {
|
||||
c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
|
||||
}
|
||||
}
|
||||
|
||||
// notice: Predicate might be different from associative key
|
||||
// when Predicate is associative key, it is slower than erase [lower_bound, upper_bound)
|
||||
template <class AssociativeContainer, class Predicate>
|
||||
void associativeEraseIf(AssociativeContainer &c, Predicate &&p) noexcept {
|
||||
auto next = c.begin();
|
||||
for (auto i = next; next != c.end(); i = next) {
|
||||
++next;
|
||||
if (p(*i)) {
|
||||
c.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notice: Predicate might be different from associative key
|
||||
// when Predicate is associative key, it is slower than erase [lower_bound, upper_bound)
|
||||
template <class AssociativeContainer, class Predicate>
|
||||
void unstableAssociativeEraseIf(AssociativeContainer &c, Predicate &&p) noexcept {
|
||||
auto n = c.size();
|
||||
while (n--) {
|
||||
for (auto i = c.begin(); i != c.end(); ++i) {
|
||||
if (p(*i)) {
|
||||
c.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class EdgeDescriptor, class IncidenceList>
|
||||
inline void removeIncidenceEdge(EdgeDescriptor e, IncidenceList &el) noexcept {
|
||||
e.expectsNoProperty();
|
||||
for (auto i = el.begin(); i != el.end(); ++i) {
|
||||
if ((*i).get_target() == e.target) {
|
||||
el.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor, class IncidenceList, class EdgeProperty>
|
||||
inline void removeIncidenceEdge(
|
||||
EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> e, IncidenceList &el) noexcept {
|
||||
for (auto i = el.begin(); i != el.end(); ++i) {
|
||||
if (static_cast<void *>(&(*i).get_property()) == e.get_property()) {
|
||||
el.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class IncidenceList, class VertexDescriptor>
|
||||
inline void removeDirectedAllEdgeProperties(Graph &g, IncidenceList &el, VertexDescriptor v) noexcept {
|
||||
auto i = el.begin();
|
||||
auto end = el.end();
|
||||
for (; i != end; ++i) {
|
||||
if ((*i).get_target() == v) {
|
||||
// NOTE: Wihtout this skip, this loop will double-delete
|
||||
// properties of loop edges. This solution is based on the
|
||||
// observation that the incidence edges of a vertex with a loop
|
||||
// are adjacent in the out edge list. This *may* actually hold
|
||||
// for multisets also.
|
||||
bool skip = (std::next(i) != end && i->get_iter() == std::next(i)->get_iter());
|
||||
g.edges.erase((*i).get_iter());
|
||||
if (skip) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class IncidenceIterator, class IncidenceList, class Predicate>
|
||||
inline void sequenceRemoveIncidenceEdgeIf(IncidenceIterator first, IncidenceIterator last,
|
||||
IncidenceList &el, Predicate &&pred) noexcept {
|
||||
// remove_if
|
||||
while (first != last && !pred(*first)) {
|
||||
++first;
|
||||
}
|
||||
auto i = first;
|
||||
if (first != last) {
|
||||
for (++i; i != last; ++i) {
|
||||
if (!pred(*i)) {
|
||||
*first.base() = std::move(*i.base());
|
||||
++first;
|
||||
}
|
||||
}
|
||||
}
|
||||
el.erase(first.base(), el.end());
|
||||
}
|
||||
|
||||
template <class IncidenceIterator, class IncidenceList, class Predicate>
|
||||
inline void associativeRemoveIncidenceEdgeIf(IncidenceIterator first, IncidenceIterator last,
|
||||
IncidenceList &el, Predicate &&pred) noexcept {
|
||||
for (auto next = first; first != last; first = next) {
|
||||
++next;
|
||||
if (pred(*first)) {
|
||||
el.erase(first.base());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class EdgeDescriptor, class EdgeProperty>
|
||||
inline void removeUndirectedEdge(Graph &g, EdgeDescriptor e, EdgeProperty &p) noexcept {
|
||||
auto &outEdgeList = g.getOutEdgeList(source(e, g));
|
||||
auto outEdgeIter = outEdgeList.begin();
|
||||
decltype((*outEdgeIter).get_iter()) edgeIterToErase;
|
||||
for (; outEdgeIter != outEdgeList.end(); ++outEdgeIter) {
|
||||
if (&(*outEdgeIter).get_property() == &p) {
|
||||
edgeIterToErase = (*outEdgeIter).get_iter();
|
||||
outEdgeList.erase(outEdgeIter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto &inEdgeList = g.getOutEdgeList(target(e, g));
|
||||
auto inEdgeIter = inEdgeList.begin();
|
||||
for (; inEdgeIter != inEdgeList.end(); ++inEdgeIter) {
|
||||
if (&(*inEdgeIter).get_property() == &p) {
|
||||
inEdgeList.erase(inEdgeIter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g.edges.erase(edgeIterToErase);
|
||||
}
|
||||
|
||||
template <class Graph, class IncidenceIterator, class IncidenceList, class Predicate>
|
||||
inline void sequenceRemoveUndirectedOutEdgeIf(Graph &g,
|
||||
IncidenceIterator first, IncidenceIterator last, IncidenceList &el,
|
||||
Predicate &&pred) noexcept {
|
||||
// remove_if
|
||||
while (first != last && !pred(*first)) {
|
||||
++first;
|
||||
}
|
||||
auto i = first;
|
||||
bool selfLoopRemoved = false;
|
||||
if (first != last) {
|
||||
for (; i != last; ++i) {
|
||||
if (selfLoopRemoved) {
|
||||
/* With self loops, the descriptor will show up
|
||||
* twice. The first time it will be removed, and now it
|
||||
* will be skipped.
|
||||
*/
|
||||
selfLoopRemoved = false;
|
||||
} else if (!pred(*i)) {
|
||||
*first.base() = std::move(*i.base());
|
||||
++first;
|
||||
} else {
|
||||
if (source(*i, g) == target(*i, g)) {
|
||||
selfLoopRemoved = true;
|
||||
} else {
|
||||
// Remove the edge from the target
|
||||
removeIncidenceEdge(*i, g.getOutEdgeList(target(*i, g)));
|
||||
}
|
||||
|
||||
// Erase the edge property
|
||||
g.edges.erase((*i.base()).get_iter());
|
||||
}
|
||||
}
|
||||
}
|
||||
el.erase(first.base(), el.end());
|
||||
}
|
||||
|
||||
template <class Graph, class IncidenceIterator, class IncidenceList, class Predicate>
|
||||
inline void associativeRemoveUndirectedOutEdgeIf(Graph &g,
|
||||
IncidenceIterator first, IncidenceIterator last, IncidenceList &el,
|
||||
Predicate &&pred) noexcept {
|
||||
for (auto next = first; first != last; first = next) {
|
||||
++next;
|
||||
if (pred(*first)) {
|
||||
if (source(*first, g) != target(*first, g)) {
|
||||
// Remove the edge from the target
|
||||
removeIncidenceEdge(*first, g.getOutEdgeList(target(*first, g)));
|
||||
}
|
||||
|
||||
// Erase the edge property
|
||||
g.edges.erase((*first.base()).get_iter());
|
||||
|
||||
// Erase the edge in the source
|
||||
el.erase(first.base());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// list/vector out_edge_list
|
||||
template <class IncidenceList, class VertexDescriptor>
|
||||
inline void reindexEdgeList(IncidenceList &el, VertexDescriptor u) {
|
||||
auto ei = el.begin();
|
||||
auto eEnd = el.end();
|
||||
for (; ei != eEnd; ++ei) {
|
||||
if ((*ei).get_target() > u) {
|
||||
--(*ei).get_target();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag, class Container, class HandleDescriptor>
|
||||
inline void reindexVectorHandle(Container &container, HandleDescriptor u) {
|
||||
static_assert(std::is_arithmetic<HandleDescriptor>::value, "reindexVectorHandle");
|
||||
|
||||
using handle_type = ValueHandle<Tag, HandleDescriptor>;
|
||||
for (auto &vert : container) {
|
||||
if (ccstd::holds_alternative<handle_type>(vert.handle)) {
|
||||
auto &v = ccstd::get<handle_type>(vert.handle).value;
|
||||
if (v > u) {
|
||||
--v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class VertexDescriptor>
|
||||
inline void removeVectorVertex(Graph &g, VertexDescriptor u, boost::directed_tag /*tag*/) {
|
||||
g._vertices.erase(g._vertices.begin() + u);
|
||||
auto numV = num_vertices(g);
|
||||
if (u != numV) {
|
||||
for (VertexDescriptor v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getOutEdgeList(v), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class VertexDescriptor>
|
||||
inline void removeVectorVertex(Graph &g, VertexDescriptor u, boost::undirected_tag /*tag*/) {
|
||||
g._vertices.erase(g._vertices.begin() + u);
|
||||
VertexDescriptor numV = num_vertices(g);
|
||||
for (VertexDescriptor v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getOutEdgeList(v), u);
|
||||
}
|
||||
|
||||
auto ei = g.edges.begin();
|
||||
auto eiEnd = g.edges.end();
|
||||
for (; ei != eiEnd; ++ei) {
|
||||
if (ei->source > u) {
|
||||
--ei->source;
|
||||
}
|
||||
if (ei->target > u) {
|
||||
--ei->target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class VertexDescriptor>
|
||||
inline void removeVectorVertex(Graph &g, VertexDescriptor u, boost::bidirectional_tag /*tag*/) {
|
||||
g._vertices.erase(g._vertices.begin() + u);
|
||||
VertexDescriptor numV = num_vertices(g);
|
||||
VertexDescriptor v;
|
||||
if (u != numV) {
|
||||
for (v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getOutEdgeList(v), u);
|
||||
}
|
||||
|
||||
for (v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getInEdgeList(v), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class VertexDescriptor, class EdgeList>
|
||||
inline void removeVectorVertex(Graph &g, EdgeList & /*edges*/,
|
||||
VertexDescriptor u, boost::bidirectional_tag /*tag*/) {
|
||||
g._vertices.erase(g._vertices.begin() + u);
|
||||
VertexDescriptor numV = num_vertices(g);
|
||||
VertexDescriptor v;
|
||||
if (u != numV) {
|
||||
for (v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getOutEdgeList(v), u);
|
||||
}
|
||||
|
||||
for (v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getInEdgeList(v), u);
|
||||
}
|
||||
|
||||
auto ei = g.edges.begin();
|
||||
auto eiEnd = g.edges.end();
|
||||
for (; ei != eiEnd; ++ei) {
|
||||
if (ei->source > u) {
|
||||
--ei->source;
|
||||
}
|
||||
if (ei->target > u) {
|
||||
--ei->target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
inline void removeVectorOwner(Graph &g, typename Graph::vertex_descriptor u) {
|
||||
// might make children detached
|
||||
g.mObjects.erase(g.mObjects.begin() + u);
|
||||
auto numV = num_vertices(g);
|
||||
if (u != numV) {
|
||||
for (typename Graph::vertex_descriptor v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getChildrenList(v), u);
|
||||
}
|
||||
|
||||
for (typename Graph::vertex_descriptor v = 0; v < numV; ++v) {
|
||||
reindexEdgeList(g.getParentsList(v), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddressableGraph
|
||||
template <class AddressableGraph>
|
||||
inline std::ptrdiff_t pathLength(typename AddressableGraph::vertex_descriptor u, const AddressableGraph &g,
|
||||
typename AddressableGraph::vertex_descriptor parentID = AddressableGraph::null_vertex()) noexcept {
|
||||
if (u == parentID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto &pmap = get(boost::vertex_name, g);
|
||||
|
||||
std::ptrdiff_t sz = 0;
|
||||
while (u != parentID) {
|
||||
sz += static_cast<std::ptrdiff_t>(get(pmap, u).size()) + 1;
|
||||
u = parent(u, g);
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
template <class AddressableGraph, class CharT, class Allocator>
|
||||
inline void pathComposite(
|
||||
std::basic_string<CharT, std::char_traits<CharT>, Allocator> &str,
|
||||
std::ptrdiff_t &sz,
|
||||
typename AddressableGraph::vertex_descriptor u, const AddressableGraph &g,
|
||||
typename AddressableGraph::vertex_descriptor parentID = AddressableGraph::null_vertex()) noexcept {
|
||||
const auto &pmap = get(boost::vertex_name, g);
|
||||
|
||||
while (u != parentID) {
|
||||
CC_EXPECTS(sz <= static_cast<std::ptrdiff_t>(str.size()));
|
||||
|
||||
const auto &name = get(pmap, u);
|
||||
sz -= static_cast<std::ptrdiff_t>(name.size()) + 1;
|
||||
CC_ENSURES(sz >= 0);
|
||||
str[sz] = '/';
|
||||
std::copy(name.begin(), name.end(), str.begin() + sz + 1);
|
||||
|
||||
u = parent(u, g);
|
||||
}
|
||||
CC_ENSURES(sz == 0);
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
struct ColorMap : public boost::put_get_helper<boost::default_color_type &, ColorMap<Key>> {
|
||||
using value_type = boost::default_color_type;
|
||||
using reference = boost::default_color_type &;
|
||||
using key_type = Key;
|
||||
using category = boost::lvalue_property_map_tag;
|
||||
|
||||
ColorMap(ccstd::pmr::vector<boost::default_color_type> &vec) noexcept // NOLINT(google-explicit-constructor)
|
||||
: container{&vec} {}
|
||||
|
||||
inline reference operator[](const key_type &v) const noexcept {
|
||||
return (*container)[v];
|
||||
}
|
||||
inline reference operator()(const key_type &v) const noexcept {
|
||||
return operator[](v);
|
||||
}
|
||||
|
||||
ccstd::pmr::vector<boost::default_color_type> *container{};
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace std {
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
struct hash<cc::render::impl::EdgeDescriptor<DirectedCategory, VertexDescriptor>> {
|
||||
size_t operator()(const cc::render::impl::EdgeDescriptor<DirectedCategory, VertexDescriptor> &e) const noexcept {
|
||||
return boost::hash_value(e.get_property());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
627
cocos/renderer/pipeline/custom/details/GraphTypes.h
Normal file
627
cocos/renderer/pipeline/custom/details/GraphTypes.h
Normal file
@@ -0,0 +1,627 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include "cocos/base/memory/Memory.h"
|
||||
#include "cocos/base/std/container/list.h"
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/variant.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Overload.h"
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct use_default;
|
||||
|
||||
struct directed_tag;
|
||||
struct undirected_tag;
|
||||
struct bidirectional_tag;
|
||||
|
||||
struct no_property;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace cc {
|
||||
|
||||
template <class T>
|
||||
using PmrList = ccstd::list<T, boost::container::pmr::polymorphic_allocator<T>>;
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class... Ts>
|
||||
struct VertexOverloaded : Overloaded<Ts...> {
|
||||
VertexOverloaded(Ts &&...ts) // NOLINT
|
||||
: Overloaded<Ts...>{std::forward<Ts>(ts)...} {}
|
||||
template <class T>
|
||||
auto operator()(T *ptr) {
|
||||
return this->Overloaded<Ts...>::operator()(*ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <class GraphT, class... Ts>
|
||||
auto visitObject(typename GraphT::vertex_descriptor v, GraphT &g, Ts &&...args) {
|
||||
return ccstd::visit(VertexOverloaded<Ts...>{std::forward<Ts>(args)...}, value(v, g));
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// EdgeDescriptor
|
||||
//--------------------------------------------------------------------
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
struct EdgeDescriptor {
|
||||
EdgeDescriptor() = default;
|
||||
EdgeDescriptor(VertexDescriptor s, VertexDescriptor t) noexcept // NOLINT
|
||||
: source(s), target(t) {}
|
||||
|
||||
void expectsNoProperty() const noexcept {
|
||||
// CC_EXPECTS(false);
|
||||
}
|
||||
VertexDescriptor source{static_cast<VertexDescriptor>(-1)};
|
||||
VertexDescriptor target{static_cast<VertexDescriptor>(-1)};
|
||||
};
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator==(
|
||||
const EdgeDescriptor<boost::directed_tag, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptor<boost::directed_tag, VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.source == rhs.source &&
|
||||
lhs.target == rhs.target;
|
||||
}
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator==(
|
||||
const EdgeDescriptor<boost::bidirectional_tag, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptor<boost::bidirectional_tag, VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.source == rhs.source &&
|
||||
lhs.target == rhs.target;
|
||||
}
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator!=(
|
||||
const EdgeDescriptor<boost::directed_tag, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptor<boost::directed_tag, VertexDescriptor> &rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator!=(
|
||||
const EdgeDescriptor<boost::bidirectional_tag, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptor<boost::bidirectional_tag, VertexDescriptor> &rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
struct EdgeDescriptorWithProperty : EdgeDescriptor<DirectedCategory, VertexDescriptor> {
|
||||
using property_type = void;
|
||||
|
||||
EdgeDescriptorWithProperty() = default;
|
||||
EdgeDescriptorWithProperty(VertexDescriptor s, VertexDescriptor t, const property_type *p) noexcept
|
||||
: EdgeDescriptor<DirectedCategory, VertexDescriptor>(s, t), edgeProperty(const_cast<property_type *>(p)) {}
|
||||
|
||||
property_type *get_property() const noexcept { // NOLINT
|
||||
return edgeProperty;
|
||||
}
|
||||
|
||||
property_type *edgeProperty{};
|
||||
};
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
inline bool operator==(
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.edgeProperty == rhs.edgeProperty;
|
||||
}
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
inline bool operator!=(
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class DirectedCategory, class VertexDescriptor>
|
||||
inline bool operator<(
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &lhs,
|
||||
const EdgeDescriptorWithProperty<DirectedCategory, VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.edgeProperty < rhs.edgeProperty;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// StoredEdge
|
||||
//--------------------------------------------------------------------
|
||||
template <class VertexDescriptor>
|
||||
class StoredEdge {
|
||||
public:
|
||||
StoredEdge(VertexDescriptor target) noexcept // NOLINT(google-explicit-constructor)
|
||||
: target(target) {}
|
||||
const VertexDescriptor &get_target() const noexcept { // NOLINT
|
||||
return target;
|
||||
}
|
||||
VertexDescriptor &get_target() noexcept { // NOLINT
|
||||
return target;
|
||||
}
|
||||
// auto operator<=>(const StoredEdge&) const noexcept = default;
|
||||
|
||||
VertexDescriptor target;
|
||||
};
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator==(
|
||||
const StoredEdge<VertexDescriptor> &lhs,
|
||||
const StoredEdge<VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.target == rhs.target;
|
||||
}
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator!=(
|
||||
const StoredEdge<VertexDescriptor> &lhs,
|
||||
const StoredEdge<VertexDescriptor> &rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <class VertexDescriptor>
|
||||
inline bool operator<(
|
||||
const StoredEdge<VertexDescriptor> &lhs,
|
||||
const StoredEdge<VertexDescriptor> &rhs) noexcept {
|
||||
return lhs.target < rhs.target;
|
||||
}
|
||||
|
||||
template <class VertexDescriptor, class EdgeProperty>
|
||||
class StoredEdgeWithProperty : public StoredEdge<VertexDescriptor> {
|
||||
public:
|
||||
StoredEdgeWithProperty(VertexDescriptor target, const EdgeProperty &p)
|
||||
: StoredEdge<VertexDescriptor>(target), property(ccnew EdgeProperty(p)) {}
|
||||
StoredEdgeWithProperty(VertexDescriptor target, std::unique_ptr<EdgeProperty> &&ptr)
|
||||
: StoredEdge<VertexDescriptor>(target), property(std::move(ptr)) {}
|
||||
StoredEdgeWithProperty(VertexDescriptor target) // NOLINT(google-explicit-constructor)
|
||||
: StoredEdge<VertexDescriptor>(target) {}
|
||||
|
||||
StoredEdgeWithProperty(StoredEdgeWithProperty &&) noexcept = default;
|
||||
StoredEdgeWithProperty &operator=(StoredEdgeWithProperty &&) noexcept = default;
|
||||
|
||||
EdgeProperty &get_property() noexcept { // NOLINT
|
||||
CC_EXPECTS(property);
|
||||
return *property;
|
||||
}
|
||||
const EdgeProperty &get_property() const noexcept { // NOLINT
|
||||
CC_EXPECTS(property);
|
||||
return *property;
|
||||
}
|
||||
std::unique_ptr<EdgeProperty> property;
|
||||
};
|
||||
|
||||
template <class VertexDescriptor, class EdgeListIter, class EdgeProperty = boost::no_property>
|
||||
class StoredEdgeWithEdgeIter : public StoredEdge<VertexDescriptor> {
|
||||
public:
|
||||
StoredEdgeWithEdgeIter(VertexDescriptor v, EdgeListIter iter) noexcept
|
||||
: StoredEdge<VertexDescriptor>(v), _edgeListIter(iter) {}
|
||||
StoredEdgeWithEdgeIter(VertexDescriptor v) noexcept // NOLINT(google-explicit-constructor)
|
||||
: StoredEdge<VertexDescriptor>(v) {}
|
||||
|
||||
EdgeListIter get_iter() const noexcept { // NOLINT
|
||||
return _edgeListIter;
|
||||
}
|
||||
EdgeProperty &get_property() noexcept { // NOLINT
|
||||
return _edgeListIter->get_property();
|
||||
}
|
||||
const EdgeProperty &get_property() const noexcept { // NOLINT
|
||||
return _edgeListIter->get_property();
|
||||
}
|
||||
|
||||
protected:
|
||||
EdgeListIter _edgeListIter{};
|
||||
};
|
||||
|
||||
template <class VertexDescriptor, class EdgeVec, class EdgeProperty = boost::no_property>
|
||||
class StoredEdgeWithRandomAccessEdgeIter : public StoredEdge<VertexDescriptor> {
|
||||
public:
|
||||
StoredEdgeWithRandomAccessEdgeIter(
|
||||
VertexDescriptor v, typename EdgeVec::iterator i, EdgeVec *edgeVec) noexcept
|
||||
: StoredEdge<VertexDescriptor>(v), _id(i - edgeVec->begin()), _vector(edgeVec) {}
|
||||
|
||||
typename EdgeVec::iterator get_iter() const noexcept { // NOLINT
|
||||
CC_EXPECTS(_vector);
|
||||
return _vector->begin() + _id;
|
||||
}
|
||||
EdgeProperty &get_property() noexcept { // NOLINT
|
||||
CC_EXPECTS(_vector);
|
||||
return (*_vector)[_id].get_property();
|
||||
}
|
||||
const EdgeProperty &get_property() const noexcept { // NOLINT
|
||||
CC_EXPECTS(_vector);
|
||||
return (*_vector)[_id].get_property();
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t _id{static_cast<size_t>(-1)};
|
||||
EdgeVec *_vector{};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// VertexIterator
|
||||
//--------------------------------------------------------------------
|
||||
template <class BaseIter, class VertexDescriptor, class Difference>
|
||||
struct VertexIter : boost::iterator_adaptor<
|
||||
VertexIter<BaseIter, VertexDescriptor, Difference>,
|
||||
BaseIter, VertexDescriptor, boost::use_default, VertexDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
VertexIter<BaseIter, VertexDescriptor, Difference>,
|
||||
BaseIter, VertexDescriptor, boost::use_default, VertexDescriptor, Difference>;
|
||||
|
||||
VertexIter() = default;
|
||||
VertexIter(const BaseIter &i) noexcept // NOLINT(google-explicit-constructor)
|
||||
: Base(i) {}
|
||||
|
||||
VertexDescriptor dereference() const noexcept {
|
||||
return VertexDescriptor{&(*this->base())};
|
||||
}
|
||||
};
|
||||
|
||||
template <class BaseIter, class VertexDescriptor, class Difference>
|
||||
struct VertexMapPtrIter : boost::iterator_adaptor<
|
||||
VertexMapPtrIter<BaseIter, VertexDescriptor, Difference>,
|
||||
BaseIter, VertexDescriptor, boost::use_default, VertexDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
VertexMapPtrIter<BaseIter, VertexDescriptor, Difference>,
|
||||
BaseIter, VertexDescriptor, boost::use_default, VertexDescriptor, Difference>;
|
||||
|
||||
VertexMapPtrIter() = default;
|
||||
VertexMapPtrIter(const BaseIter &i) noexcept // NOLINT(google-explicit-constructor)
|
||||
: Base(i) {}
|
||||
|
||||
VertexDescriptor dereference() const noexcept {
|
||||
return VertexDescriptor{this->base()->second.get()};
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// OutEdgeIterator
|
||||
//--------------------------------------------------------------------
|
||||
template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
|
||||
struct OutEdgeIter : boost::iterator_adaptor<
|
||||
OutEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
OutEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference>;
|
||||
|
||||
OutEdgeIter() = default;
|
||||
OutEdgeIter(const BaseIter &i, const VertexDescriptor &src) noexcept
|
||||
: Base(i), source(src) {}
|
||||
|
||||
EdgeDescriptor dereference() const noexcept {
|
||||
// this->base() return out edge list iterator
|
||||
return EdgeDescriptor{
|
||||
source, (*this->base()).get_target()};
|
||||
}
|
||||
VertexDescriptor source{};
|
||||
};
|
||||
|
||||
template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
|
||||
struct OutPropertyEdgeIter : boost::iterator_adaptor<
|
||||
OutPropertyEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
OutPropertyEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference>;
|
||||
|
||||
OutPropertyEdgeIter() = default;
|
||||
OutPropertyEdgeIter(const BaseIter &i, const VertexDescriptor &src) noexcept
|
||||
: Base(i), source(src) {}
|
||||
|
||||
EdgeDescriptor dereference() const noexcept {
|
||||
// this->base() return out edge list iterator
|
||||
return EdgeDescriptor{
|
||||
source, (*this->base()).get_target(), &(*this->base()).get_property()};
|
||||
}
|
||||
VertexDescriptor source{};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// InEdgeIterator
|
||||
//--------------------------------------------------------------------
|
||||
template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
|
||||
struct InEdgeIter : boost::iterator_adaptor<
|
||||
InEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
InEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference>;
|
||||
|
||||
InEdgeIter() = default;
|
||||
InEdgeIter(const BaseIter &i, const VertexDescriptor &src) noexcept
|
||||
: Base(i), source(src) {}
|
||||
|
||||
EdgeDescriptor dereference() const noexcept {
|
||||
return EdgeDescriptor{
|
||||
(*this->base()).get_target(), source};
|
||||
}
|
||||
VertexDescriptor source{};
|
||||
};
|
||||
|
||||
template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
|
||||
struct InPropertyEdgeIter : boost::iterator_adaptor<
|
||||
InPropertyEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
InPropertyEdgeIter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>,
|
||||
BaseIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference>;
|
||||
|
||||
InPropertyEdgeIter() = default;
|
||||
InPropertyEdgeIter(const BaseIter &i, const VertexDescriptor &src) noexcept
|
||||
: Base(i), source(src) {}
|
||||
|
||||
EdgeDescriptor dereference() const noexcept {
|
||||
return EdgeDescriptor{
|
||||
(*this->base()).get_target(), source, &this->base()->get_property()};
|
||||
}
|
||||
VertexDescriptor source{};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// EdgeIterator
|
||||
//--------------------------------------------------------------------
|
||||
// UndirectedEdgeIter (Bidirectional || Undirected)
|
||||
template <class EdgeIter, class EdgeDescriptor, class Difference>
|
||||
struct UndirectedEdgeIter : boost::iterator_adaptor<
|
||||
UndirectedEdgeIter<EdgeIter, EdgeDescriptor, Difference>,
|
||||
EdgeIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference> {
|
||||
using Base = boost::iterator_adaptor<
|
||||
UndirectedEdgeIter<EdgeIter, EdgeDescriptor, Difference>,
|
||||
EdgeIter, EdgeDescriptor, boost::use_default, EdgeDescriptor, Difference>;
|
||||
|
||||
UndirectedEdgeIter() = default;
|
||||
explicit UndirectedEdgeIter(EdgeIter i) noexcept : Base(i) {}
|
||||
|
||||
EdgeDescriptor dereference() const noexcept {
|
||||
return EdgeDescriptor{
|
||||
(*this->base()).source, (*this->base()).target, &this->base()->get_property()};
|
||||
}
|
||||
};
|
||||
|
||||
// DirectedEdgeIterator
|
||||
template <class VertexIterator, class OutEdgeIterator, class Graph>
|
||||
class DirectedEdgeIterator {
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = typename OutEdgeIterator::value_type;
|
||||
using reference = typename OutEdgeIterator::reference;
|
||||
using pointer = typename OutEdgeIterator::pointer;
|
||||
using difference_type = typename OutEdgeIterator::difference_type;
|
||||
using distance_type = difference_type;
|
||||
|
||||
DirectedEdgeIterator() = default;
|
||||
template <class G>
|
||||
DirectedEdgeIterator(VertexIterator b, VertexIterator c, VertexIterator e, const G &g) noexcept
|
||||
: _begin(b), _curr(c), _end(e), _g(&g) {
|
||||
if (_curr != _end) {
|
||||
while (_curr != _end && out_degree(*_curr, *_g) == 0) {
|
||||
++_curr;
|
||||
}
|
||||
if (_curr != _end) {
|
||||
_edges = out_edges(*_curr, *_g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DirectedEdgeIterator &operator++() noexcept {
|
||||
++_edges->first;
|
||||
if (_edges->first == _edges->second) {
|
||||
++_curr;
|
||||
while (_curr != _end && out_degree(*_curr, *_g) == 0) {
|
||||
++_curr;
|
||||
}
|
||||
if (_curr != _end) {
|
||||
_edges = out_edges(*_curr, *_g);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
DirectedEdgeIterator operator++(int) noexcept {
|
||||
DirectedEdgeIterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
value_type operator*() const noexcept {
|
||||
return *_edges->first;
|
||||
}
|
||||
bool operator==(const DirectedEdgeIterator &x) const noexcept {
|
||||
return _curr == x._curr && (_curr == _end || _edges->first == x._edges->first);
|
||||
}
|
||||
bool operator!=(const DirectedEdgeIterator &x) const noexcept {
|
||||
return _curr != x._curr || (_curr != _end && _edges->first != x._edges->first);
|
||||
}
|
||||
|
||||
protected:
|
||||
VertexIterator _begin{};
|
||||
VertexIterator _curr{};
|
||||
VertexIterator _end{};
|
||||
boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator>> _edges;
|
||||
const Graph *_g{};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// EdgeListGraph
|
||||
//--------------------------------------------------------------------
|
||||
template <class VertexDescriptor, class EdgeProperty = boost::no_property>
|
||||
struct ListEdge {
|
||||
ListEdge(VertexDescriptor s, VertexDescriptor t) // NOLINT
|
||||
: source(s), target(t) {}
|
||||
|
||||
ListEdge(VertexDescriptor s, VertexDescriptor t, EdgeProperty &&p) // NOLINT
|
||||
: source(s), target(t), property(std::move(p)) {}
|
||||
|
||||
ListEdge(VertexDescriptor s, VertexDescriptor t, const EdgeProperty &p) // NOLINT
|
||||
: source(s), target(t), property(p) {}
|
||||
|
||||
template <class... T>
|
||||
ListEdge(VertexDescriptor s, VertexDescriptor t, T &&...args) // NOLINT
|
||||
: source(s), target(t), property(std::forward<T>(args)...) {}
|
||||
|
||||
EdgeProperty &get_property() noexcept { return property; } // NOLINT
|
||||
const EdgeProperty &get_property() const noexcept { return property; } // NOLINT
|
||||
|
||||
VertexDescriptor source{};
|
||||
VertexDescriptor target{};
|
||||
EdgeProperty property;
|
||||
};
|
||||
|
||||
// template<class VertexDescriptor, PmrAllocatorUserClass_ EdgeProperty>
|
||||
template <class VertexDescriptor, class EdgeProperty>
|
||||
struct PmrListEdge {
|
||||
using allocator_type = boost::container::pmr::polymorphic_allocator<char>;
|
||||
allocator_type get_allocator() const noexcept { // NOLINT
|
||||
return allocator_type{property.get_allocator().resource()};
|
||||
}
|
||||
// cntrs
|
||||
PmrListEdge(VertexDescriptor s, VertexDescriptor t, const allocator_type &alloc) // NOLINT
|
||||
: source(s), target(t), property(alloc) {}
|
||||
|
||||
PmrListEdge(VertexDescriptor s, VertexDescriptor t, EdgeProperty &&p, const allocator_type &alloc) // NOLINT
|
||||
: source(s), target(t), property(std::move(p), alloc) {}
|
||||
|
||||
PmrListEdge(VertexDescriptor s, VertexDescriptor t, const EdgeProperty &p, const allocator_type &alloc) // NOLINT
|
||||
: source(s), target(t), property(p, alloc) {}
|
||||
|
||||
template <class... T>
|
||||
PmrListEdge(VertexDescriptor s, VertexDescriptor t, T &&...args) // NOLINT
|
||||
: source(s), target(t), property(std::forward<T>(args)...) {}
|
||||
|
||||
// move/copy cntrs
|
||||
PmrListEdge(PmrListEdge &&rhs, const allocator_type &alloc)
|
||||
: source(std::move(rhs.source)), target(std::move(rhs.target)), property(std::move(rhs.property), alloc) {}
|
||||
PmrListEdge(const PmrListEdge &rhs, const allocator_type &alloc)
|
||||
: source(rhs.source), target(rhs.target), property(rhs.property, alloc) {}
|
||||
|
||||
PmrListEdge(const PmrListEdge &) = delete;
|
||||
|
||||
EdgeProperty &get_property() noexcept { return property; } // NOLINT
|
||||
const EdgeProperty &get_property() const noexcept { return property; } // NOLINT
|
||||
|
||||
VertexDescriptor source{};
|
||||
VertexDescriptor target{};
|
||||
EdgeProperty property;
|
||||
};
|
||||
|
||||
// Polymorphic Graph
|
||||
template <class Tag, class Handle>
|
||||
struct ValueHandle : Tag {
|
||||
ValueHandle() noexcept = default;
|
||||
ValueHandle(ValueHandle &&rhs) noexcept
|
||||
: value(std::move(rhs.value)) {}
|
||||
ValueHandle(const ValueHandle &rhs) noexcept
|
||||
: value(rhs.value) {}
|
||||
ValueHandle &operator=(ValueHandle &&rhs) noexcept {
|
||||
value = std::move(rhs.value);
|
||||
return *this;
|
||||
}
|
||||
ValueHandle &operator=(const ValueHandle &rhs) noexcept {
|
||||
value = rhs.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ValueHandle(const Handle &handle) noexcept // NOLINT(google-explicit-constructor)
|
||||
: value(handle) {}
|
||||
ValueHandle(Handle &&handle) noexcept // NOLINT(google-explicit-constructor)
|
||||
: value(std::move(handle)) {}
|
||||
template <class... Args>
|
||||
ValueHandle(Args &&...args) noexcept // NOLINT(google-explicit-constructor)
|
||||
: value(std::forward<Args>(args)...) {}
|
||||
|
||||
Handle value{};
|
||||
};
|
||||
|
||||
// Reference Graph
|
||||
// OwnershipIterator (Bidirectional, !EdgeProperty)
|
||||
template <class VertexIterator, class OutEdgeIterator, class Graph>
|
||||
class OwnershipIterator {
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = typename OutEdgeIterator::value_type;
|
||||
using reference = typename OutEdgeIterator::reference;
|
||||
using pointer = typename OutEdgeIterator::pointer;
|
||||
using difference_type = typename OutEdgeIterator::difference_type;
|
||||
using distance_type = difference_type;
|
||||
|
||||
OwnershipIterator() = default;
|
||||
template <class G>
|
||||
OwnershipIterator(VertexIterator b, VertexIterator c, VertexIterator e, const G &g) noexcept
|
||||
: _begin(b), _curr(c), _end(e), _g(&g) {
|
||||
if (_curr != _end) {
|
||||
while (_curr != _end && numChildren(*_curr, *_g) == 0) {
|
||||
++_curr;
|
||||
}
|
||||
if (_curr != _end) {
|
||||
_edges = children(*_curr, *_g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwnershipIterator &operator++() noexcept {
|
||||
++_edges->first;
|
||||
if (_edges->first == _edges->second) {
|
||||
++_curr;
|
||||
while (_curr != _end && numChildren(*_curr, *_g) == 0) {
|
||||
++_curr;
|
||||
}
|
||||
if (_curr != _end) {
|
||||
_edges = children(*_curr, *_g);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
OwnershipIterator operator++(int) noexcept {
|
||||
OwnershipIterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
value_type operator*() const noexcept {
|
||||
return *_edges->first;
|
||||
}
|
||||
bool operator==(const OwnershipIterator &x) const noexcept {
|
||||
return _curr == x._curr && (_curr == _end || _edges->first == x._edges->first);
|
||||
}
|
||||
bool operator!=(const OwnershipIterator &x) const noexcept {
|
||||
return _curr != x._curr || (_curr != _end && _edges->first != x._edges->first);
|
||||
}
|
||||
|
||||
protected:
|
||||
VertexIterator _begin{};
|
||||
VertexIterator _curr{};
|
||||
VertexIterator _end{};
|
||||
boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator>> _edges;
|
||||
const Graph *_g{};
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
235
cocos/renderer/pipeline/custom/details/GraphView.h
Normal file
235
cocos/renderer/pipeline/custom/details/GraphView.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/graph/adjacency_iterator.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class GraphT>
|
||||
struct AddressableView {
|
||||
explicit AddressableView(const GraphT& g) noexcept
|
||||
: mGraph(g) {}
|
||||
|
||||
// GraphT
|
||||
using directed_category = boost::bidirectional_tag;
|
||||
using vertex_descriptor = typename GraphT::vertex_descriptor;
|
||||
using edge_descriptor = typename GraphT::ownership_descriptor;
|
||||
using edge_parallel_category = boost::allow_parallel_edge_tag;
|
||||
struct traversal_category // NOLINT(readability-identifier-naming)
|
||||
: virtual boost::incidence_graph_tag,
|
||||
virtual boost::bidirectional_graph_tag,
|
||||
virtual boost::adjacency_graph_tag,
|
||||
virtual boost::vertex_list_graph_tag,
|
||||
virtual boost::edge_list_graph_tag {};
|
||||
|
||||
static vertex_descriptor null_vertex() noexcept { // NOLINT(readability-identifier-naming)
|
||||
return GraphT::null_vertex();
|
||||
}
|
||||
|
||||
// IncidenceGraph
|
||||
using out_edge_iterator = typename GraphT::children_iterator;
|
||||
using degree_size_type = typename GraphT::children_size_type;
|
||||
|
||||
// BidirectionalGraph
|
||||
using in_edge_iterator = typename GraphT::parent_iterator;
|
||||
|
||||
// AdjacencyGraph
|
||||
using adjacency_iterator = typename boost::adjacency_iterator_generator<
|
||||
AddressableView, vertex_descriptor, out_edge_iterator>::type;
|
||||
|
||||
// VertexListGraph
|
||||
using vertex_iterator = typename GraphT::vertex_iterator;
|
||||
using vertices_size_type = typename GraphT::vertices_size_type;
|
||||
|
||||
// EdgeListGraph
|
||||
using edge_iterator = typename GraphT::ownership_iterator;
|
||||
using edges_size_type = typename GraphT::ownerships_size_type;
|
||||
|
||||
// Member
|
||||
const GraphT& mGraph;
|
||||
};
|
||||
|
||||
// IncidenceGraph
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::vertex_descriptor
|
||||
source(const typename AddressableView<GraphT>::edge_descriptor& e, const AddressableView<GraphT>& g) noexcept {
|
||||
return parent(e, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::vertex_descriptor
|
||||
target(const typename AddressableView<GraphT>::edge_descriptor& e, const AddressableView<GraphT>& g) noexcept {
|
||||
return child(e, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline std::pair<
|
||||
typename AddressableView<GraphT>::out_edge_iterator,
|
||||
typename AddressableView<GraphT>::out_edge_iterator>
|
||||
out_edges( // NOLINT(readability-identifier-naming)
|
||||
typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
const AddressableView<GraphT>& g) {
|
||||
return children(u, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::degree_size_type
|
||||
out_degree( // NOLINT(readability-identifier-naming)
|
||||
typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
const AddressableView<GraphT>& g) noexcept {
|
||||
return numChildren(u, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline std::pair<typename AddressableView<GraphT>::edge_descriptor, bool>
|
||||
edge(typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
typename AddressableView<GraphT>::vertex_descriptor v,
|
||||
const AddressableView<GraphT>& g) noexcept {
|
||||
return ownership(u, v, g.mGraph);
|
||||
}
|
||||
|
||||
// BidirectionalGraph
|
||||
template <class GraphT>
|
||||
inline std::pair<typename AddressableView<GraphT>::in_edge_iterator, typename AddressableView<GraphT>::in_edge_iterator>
|
||||
in_edges( // NOLINT(readability-identifier-naming)
|
||||
typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
const AddressableView<GraphT>& g) noexcept {
|
||||
return parents(u, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::degree_size_type
|
||||
in_degree( // NOLINT(readability-identifier-naming)
|
||||
typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
const AddressableView<GraphT>& g) noexcept {
|
||||
return numParents(u, g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::degree_size_type
|
||||
degree(typename AddressableView<GraphT>::vertex_descriptor u, const AddressableView<GraphT>& g) noexcept {
|
||||
return out_degree(u, g) + in_degree(u, g);
|
||||
}
|
||||
|
||||
// AdjacencyGraph
|
||||
template <class GraphT>
|
||||
inline std::pair<
|
||||
typename AddressableView<GraphT>::adjacency_iterator,
|
||||
typename AddressableView<GraphT>::adjacency_iterator>
|
||||
adjacent_vertices( // NOLINT(readability-identifier-naming)
|
||||
typename AddressableView<GraphT>::vertex_descriptor u,
|
||||
const AddressableView<GraphT>& g) noexcept {
|
||||
auto r = out_edges(u, g);
|
||||
return std::make_pair(
|
||||
typename AddressableView<GraphT>::adjacency_iterator(r.first, &g),
|
||||
typename AddressableView<GraphT>::adjacency_iterator(r.second, &g));
|
||||
}
|
||||
|
||||
// VertexListGraph
|
||||
template <class GraphT>
|
||||
inline std::pair<
|
||||
typename AddressableView<GraphT>::vertex_iterator,
|
||||
typename AddressableView<GraphT>::vertex_iterator>
|
||||
vertices(const AddressableView<GraphT>& g) noexcept {
|
||||
return vertices(g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::vertices_size_type
|
||||
num_vertices(const AddressableView<GraphT>& g) noexcept { // NOLINT(readability-identifier-naming)
|
||||
return num_vertices(g.mGraph);
|
||||
}
|
||||
|
||||
// EdgeListGraph
|
||||
template <class GraphT>
|
||||
inline std::pair<
|
||||
typename AddressableView<GraphT>::edge_iterator,
|
||||
typename AddressableView<GraphT>::edge_iterator>
|
||||
edges(const AddressableView<GraphT>& g) noexcept {
|
||||
return ownerships(g.mGraph);
|
||||
}
|
||||
|
||||
template <class GraphT>
|
||||
inline typename AddressableView<GraphT>::edges_size_type
|
||||
num_edges(const AddressableView<GraphT>& g) noexcept { // NOLINT(readability-identifier-naming)
|
||||
return num_ownerships(g.mGraph);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class GraphT, class TagT>
|
||||
struct property_map<cc::render::AddressableView<GraphT>, TagT> {
|
||||
using const_type = typename property_map<GraphT, TagT>::const_type;
|
||||
using type = typename property_map<GraphT, TagT>::type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class TagT, class GraphT>
|
||||
typename boost::property_map<AddressableView<GraphT>, TagT>::const_type
|
||||
get(TagT t, const AddressableView<GraphT>& g) {
|
||||
return get(t, g.mGraph);
|
||||
}
|
||||
|
||||
template <class TagT, class GraphT>
|
||||
typename boost::property_map<AddressableView<GraphT>, TagT>::type
|
||||
get(TagT t, AddressableView<GraphT>& g) {
|
||||
return get(t, g.mGraph);
|
||||
}
|
||||
|
||||
template <class TagT, class GraphT>
|
||||
[[nodiscard]] inline decltype(auto)
|
||||
get(TagT tag, const AddressableView<GraphT>& g, typename AddressableView<GraphT>::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
template <class TagT, class GraphT>
|
||||
[[nodiscard]] inline decltype(auto)
|
||||
get(TagT tag, AddressableView<GraphT>& g, typename AddressableView<GraphT>::vertex_descriptor v) noexcept {
|
||||
return get(get(tag, g), v);
|
||||
}
|
||||
|
||||
template <class TagT, class GraphT, class... Args>
|
||||
inline void put(TagT tag, AddressableView<GraphT>& g,
|
||||
typename AddressableView<GraphT>::vertex_descriptor v,
|
||||
Args&&... args) {
|
||||
put(get(tag, g), v, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
45
cocos/renderer/pipeline/custom/details/GslUtils.h
Normal file
45
cocos/renderer/pipeline/custom/details/GslUtils.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include "cocos/base/Macros.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace gsl {
|
||||
|
||||
// narrow_cast(): a searchable way to do narrowing casts of values
|
||||
template <class T, class U>
|
||||
constexpr T narrow_cast(U &&u) noexcept { // NOLINT
|
||||
return static_cast<T>(std::forward<U>(u));
|
||||
}
|
||||
|
||||
#define CC_EXPECTS(cond) CC_ASSERT(cond) // NOLINT
|
||||
|
||||
#define CC_ENSURES(cond) CC_ASSERT(cond) // NOLINT
|
||||
|
||||
} // namespace gsl
|
||||
|
||||
} // namespace cc
|
||||
130
cocos/renderer/pipeline/custom/details/JsbConversion.h
Normal file
130
cocos/renderer/pipeline/custom/details/JsbConversion.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "cocos/base/std/container/map.h"
|
||||
#include "cocos/base/std/container/string.h"
|
||||
#include "cocos/base/std/container/vector.h"
|
||||
#include "cocos/bindings/manual/jsb_conversions.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Map.h"
|
||||
|
||||
template <typename T, typename allocator>
|
||||
inline bool nativevalue_to_se( // NOLINT(readability-identifier-naming)
|
||||
const ccstd::vector<T, allocator> &from,
|
||||
se::Value &to, se::Object *ctx) {
|
||||
se::Object *array = se::Object::createArrayObject(from.size());
|
||||
se::Value tmp;
|
||||
for (size_t i = 0; i < from.size(); i++) {
|
||||
nativevalue_to_se(from[i], tmp, ctx);
|
||||
array->setArrayElement(static_cast<uint32_t>(i), tmp);
|
||||
}
|
||||
to.setObject(array);
|
||||
array->decRef();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Value, typename Less, typename Allocator>
|
||||
inline bool nativevalue_to_se( // NOLINT(readability-identifier-naming)
|
||||
const ccstd::map<ccstd::string, Value, Less, Allocator> &from,
|
||||
se::Value &to, se::Object *ctx) {
|
||||
se::Object *ret = se::Object::createPlainObject();
|
||||
se::Value value;
|
||||
bool ok = true;
|
||||
for (auto &it : from) {
|
||||
ok &= nativevalue_to_se(it.second, value, ctx);
|
||||
cc_tmp_set_property(ret, it.first, value);
|
||||
}
|
||||
to.setObject(ret);
|
||||
ret->decRef();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool nativevalue_to_se( // NOLINT(readability-identifier-naming)
|
||||
const ccstd::pmr::string &from, se::Value &to, se::Object * /*ctx*/) {
|
||||
to.setString(from.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename allocator>
|
||||
bool sevalue_to_native(const se::Value &from, ccstd::vector<T, allocator> *to, se::Object *ctx) { // NOLINT(readability-identifier-naming)
|
||||
if (from.isNullOrUndefined()) {
|
||||
to->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
CC_ASSERT(from.toObject());
|
||||
se::Object *array = from.toObject();
|
||||
|
||||
if (array->isArray()) {
|
||||
uint32_t len = 0;
|
||||
array->getArrayLength(&len);
|
||||
to->resize(len);
|
||||
se::Value tmp;
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
array->getArrayElement(i, &tmp);
|
||||
if (!sevalue_to_native(tmp, to->data() + i, ctx)) {
|
||||
SE_LOGE("vector %s convert error at %d\n", typeid(T).name(), i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array->isTypedArray()) {
|
||||
CC_ASSERT(std::is_arithmetic<T>::value);
|
||||
uint8_t *data = nullptr;
|
||||
size_t dataLen = 0;
|
||||
array->getTypedArrayData(&data, &dataLen);
|
||||
to->assign(reinterpret_cast<T *>(data), reinterpret_cast<T *>(data + dataLen));
|
||||
return true;
|
||||
}
|
||||
|
||||
SE_LOGE("[warn] failed to convert to ccstd::vector\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Value, typename Less, typename Allocator>
|
||||
bool sevalue_to_native(const se::Value &from, ccstd::map<ccstd::string, Value, Less, Allocator> *to, se::Object * /*ctx*/) { // NOLINT(readability-identifier-naming)
|
||||
se::Object *jsmap = from.toObject();
|
||||
ccstd::vector<ccstd::string> allKeys;
|
||||
jsmap->getAllKeys(&allKeys);
|
||||
bool ret = true;
|
||||
se::Value property;
|
||||
for (auto &it : allKeys) {
|
||||
if (jsmap->getProperty(it.c_str(), &property)) {
|
||||
auto &output = (*to)[it];
|
||||
ret &= sevalue_to_native(property, &output, jsmap);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sevalue_to_native(const se::Value &from, ccstd::pmr::string *to, se::Object * /*ctx*/) { // NOLINT(readability-identifier-naming)
|
||||
if (!from.isNullOrUndefined()) {
|
||||
const auto &str = from.toString();
|
||||
to->assign(str.begin(), str.end());
|
||||
} else {
|
||||
to->clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
164
cocos/renderer/pipeline/custom/details/Map.h
Normal file
164
cocos/renderer/pipeline/custom/details/Map.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/pmr/flat_map.hpp>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include "cocos/base/std/container/unordered_map.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Pmr.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/Utility.h"
|
||||
|
||||
// for std::less<> the transparent comparator
|
||||
// see https://stackoverflow.com/questions/20317413/what-are-transparent-comparators
|
||||
|
||||
namespace cc {
|
||||
|
||||
// map
|
||||
template <class Key, class Value>
|
||||
using PmrMap = std::map<
|
||||
Key, Value, std::less<Key>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrMultiMap = std::multimap<
|
||||
Key, Value, std::less<Key>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using TransparentMap = std::map<Key, Value, std::less<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using TransparentMultiMap = std::multimap<Key, Value, std::less<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrTransparentMap = std::map<
|
||||
Key, Value, std::less<>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrTransparentMultiMap = std::multimap<
|
||||
Key, Value, std::less<>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
// flat_map
|
||||
template <class Key, class Value>
|
||||
using FlatMap = boost::container::flat_map<Key, Value, std::less<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using FlatMultiMap = boost::container::flat_multimap<Key, Value, std::less<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrFlatMap = boost::container::pmr::flat_map<Key, Value, std::less<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrFlatMultiMap = boost::container::pmr::flat_multimap<Key, Value, std::less<>>;
|
||||
|
||||
// unordered_map
|
||||
template <class Key, class Value>
|
||||
using PmrUnorderedMap = ccstd::pmr::unordered_map<Key, Value>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrUnorderedMultiMap = ccstd::pmr::unordered_multimap<Key, Value>;
|
||||
|
||||
// transparent string unordered_map
|
||||
template <class Key, class Value>
|
||||
using UnorderedStringMap = std::unordered_map<
|
||||
Key, Value,
|
||||
TransparentStringHash<typename Key::value_type>, std::equal_to<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using UnorderedStringMultiMap = std::unordered_multimap<
|
||||
Key, Value,
|
||||
TransparentStringHash<typename Key::value_type>, std::equal_to<>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrUnorderedStringMap = std::unordered_map<
|
||||
Key, Value,
|
||||
TransparentStringHash<typename Key::value_type>, std::equal_to<>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
template <class Key, class Value>
|
||||
using PmrUnorderedStringMultiMap = std::unordered_multimap<
|
||||
Key, Value,
|
||||
TransparentStringHash<typename Key::value_type>, std::equal_to<>,
|
||||
boost::container::pmr::polymorphic_allocator<std::pair<const Key, Value>>>;
|
||||
|
||||
template <class Key, class Value, class Allocator, class KeyLike>
|
||||
inline typename std::map<Key, Value, std::less<>, Allocator>::mapped_type&
|
||||
at(std::map<Key, Value, std::less<>, Allocator>& m, const KeyLike& key) {
|
||||
auto iter = m.find(key);
|
||||
if (iter == m.end()) {
|
||||
throw std::out_of_range("at(std::map) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Allocator, class KeyLike>
|
||||
inline typename std::map<Key, Value, std::less<>, Allocator>::mapped_type const&
|
||||
at(const std::map<Key, Value, std::less<>, Allocator>& m, const KeyLike& key) {
|
||||
auto iter = m.find(key);
|
||||
if (iter == m.end()) {
|
||||
throw std::out_of_range("at(std::map) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Allocator, class KeyLike>
|
||||
inline typename boost::container::flat_map<Key, Value, std::less<>, Allocator>::mapped_type&
|
||||
at(boost::container::flat_map<Key, Value, std::less<>, Allocator>& m, const KeyLike& key) {
|
||||
auto iter = m.find(key);
|
||||
if (iter == m.end()) {
|
||||
throw std::out_of_range("at(boost::container::flat_map) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Allocator, class KeyLike>
|
||||
inline typename boost::container::flat_map<Key, Value, std::less<>, Allocator>::mapped_type const&
|
||||
at(const boost::container::flat_map<Key, Value, std::less<>, Allocator>& m, const KeyLike& key) {
|
||||
auto iter = m.find(key);
|
||||
if (iter == m.end()) {
|
||||
throw std::out_of_range("at(boost::container::flat_map) out of range");
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
|
||||
namespace ccstd {
|
||||
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
struct hash<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer>> {
|
||||
hash_t operator()(const boost::container::flat_map<Key, T, Compare, AllocatorOrContainer>& val) const noexcept {
|
||||
hash_t seed = 0;
|
||||
for (const auto& pair : val) {
|
||||
hash_combine(seed, pair);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ccstd
|
||||
73
cocos/renderer/pipeline/custom/details/Overload.h
Normal file
73
cocos/renderer/pipeline/custom/details/Overload.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "cocos/base/std/variant.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1920)
|
||||
// https://stackoverflow.com/questions/50510122/stdvariant-with-overloaded-lambdas-alternative-with-msvc
|
||||
template <class... Ts>
|
||||
struct Overloaded {}; // NOLINT
|
||||
|
||||
template <class T0>
|
||||
struct Overloaded<T0> : T0 {
|
||||
using T0::operator();
|
||||
Overloaded(T0 t0) // NOLINT
|
||||
: T0(std::move(t0)) {}
|
||||
};
|
||||
|
||||
template <class T0, class T1, class... Ts>
|
||||
struct Overloaded<T0, T1, Ts...> : T0, Overloaded<T1, Ts...> {
|
||||
using T0::operator();
|
||||
using Overloaded<T1, Ts...>::operator();
|
||||
Overloaded(T0 t0, T1 t1, Ts... ts)
|
||||
: T0(std::move(t0)), Overloaded<T1, Ts...>(std::move(t1), std::move(ts)...) {}
|
||||
};
|
||||
#else
|
||||
template <class... Ts>
|
||||
struct Overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template <class... Ts>
|
||||
Overloaded(Ts...) -> Overloaded<Ts...>;
|
||||
#endif
|
||||
|
||||
template <class... Ts>
|
||||
Overloaded<Ts...> overload(Ts&&... ts) {
|
||||
return {std::forward<Ts>(ts)...};
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto variantFromIndex(size_t index) -> V { // NOLINT
|
||||
return boost::mp11::mp_with_index<boost::mp11::mp_size<V>>(index,
|
||||
[](auto i) { return V(ccstd::in_place_index<i>); });
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
82
cocos/renderer/pipeline/custom/details/PathUtils.h
Normal file
82
cocos/renderer/pipeline/custom/details/PathUtils.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <string_view>
|
||||
#include "cocos/base/std/container/array.h"
|
||||
#include "cocos/renderer/pipeline/custom/details/GslUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <class CharT, class Allocator>
|
||||
inline void cleanPath(std::basic_string<CharT, std::char_traits<CharT>, Allocator> &str) noexcept {
|
||||
using string_t = std::basic_string<CharT, std::char_traits<CharT>, Allocator>;
|
||||
constexpr CharT slash[] = {'/', '\0'};
|
||||
constexpr CharT doubleSlash[] = {'/', '/', '\0'};
|
||||
|
||||
CC_EXPECTS(!str.empty());
|
||||
CC_EXPECTS(boost::algorithm::starts_with(str, std::string_view(slash)));
|
||||
CC_EXPECTS(str.find(doubleSlash) == string_t::npos);
|
||||
|
||||
{ // remove all /./
|
||||
constexpr CharT current[] = {'/', '.', '/', '\0'};
|
||||
|
||||
auto pos = str.rfind(current);
|
||||
while (pos != string_t::npos) {
|
||||
str.erase(pos, 2);
|
||||
pos = str.rfind(current);
|
||||
}
|
||||
// remove tailing /.
|
||||
constexpr CharT ending[] = {'/', '.', '\0'};
|
||||
if (boost::algorithm::ends_with(str, std::string_view(ending))) {
|
||||
str.resize(str.size() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// try remove /..
|
||||
constexpr ccstd::array<CharT, 4> previous = {CharT('/'), CharT('.'), CharT('.'), CharT('\0')};
|
||||
auto pos = str.find(previous.data());
|
||||
while (pos != string_t::npos) {
|
||||
if (pos == 0) {
|
||||
// root element has not parent path
|
||||
str = {}; // slash;
|
||||
return;
|
||||
}
|
||||
auto beg = str.rfind(slash, pos - 1);
|
||||
CC_EXPECTS(beg != string_t::npos);
|
||||
str.erase(beg, pos - beg + previous.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
79
cocos/renderer/pipeline/custom/details/Pmr.h
Normal file
79
cocos/renderer/pipeline/custom/details/Pmr.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container/pmr/global_resource.hpp>
|
||||
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
||||
#include <boost/container/pmr/unsynchronized_pool_resource.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
template <class T>
|
||||
struct PmrDeallocator {
|
||||
void operator()(T* ptr) noexcept {
|
||||
mAllocator.deallocate(ptr, 1);
|
||||
}
|
||||
boost::container::pmr::polymorphic_allocator<T> mAllocator;
|
||||
};
|
||||
|
||||
template <class T, class... Args>
|
||||
[[nodiscard]] T*
|
||||
newPmr(boost::container::pmr::memory_resource* mr, Args&&... args) {
|
||||
boost::container::pmr::polymorphic_allocator<T> alloc(mr);
|
||||
|
||||
std::unique_ptr<T, PmrDeallocator<T>> ptr{
|
||||
alloc.allocate(1), PmrDeallocator<T>{alloc}};
|
||||
|
||||
// construct, might throw
|
||||
alloc.construct(ptr.get(), std::forward<Args>(args)...);
|
||||
|
||||
return ptr.release();
|
||||
}
|
||||
|
||||
struct PmrDeleter {
|
||||
template <class T>
|
||||
void operator()(T* ptr) const noexcept {
|
||||
if (ptr) {
|
||||
boost::container::pmr::polymorphic_allocator<T> alloc(ptr->get_allocator());
|
||||
ptr->~T();
|
||||
alloc.deallocate(ptr, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using PmrUniquePtr = std::unique_ptr<T, PmrDeleter>;
|
||||
|
||||
template <class T, class... Args>
|
||||
PmrUniquePtr<T>
|
||||
allocatePmrUniquePtr(const boost::container::pmr::polymorphic_allocator<std::byte>& alloc, Args&&... args) {
|
||||
return PmrUniquePtr<T>(newPmr<T>(alloc.resource(), std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
36
cocos/renderer/pipeline/custom/details/Range.h
Normal file
36
cocos/renderer/pipeline/custom/details/Range.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace cc {
|
||||
|
||||
template <class IteratorT>
|
||||
inline boost::iterator_range<IteratorT>
|
||||
makeRange(const std::pair<IteratorT, IteratorT> &p) noexcept { // NOLINT
|
||||
return boost::make_iterator_range(p.first, p.second);
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
493
cocos/renderer/pipeline/custom/details/SerializationUtils.h
Normal file
493
cocos/renderer/pipeline/custom/details/SerializationUtils.h
Normal file
@@ -0,0 +1,493 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "cocos/renderer/gfx-base/GFXDef-common.h"
|
||||
#include "cocos/renderer/pipeline/custom/ArchiveTypes.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
// bool
|
||||
inline void save(OutputArchive& ar, const bool& v) {
|
||||
ar.writeBool(v);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, bool& v) {
|
||||
v = ar.readBool();
|
||||
}
|
||||
|
||||
// enum, integral, floating_point
|
||||
template <class T,
|
||||
std::enable_if_t<
|
||||
std::is_enum_v<T> || std::is_integral_v<T> || std::is_floating_point_v<T>,
|
||||
bool> = false>
|
||||
void save(OutputArchive& ar, const T& v) {
|
||||
static_assert(!std::is_enum_v<T> || sizeof(T) <= sizeof(uint32_t)); // enum can only be 1, 2, 4 bytes
|
||||
ar.writeNumber(static_cast<double>(v));
|
||||
}
|
||||
|
||||
template <class T,
|
||||
std::enable_if_t<
|
||||
std::is_integral_v<T> || std::is_floating_point_v<T>,
|
||||
bool> = false>
|
||||
void load(InputArchive& ar, T& v) {
|
||||
v = static_cast<T>(ar.readNumber());
|
||||
}
|
||||
|
||||
// Cast from double to enum might not be supported. _MSC_VER(1924)
|
||||
template <class T,
|
||||
std::enable_if_t<
|
||||
std::is_enum_v<T>,
|
||||
bool> = false>
|
||||
void load(InputArchive& ar, T& v) {
|
||||
v = static_cast<T>(static_cast<typename std::underlying_type<T>::type>(ar.readNumber()));
|
||||
}
|
||||
|
||||
// string
|
||||
template <class T, class Traits, class Allocator>
|
||||
void save(OutputArchive& ar, const std::basic_string<T, Traits, Allocator>& v) {
|
||||
ar.writeString(v);
|
||||
}
|
||||
|
||||
template <class T, class Traits, class Allocator>
|
||||
void load(InputArchive& ar, std::basic_string<T, Traits, Allocator>& v) {
|
||||
v = ar.readString();
|
||||
}
|
||||
|
||||
// vector
|
||||
template <class T, class Allocator>
|
||||
void save(OutputArchive& ar, const std::vector<T, Allocator>& vec) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(vec.size()));
|
||||
for (const auto& v : vec) {
|
||||
save(ar, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
void load(InputArchive& ar, std::vector<T, Allocator>& vec) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
vec.resize(sz);
|
||||
for (auto& v : vec) {
|
||||
load(ar, v);
|
||||
}
|
||||
}
|
||||
|
||||
// set
|
||||
template <class Value, class Less, class Allocator>
|
||||
void save(OutputArchive& ar, const std::set<Value, Less, Allocator>& set) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(set.size()));
|
||||
for (const auto& value : set) {
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::set<Value, Less, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value;
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::set<Value, Less, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value(set.get_allocator());
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// flat_set
|
||||
template <class Value, class Less, class Allocator>
|
||||
void save(OutputArchive& ar, const boost::container::flat_set<Value, Less, Allocator>& set) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(set.size()));
|
||||
for (const auto& value : set) {
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_set<Value, Less, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
set.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value;
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_set<Value, Less, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
set.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value(set.get_allocator());
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// unordered_set
|
||||
template <class Value, class Hash, class Pred, class Allocator>
|
||||
void save(OutputArchive& ar, const std::unordered_set<Value, Hash, Pred, Allocator>& set) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(set.size()));
|
||||
for (const auto& value : set) {
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_set<Value, Hash, Pred, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value;
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_set<Value, Hash, Pred, Allocator>& set) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Value value(set.get_allocator());
|
||||
load(ar, value);
|
||||
set.emplace(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// map
|
||||
template <class Key, class Value, class Less, class Allocator>
|
||||
void save(OutputArchive& ar, const std::map<Key, Value, Less, Allocator>& map) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(map.size()));
|
||||
for (const auto& [key, value] : map) {
|
||||
save(ar, key);
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// flat_map
|
||||
template <class Key, class Value, class Less, class Allocator>
|
||||
void save(OutputArchive& ar, const boost::container::flat_map<Key, Value, Less, Allocator>& map) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(map.size()));
|
||||
for (const auto& [key, value] : map) {
|
||||
save(ar, key);
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
map.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
map.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
map.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Less, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, boost::container::flat_map<Key, Value, Less, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
map.reserve(sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// unordered_map
|
||||
template <class Key, class Value, class Hash, class Pred, class Allocator>
|
||||
void save(OutputArchive& ar, const std::unordered_map<Key, Value, Hash, Pred, Allocator>& map) {
|
||||
save<uint32_t>(ar, static_cast<uint32_t>(map.size()));
|
||||
for (const auto& [key, value] : map) {
|
||||
save(ar, key);
|
||||
save(ar, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_map<Key, Value, Hash, Pred, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<!std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_map<Key, Value, Hash, Pred, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value;
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<!std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_map<Key, Value, Hash, Pred, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key;
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Value, class Hash, class Pred, class Allocator,
|
||||
std::enable_if_t<std::uses_allocator_v<Key, Allocator>, bool> = false,
|
||||
std::enable_if_t<std::uses_allocator_v<Value, Allocator>, bool> = false>
|
||||
void load(InputArchive& ar, std::unordered_map<Key, Value, Hash, Pred, Allocator>& map) {
|
||||
uint32_t sz = 0;
|
||||
load(ar, sz);
|
||||
for (uint32_t i = 0; i != sz; ++i) {
|
||||
Key key(map.get_allocator());
|
||||
Value value(map.get_allocator());
|
||||
load(ar, key);
|
||||
load(ar, value);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
// gfx
|
||||
inline void save(OutputArchive& ar, const gfx::Color& v) {
|
||||
save(ar, v.x);
|
||||
save(ar, v.y);
|
||||
save(ar, v.z);
|
||||
save(ar, v.w);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, gfx::Color& v) {
|
||||
load(ar, v.x);
|
||||
load(ar, v.y);
|
||||
load(ar, v.z);
|
||||
load(ar, v.w);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const gfx::Uniform& v) {
|
||||
save(ar, v.name);
|
||||
save(ar, v.type);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, gfx::Uniform& v) {
|
||||
load(ar, v.name);
|
||||
load(ar, v.type);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const gfx::UniformBlock& v) {
|
||||
save(ar, v.set);
|
||||
save(ar, v.binding);
|
||||
save(ar, v.name);
|
||||
save(ar, v.members);
|
||||
save(ar, v.count);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, gfx::UniformBlock& v) {
|
||||
load(ar, v.set);
|
||||
load(ar, v.binding);
|
||||
load(ar, v.name);
|
||||
load(ar, v.members);
|
||||
load(ar, v.count);
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const gfx::DescriptorSetLayoutBinding& v) {
|
||||
save(ar, v.binding);
|
||||
save(ar, v.descriptorType);
|
||||
save(ar, v.count);
|
||||
save(ar, v.stageFlags);
|
||||
// skip immutableSamplers: SamplerList
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, gfx::DescriptorSetLayoutBinding& v) {
|
||||
load(ar, v.binding);
|
||||
load(ar, v.descriptorType);
|
||||
load(ar, v.count);
|
||||
load(ar, v.stageFlags);
|
||||
// skip immutableSamplers: SamplerList
|
||||
}
|
||||
|
||||
inline void save(OutputArchive& ar, const gfx::DescriptorSetLayoutInfo& v) {
|
||||
save(ar, v.bindings);
|
||||
}
|
||||
|
||||
inline void load(InputArchive& ar, gfx::DescriptorSetLayoutInfo& v) {
|
||||
load(ar, v.bindings);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace cc
|
||||
102
cocos/renderer/pipeline/custom/details/Set.h
Normal file
102
cocos/renderer/pipeline/custom/details/Set.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/container/pmr/flat_set.hpp>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include "cocos/base/std/hash/hash_fwd.hpp"
|
||||
#include "cocos/renderer/pipeline/custom/details/Utility.h"
|
||||
|
||||
// for std::less<> the transparent comparator
|
||||
// see https://stackoverflow.com/questions/20317413/what-are-transparent-comparators
|
||||
|
||||
namespace cc {
|
||||
|
||||
// set
|
||||
template <class Value>
|
||||
using TransparentSet = std::set<Value, std::less<>>;
|
||||
|
||||
template <class Value>
|
||||
using TransparentMultiSet = std::multiset<Value, std::less<>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrTransparentSet = std::set<
|
||||
Value, std::less<>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrTransparentMultiSet = std::multiset<
|
||||
Value, std::less<>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
// flat_set
|
||||
template <class Value>
|
||||
using FlatSet = boost::container::flat_set<Value, std::less<>>;
|
||||
|
||||
template <class Value>
|
||||
using FlatMultiSet = boost::container::flat_multiset<Value, std::less<>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrFlatSet = boost::container::pmr::flat_set<Value, std::less<>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrFlatMultiSet = boost::container::pmr::flat_multiset<Value, std::less<>>;
|
||||
|
||||
// unordered_set
|
||||
template <class Value>
|
||||
using PmrUnorderedSet = std::unordered_set<
|
||||
Value, ccstd::hash<Value>, std::equal_to<Value>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrUnorderedMultiSet = std::unordered_multiset<
|
||||
Value, ccstd::hash<Value>, std::equal_to<Value>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
// transparent string unordered_set
|
||||
template <class Value>
|
||||
using UnorderedStringSet = std::unordered_set<
|
||||
Value,
|
||||
TransparentStringHash<typename Value::value_type>, std::equal_to<>>;
|
||||
|
||||
template <class Value>
|
||||
using UnorderedStringMultiSet = std::unordered_multiset<
|
||||
Value,
|
||||
TransparentStringHash<typename Value::value_type>, std::equal_to<>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrUnorderedStringSet = std::unordered_set<
|
||||
Value,
|
||||
TransparentStringHash<typename Value::value_type>, std::equal_to<>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
template <class Value>
|
||||
using PmrUnorderedStringMultiSet = std::unordered_multiset<
|
||||
Value,
|
||||
TransparentStringHash<typename Value::value_type>, std::equal_to<>,
|
||||
boost::container::pmr::polymorphic_allocator<Value>>;
|
||||
|
||||
} // namespace cc
|
||||
61
cocos/renderer/pipeline/custom/details/Utility.h
Normal file
61
cocos/renderer/pipeline/custom/details/Utility.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <string_view>
|
||||
|
||||
// transparent hash
|
||||
// see https://stackoverflow.com/questions/20317413/what-are-transparent-comparators
|
||||
|
||||
namespace cc {
|
||||
|
||||
template <class Char>
|
||||
struct TransparentStringHash {
|
||||
using is_transparent = void;
|
||||
using string_view_type = std::basic_string_view<Char>;
|
||||
|
||||
size_t operator()(string_view_type str) const noexcept {
|
||||
return boost::hash<string_view_type>{}(str);
|
||||
}
|
||||
size_t operator()(const Char* str) const noexcept {
|
||||
return boost::hash<string_view_type>{}(str);
|
||||
}
|
||||
template <class Alloc>
|
||||
size_t operator()(const std::basic_string<Char, std::char_traits<Char>, Alloc>& str) const noexcept {
|
||||
return boost::hash<string_view_type>{}(str);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Char>
|
||||
struct TransparentStringEqual {
|
||||
using is_transparent = void;
|
||||
using string_view_type = std::basic_string_view<Char>;
|
||||
template <class T, class U>
|
||||
bool operator()(T&& lhs, U&& rhs) const noexcept {
|
||||
return string_view_type{lhs} == string_view_type{rhs};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
803
cocos/renderer/pipeline/custom/test/test.h
Normal file
803
cocos/renderer/pipeline/custom/test/test.h
Normal file
@@ -0,0 +1,803 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include "../../Enum.h"
|
||||
#include "../FGDispatcherTypes.h"
|
||||
#include "../LayoutGraphGraphs.h"
|
||||
#include "../NativePipelineTypes.h"
|
||||
#include "../RenderGraphGraphs.h"
|
||||
#include "../RenderGraphTypes.h"
|
||||
#include "../details/Range.h"
|
||||
#include "GFXDeviceManager.h"
|
||||
#include "cocos/base/std/container/vector.h"
|
||||
#include "frame-graph/FrameGraph.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
#include "gfx-base/GFXDevice.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace render {
|
||||
|
||||
using ccstd::pmr::string;
|
||||
using gfx::PassType;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using ViewInfo = vector<pair<PassType, vector<vector<vector<string>>>>>;
|
||||
using ResourceInfo = vector<std::tuple<string, ResourceDesc, ResourceTraits, ResourceStates>>;
|
||||
using LayoutUnit = std::tuple<string, uint32_t, gfx::ShaderStageFlagBit>;
|
||||
using LayoutInfo = vector<vector<LayoutUnit>>;
|
||||
using framegraph::PassBarrierPair;
|
||||
using framegraph::ResourceBarrier;
|
||||
using RasterViews = PmrTransparentMap<ccstd::pmr::string, RasterView>;
|
||||
using ComputeViews = PmrTransparentMap<ccstd::pmr::string, ccstd::pmr::vector<ComputeView>>;
|
||||
|
||||
static void fillTestGraph(const ViewInfo &rasterData, const ResourceInfo &rescInfo, const LayoutInfo &layoutInfo, RenderGraph &renderGraph, ResourceGraph &rescGraph, LayoutGraphData &layoutGraphData) {
|
||||
for (const auto &resc : rescInfo) {
|
||||
string name = std::get<0>(resc);
|
||||
auto rescVertexID = add_vertex(rescGraph, ManagedTag{}, name.c_str());
|
||||
rescGraph.descs[rescVertexID] = std::get<1>(resc);
|
||||
rescGraph.traits[rescVertexID] = std::get<2>(resc);
|
||||
rescGraph.states[rescVertexID].states = gfx::AccessFlagBit::NONE;
|
||||
}
|
||||
|
||||
const auto &mem_resource = layoutGraphData.get_allocator();
|
||||
auto &stages = layoutGraphData.stages;
|
||||
stages.resize(layoutInfo.size());
|
||||
|
||||
add_vertex(layoutGraphData, RenderPhaseTag{}, "default");
|
||||
auto &layout = layoutGraphData.layouts.back();
|
||||
const auto &descPair = layout.descriptorSets.emplace(UpdateFrequency::PER_PASS, DescriptorSetData{renderGraph.get_allocator()});
|
||||
auto &descData = (*descPair.first).second.descriptorSetLayoutData;
|
||||
for (size_t i = 0; i < layoutInfo.size(); ++i) {
|
||||
const ccstd::string passName = "pass" + std::to_string(i);
|
||||
auto layoutVtxID = add_vertex(layoutGraphData, RenderStageTag{}, passName.c_str());
|
||||
const auto &renderStageInfo = layoutInfo[i];
|
||||
for (const auto &layoutUnit : renderStageInfo) {
|
||||
const auto &rescName = std::get<0>(layoutUnit);
|
||||
const auto &nameID = std::get<1>(layoutUnit);
|
||||
const auto &shaderStage = std::get<2>(layoutUnit);
|
||||
if (layoutGraphData.attributeIndex.find(rescName) == layoutGraphData.attributeIndex.end()) {
|
||||
layoutGraphData.attributeIndex.emplace(std::make_pair<string, NameLocalID>(rescName.c_str(), NameLocalID{nameID}));
|
||||
}
|
||||
stages[i].descriptorVisibility.emplace(NameLocalID{nameID}, shaderStage);
|
||||
auto &block = descData.descriptorBlocks.emplace_back();
|
||||
block.visibility = shaderStage;
|
||||
auto &desc = block.descriptors.emplace_back();
|
||||
desc.count = 1;
|
||||
desc.descriptorID = {nameID};
|
||||
}
|
||||
}
|
||||
renderGraph.layoutNodes.emplace_back("");
|
||||
|
||||
std::set<ccstd::string> nameSet;
|
||||
auto addRasterNode = [&](const vector<vector<vector<string>>> &subpasses, uint32_t count, uint32_t passID) {
|
||||
const ccstd::string name = "pass" + std::to_string(passID);
|
||||
const auto vertexID = add_vertex(renderGraph, RasterPassTag{}, name.c_str());
|
||||
auto& layoutName = get(RenderGraph::LayoutTag{}, renderGraph, vertexID);
|
||||
layoutName = "default";
|
||||
|
||||
renderGraph.sortedVertices.emplace_back(vertexID);
|
||||
auto &raster = get(RasterPassTag{}, vertexID, renderGraph);
|
||||
auto &subpassGraph = raster.subpassGraph;
|
||||
|
||||
bool hasSubpass = count > 1;
|
||||
|
||||
Subpass *subpass = nullptr;
|
||||
auto &rasterViews = raster.rasterViews;
|
||||
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
assert(subpasses[j].size() == 2); // inputs and outputs
|
||||
const auto &attachments = subpasses[j];
|
||||
bool isOutput = false;
|
||||
|
||||
Subpass *subpass = nullptr;
|
||||
RasterSubpass *subpassNode1 = nullptr;
|
||||
PmrTransparentMap<ccstd::pmr::string, RasterView> *subpassViews = nullptr;
|
||||
if (hasSubpass) {
|
||||
const ccstd::string subpassName = "subpass" + std::to_string(passID);
|
||||
auto subpassVertexID = add_vertex(subpassGraph, subpassName.c_str());
|
||||
subpass = &get(SubpassGraph::SubpassTag{}, subpassGraph, subpassVertexID);
|
||||
|
||||
RasterSubpass subpassNode(j, 1, 0, renderGraph.get_allocator());
|
||||
auto subpassID = addVertex(
|
||||
RasterSubpassTag{},
|
||||
std::forward_as_tuple(subpassName.c_str()),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(),
|
||||
std::forward_as_tuple(std::move(subpassNode)),
|
||||
renderGraph, vertexID);
|
||||
|
||||
subpassNode1 = get_if<RasterSubpass>(subpassID, &renderGraph);
|
||||
subpassViews = &subpassNode1->rasterViews;
|
||||
}
|
||||
|
||||
uint32_t slot = 0;
|
||||
for (size_t k = 0; k < attachments.size(); ++k) {
|
||||
for (size_t l = 0; l < attachments[k].size(); ++l) {
|
||||
const auto &inputsOrOutputs = attachments[k];
|
||||
const auto &viewName = inputsOrOutputs[l];
|
||||
bool firstMeet = nameSet.find(viewName.c_str()) == nameSet.end();
|
||||
if (firstMeet) {
|
||||
nameSet.emplace(viewName);
|
||||
}
|
||||
|
||||
auto &views = hasSubpass ? (*subpass).rasterViews : raster.rasterViews;
|
||||
auto view = RasterView{
|
||||
viewName.c_str(),
|
||||
isOutput ? AccessType::WRITE : AccessType::READ,
|
||||
AttachmentType::RENDER_TARGET,
|
||||
firstMeet ? gfx::LoadOp::CLEAR : gfx::LoadOp::LOAD,
|
||||
gfx::StoreOp::STORE,
|
||||
gfx::ClearFlagBit::ALL,
|
||||
gfx::Color({1.0, 0.0, 0.0, 1.0}),
|
||||
gfx::ShaderStageFlagBit::NONE,
|
||||
};
|
||||
view.slotID = slot;
|
||||
views.emplace(viewName.c_str(), view);
|
||||
if (subpassViews) {
|
||||
subpassViews->emplace(viewName.c_str(), view);
|
||||
|
||||
const auto newID = static_cast<uint32_t>(raster.attachmentIndexMap.size());
|
||||
auto iter = raster.attachmentIndexMap.find(viewName);
|
||||
if (iter == raster.attachmentIndexMap.end()) {
|
||||
raster.attachmentIndexMap.emplace(viewName, newID);
|
||||
}
|
||||
rasterViews.emplace(viewName, view);
|
||||
}
|
||||
++slot;
|
||||
}
|
||||
isOutput = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t passCount = 0;
|
||||
for (size_t i = 0; i < rasterData.size(); ++i) {
|
||||
const auto &pass = rasterData[i];
|
||||
switch (pass.first) {
|
||||
case PassType::RASTER: {
|
||||
// const string name = pass.first;
|
||||
const auto &subpasses = pass.second;
|
||||
addRasterNode(subpasses, subpasses.size(), passCount++);
|
||||
break;
|
||||
}
|
||||
case PassType::COMPUTE: {
|
||||
// const string name = pass.first;
|
||||
const auto &subpasses = pass.second;
|
||||
|
||||
const ccstd::string name = "pass" + std::to_string(passCount++);
|
||||
const auto vertexID = add_vertex(renderGraph, ComputeTag{}, name.c_str());
|
||||
renderGraph.sortedVertices.emplace_back(vertexID);
|
||||
|
||||
assert(subpasses.back().size() == 2); // inputs and outputs
|
||||
auto &computePass = get(ComputeTag{}, vertexID, renderGraph);
|
||||
const auto &inputsAndOutputs = subpasses.back();
|
||||
const auto &inputs = inputsAndOutputs.front();
|
||||
const auto &outputs = inputsAndOutputs.back();
|
||||
|
||||
std::vector<ComputeView> views(2);
|
||||
ComputeView &src = views.front();
|
||||
src.name = inputs.front();
|
||||
src.accessType = AccessType::READ;
|
||||
ComputeView &dst = views.back();
|
||||
dst.name = outputs.front();
|
||||
dst.accessType = AccessType::WRITE;
|
||||
|
||||
computePass.computeViews.emplace(src.name, ccstd::pmr::vector<ComputeView>{});
|
||||
computePass.computeViews.emplace(dst.name, ccstd::pmr::vector<ComputeView>{});
|
||||
computePass.computeViews.at(src.name.c_str()).emplace_back();
|
||||
computePass.computeViews.at(dst.name.c_str()).emplace_back();
|
||||
computePass.computeViews.at(src.name.c_str()).front().name = inputs.front();
|
||||
computePass.computeViews.at(src.name.c_str()).front().accessType = AccessType::READ;
|
||||
computePass.computeViews.at(dst.name.c_str()).back().name = outputs.front();
|
||||
computePass.computeViews.at(dst.name.c_str()).back().accessType = AccessType::WRITE;
|
||||
|
||||
break;
|
||||
}
|
||||
case PassType::PRESENT: {
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
case PassType::COPY: {
|
||||
// const string name = pass.first;
|
||||
const auto &subpasses = pass.second;
|
||||
|
||||
const ccstd::string name = "pass" + std::to_string(passCount++);
|
||||
const auto vertexID = add_vertex(renderGraph, CopyTag{}, name.c_str());
|
||||
renderGraph.sortedVertices.emplace_back(vertexID);
|
||||
assert(subpasses.back().size() == 2); // inputs and outputs
|
||||
auto ©Pass = get(CopyTag{}, vertexID, renderGraph);
|
||||
const auto &inputsAndOutputs = subpasses.back();
|
||||
const auto &inputs = inputsAndOutputs.front();
|
||||
const auto &outputs = inputsAndOutputs.back();
|
||||
copyPass.copyPairs.emplace_back(CopyPair{
|
||||
inputs.front().c_str(),
|
||||
outputs.front().c_str(),
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FrameGraphDispatcher fgDispatcher(rescGraph, renderGraph, layoutGraphData, layoutGraphData.resource(), layoutGraphData.resource());
|
||||
fgDispatcher.enableMemoryAliasing(true);
|
||||
fgDispatcher.enablePassReorder(true);
|
||||
fgDispatcher.setParalellWeight(0.4);
|
||||
fgDispatcher.run(); */
|
||||
}
|
||||
|
||||
#define TEST_CASE_DEFINE \
|
||||
using namespace cc::render; \
|
||||
using cc::gfx::AccessFlagBit; \
|
||||
using cc::gfx::BarrierType; \
|
||||
using cc::gfx::Format; \
|
||||
using cc::gfx::MemoryAccessBit; \
|
||||
using cc::gfx::SampleCount; \
|
||||
using cc::gfx::ShaderStageFlagBit; \
|
||||
using cc::gfx::TextureFlagBit; \
|
||||
ResourceInfo resources = { \
|
||||
{"0", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"1", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"2", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"3", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"4", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"5", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"6", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"7", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"8", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"9", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"10", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"11", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"12", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"13", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"14", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"15", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"16", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"17", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"18", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::MANAGED}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"19", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::EXTERNAL}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"20", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::EXTERNAL}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"21", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::EXTERNAL}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
{"22", \
|
||||
{ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \
|
||||
ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \
|
||||
{ResourceResidency::BACKBUFFER}, \
|
||||
{AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \
|
||||
};
|
||||
|
||||
#define TEST_CASE_1 \
|
||||
TEST_CASE_DEFINE \
|
||||
\
|
||||
ViewInfo rasterData = { \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{}, {"0", "1", "2"}}, \
|
||||
{{"0", "1", "2"}, {"3"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"3"}, {"22"}}, \
|
||||
}, \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
LayoutInfo layoutInfo = { \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"22", 22, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}};
|
||||
|
||||
#define TEST_CASE_2 \
|
||||
TEST_CASE_DEFINE \
|
||||
\
|
||||
ViewInfo rasterData = { \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{}, {"0", "1"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"0"}, {"2", "3"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"4", "5"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"3", "5"}, {"6"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"2", "4", "6"}, {"7"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{}, {"8"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"0", "8"}, {"9"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"7", "9"}, {"22"}}, \
|
||||
}, \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
LayoutInfo layoutInfo = { \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::VERTEX}, \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"4", 4, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"6", 6, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"4", 4, cc::gfx::ShaderStageFlagBit::VERTEX}, \
|
||||
{"6", 6, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"7", 7, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"7", 7, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"22", 22, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
};
|
||||
|
||||
#define TEST_CASE_3 \
|
||||
TEST_CASE_DEFINE \
|
||||
\
|
||||
ViewInfo rasterData = { \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{}, {"0"}}, \
|
||||
{{"0"}, {"1"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"2"}}, \
|
||||
{{"2"}, {"3"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"3"}, {"4"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"4"}, {"5"}}, \
|
||||
{{"5"}, {"6"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::COPY, \
|
||||
{ \
|
||||
{{"3"}, {"7"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::COPY, \
|
||||
{ \
|
||||
{{"7"}, {"8"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"9"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"14"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::COPY, \
|
||||
{ \
|
||||
{{"14"}, {"15"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"15", "9"}, {"10"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"16"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::COPY, \
|
||||
{ \
|
||||
{{"16"}, {"17"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"8", "10", "17"}, {"11"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"11", "5", "6"}, {"12"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"12"}, {"22"}}, \
|
||||
}, \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
LayoutInfo layoutInfo = { \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::VERTEX}, \
|
||||
{"4", 4, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"4", 4, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"6", 6, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"7", 7, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"7", 7, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"14", 14, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"14", 14, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"15", 15, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"15", 15, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"10", 10, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"16", 16, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"16", 16, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"17", 17, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"10", 10, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"17", 17, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"11", 11, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"6", 6, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"11", 11, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"12", 12, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"12", 12, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"22", 22, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
};
|
||||
|
||||
#define TEST_CASE_4 \
|
||||
TEST_CASE_DEFINE \
|
||||
\
|
||||
ViewInfo rasterData = { \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{}, {"0"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"0"}, {"1"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"1"}, {"2"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"0"}, {"3"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"3"}, {"19"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"3"}, {"5"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"5"}, {"6"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"2"}, {"7"}}, \
|
||||
{{"7"}, {"20"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"2", "21"}, {"8"}}, \
|
||||
{{"8"}, {"9"}}, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
PassType::RASTER, \
|
||||
{ \
|
||||
{{"2"}, {"22"}}, \
|
||||
}, \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
LayoutInfo layoutInfo = { \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"0", 0, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"19", 19, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"3", 3, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"5", 5, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"6", 6, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"7", 7, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"20", 20, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"21", 21, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
{ \
|
||||
{"2", 2, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
{"22", 22, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \
|
||||
}, \
|
||||
};
|
||||
} // namespace render
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user