framegraph bugfix

This commit is contained in:
ouczbs 2024-12-13 22:03:56 +08:00
parent 38cbff3c55
commit 2a48964aae
19 changed files with 166 additions and 299 deletions

View File

@ -9,6 +9,6 @@
</Type> </Type>
<Type Name="pmr::Name"> <Type Name="pmr::Name">
<!-- 显示 Name 的32位值 --> <!-- 显示 Name 的32位值 -->
<DisplayString>{g_memory_blocks[(flag3_memory29 >> 16) % 0x2000] + 2*(flag3_memory29 % 0x10000) + 2,s}</DisplayString> <DisplayString Condition="flag3_memory29">{g_memory_blocks[(flag3_memory29 >> 16) % 0x2000] + 2*(flag3_memory29 % 0x10000) + 2,s}</DisplayString>
</Type> </Type>
</AutoVisualizer> </AutoVisualizer>

View File

@ -5,24 +5,16 @@
namespace api{ namespace api{
using pmr::Name; using pmr::Name;
//* Utility functions to create std::functions without std::placeholder //* Utility functions to create std::functions without std::placeholder
template <class> template<class>
class Event; class Event {};
/**
* @brief Event that can call all of its subscribers
*
* @tparam R Return type
* @tparam Args Function arguments
*/
template <class R, class... Args> template <class R, class... Args>
class Event<R(Args...)> { class Event<R(Args...)> {
private: private:
Name name;
using Delegate = std::function<R(Args...)>; using Delegate = std::function<R(Args...)>;
using FuncMap = std::unordered_map<Name, Delegate>; std::unordered_map<const void*, Delegate> listeners;
std::unordered_map<void*, FuncMap> listeners;
//std::unordered_map<const void*, FuncMap> constListeners;
template<typename Type> template<typename Type>
static consteval auto add_const(R(Type::* ptr)(Args...)) { static constexpr auto add_const(R(Type::* ptr)(Args...)) {
using MethodType = R(Type::*)(Args...)const; using MethodType = R(Type::*)(Args...)const;
return (MethodType)ptr; return (MethodType)ptr;
} }
@ -33,155 +25,46 @@ namespace api{
}; };
} }
public: public:
Event() = default; Event(Name name) : name(name){};
/**
* @brief Subscribes a member function to the event.
*
* @tparam Invoker The instance type to call the member function
* @tparam Type The type containing the member function
* @param id Unique identifier of the subscribing function
* @param func The function to call when the event is raised
* @param invoker The instance owning the member function
*/
template <class Invoker, class Type> template <class Invoker, class Type>
void Subscribe(const Name& id, R(Type::*func)(Args... args),const Invoker* invoker) { void Subscribe(R(Type::*func)(Args... args),const Invoker* invoker) {
Subscribe<Invoker, Type>(id, add_const(func), invoker); Subscribe<Invoker, Type>(add_const(func), invoker);
} }
/**
* @brief Subscribes a const member function to the event.
*
* @tparam Invoker The instance type to call the member function
* @tparam Type The type containing the member function
* @param id Unique identifier of the subscribing function
* @param func The const function to call when the event is raised
* @param invoker The instance owning the member function
*/
template <class Invoker, class Type> template <class Invoker, class Type>
void Subscribe(const Name& id, R (Type::*func)(Args... args) const, const Invoker* invoker) { void Subscribe(R (Type::*func)(Args... args) const, const Invoker* invoker) {
Delegate deleg{ std::move(EasyBind(func, invoker)) };
auto found{ listeners.find(invoker) }; auto found{ listeners.find(invoker) };
if (found != listeners.end()) { if (found == listeners.end()) {
auto iter{ found->second.find(id) }; listeners.emplace(invoker, EasyBind(func, invoker));
if (iter != found->second.end()) {
iter->second = std::move(deleg);
}
else {
found->second.emplace(id, std::move(deleg));
}
}
else {
listeners.emplace(invoker, FuncMap{ {id, {std::move(deleg)}} });
} }
} }
/** void Subscribe(Name key,const std::function<R(Args...)>& func) {
* @brief Subscribes a free function or a std::function reference to the event auto id = key.data();
* auto found{listeners.find(id)};
* @param id Unique identifier of the subscribing function if (found == listeners.end()) {
* @param func The function to call when the event is raised listeners.emplace(id, func);
*/
void Subscribe(const Name& id,const std::function<R(Args...)>& func) {
auto found{listeners.find(nullptr)};
if (found != listeners.end()) {
auto iter{found->second.find(id)};
if (iter != found->second.end()) {
iter->second = func;
}
else {
found->second.emplace(id, func);
}
} else {
listeners.emplace(nullptr, FuncMap{{id, {func}}});
} }
} }
/**
* @brief Unsubscribes a member function from an event
*
* @tparam Invoker
* @param id Unique identifier of the subscribed function
* @param invoker The instance owning the member function
*/
template <class Invoker> template <class Invoker>
void Unsubscribe(const Name& id,const Invoker* invoker) { void Unsubscribe(const Invoker* invoker) {
auto found {listeners.find(invoker)}; auto found {listeners.find(invoker)};
if (found != listeners.end()) {
auto iter {found->second.find(id)};
if (iter != found->second.end()) {
found->second.erase(iter);
}
if (found->second.empty()) {
listeners.erase(found);
}
}
}
/**
* @brief Unsubscribes a free function/lambda from an event
*
* @param id Unique identifier of the subscribed function/lambda
*/
void Unsubscribe(const Name& id) {
auto found{listeners.find(nullptr)};
if (found != listeners.end()) {
auto iter{found->second.find(id)};
if (iter != found->second.end()) {
found->second.erase(iter);
}
if (found->second.empty()) {
listeners.erase(found);
}
}
}
/**
* @brief Unsubscribes all functions owned by the invoker const instance from this event
*
* @param invoker Const instance subscribed to this event
*/
template <class Invoker>
void RemoveListener(const Invoker* invoker) {
auto found{ listeners.find(invoker)};
if (found != listeners.end()) { if (found != listeners.end()) {
listeners.erase(found); listeners.erase(found);
} }
} }
void Unsubscribe(Name key) {
/** auto id = key.data();
* @brief Unsubscribes all free functions/lambdas from this event auto found{listeners.find(id)};
*/
void RemoveFreeFunctions() {
auto found{listeners.find(nullptr)};
if (found != listeners.end()) { if (found != listeners.end()) {
listeners.erase(found); listeners.erase(found);
} }
} }
// TODO: Check if args should be lvalues or not.
/**
* @brief Calls all subscribed functions
*
* @param args
*/
void Invoke(Args... args) { void Invoke(Args... args) {
for (auto& listener : listeners) { for (auto& func : listeners) {
for (auto& func : listener.second) { func.second(std::forward<decltype(args)>(args)...);
func.second(std::forward<decltype(args)>(args)...);
}
} }
} }
/**
* @brief Calls all subscribed functions (this is equivalent to Invoke())
*
* @param args
*/
void operator()(Args... args) { void operator()(Args... args) {
Invoke(std::forward<decltype(args)>(args)...); Invoke(std::forward<decltype(args)>(args)...);
} }
}; };
} }

View File

@ -8,6 +8,6 @@ namespace api {
EventSystem(); EventSystem();
void Initialize() override; void Initialize() override;
void Finalize() override; void Finalize() override;
Event<void()> BeginRenderFrame; Event<void()> BeginRenderFrame{"BeginRenderFrame"};
}; };
} }

View File

@ -25,9 +25,6 @@ namespace api {
for (auto view : context.views) { for (auto view : context.views) {
RenderView(view); RenderView(view);
} }
#ifdef WITH_EDITOR
//ImguiSystem::Ptr()->Render();
#endif
} }
RenderAPI::RenderAPI(RenderContext* ctx) : context(*ctx) RenderAPI::RenderAPI(RenderContext* ctx) : context(*ctx)
{ {

View File

@ -8,40 +8,31 @@ namespace api {
class TextureBuilder; class TextureBuilder;
class RenderPassBuilder; class RenderPassBuilder;
public: public:
inline static Name NameSurface{ "surface" };
TextureDesc mSurface; TextureDesc mSurface;
table<Name, TextureDesc> mResourceTable; table<Name, TextureDesc> mTextureTable;
table<TextureDesc, ImagePtr> mResourcePool; table<TextureDesc, ImagePtr> mTexturePool;
table<TextureViewDesc, ImageViewPtr> mResourceViewPool; table<TextureViewDesc, ImageViewPtr> mTextureViewPool;
lemon::ListGraph mGraph; lemon::ListGraph mGraph;
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()}; pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
public: public:
template<typename T> template<typename T>
FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); } FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); }
using RenderPassSetupFunction = std::function<bool(FrameGraph&, RenderPassBuilder&)>; using RenderPassSetupFunction = std::function<void(FrameGraph&, RenderPassBuilder&)>;
FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor); FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);
FrameGraphNodePtr AddPresent(const FrameGraphEdgePtr& edge); TextureBuilder CreateTextureBuild();
using TextureSetupFunction = std::function<void(FrameGraph&, class TextureBuilder&)>;
FrameGraphEdgePtr CreateTexture(const TextureSetupFunction& setup);
void InitSurface(const pmr::vector<TextureDesc>& surfaces); void InitSurface(const pmr::vector<TextureDesc>& surfaces);
void Compile(); void Compile();
void Execute(FRenderView& view); void Execute(FRenderView& view);
void Clear(); void Clear();
TextureDesc Resource(Name name) { ResourceState Resolve(Name name,TextureDesc& desc, ResourceState state);
static Name surface("surface"); ResourceState Resolve(Name name, AttachmentDesc& desc, ResourceState state);
if (name == surface) { ResourceState Resolve(Name name, BufferDesc& desc, ResourceState state);
return mSurface;
}
auto it = mResourceTable.find(name);
if (it == mResourceTable.end()) {
return {};
}
return it->second;
}
ImagePtr ResolveTexture(TextureDesc desc); ImagePtr ResolveTexture(TextureDesc desc);
ImageViewPtr ResolveTextureView(TextureViewDesc desc); ImageViewPtr ResolveTextureView(TextureViewDesc desc);
public: public:
void ExecutePresentPass(FRenderView& view);
void ExecuteRenderPass(RenderPassNode* node, FRenderView& view); void ExecuteRenderPass(RenderPassNode* node, FRenderView& view);
void ExecutePresentPass(RenderPassNode* node, FRenderView& view);
void ExecuteComputePass(RenderPassNode* node, FRenderView& view); void ExecuteComputePass(RenderPassNode* node, FRenderView& view);
void ExecuteCopyPass(RenderPassNode* node, FRenderView& view); void ExecuteCopyPass(RenderPassNode* node, FRenderView& view);

View File

@ -13,13 +13,13 @@ namespace api {
FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc, ResourceState state); FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc, ResourceState state);
FrameGraph::RenderPassBuilder& Read(const FrameGraphEdgePtr& refEdge, ResourceState state); FrameGraph::RenderPassBuilder& Read(const FrameGraphEdgePtr& refEdge, ResourceState state);
FrameGraph::RenderPassBuilder& Write(const FrameGraphEdgePtr& refEdge, ResourceState state); FrameGraph::RenderPassBuilder& Write(const FrameGraphEdgePtr& refEdge, ResourceState state);
FrameGraph::RenderPassBuilder& Present(const FrameGraphEdgePtr& refEdge, ResourceState state);
}; };
struct FrameGraph::TextureBuilder { struct FrameGraph::TextureBuilder {
FrameGraph& graph; FrameGraph& graph;
FrameGraphEdgePtr& edge; FrameGraphEdgePtr edge;
public: public:
TextureBuilder(FrameGraph* graph, FrameGraphEdgePtr& edge)noexcept : graph(*graph), edge(edge) {}; TextureBuilder(FrameGraph* graph)noexcept : graph(*graph) { edge.Make(); };
FrameGraph::TextureBuilder& Import(pmr::Name name, AttachmentDesc desc, ResourceState state); FrameGraph::TextureBuilder& Import(pmr::Name name, AttachmentDesc desc, ResourceState state);
FrameGraphEdgePtr Edge() { return edge; }
}; };
} }

View File

@ -32,7 +32,6 @@ namespace api {
NodeType type{ NodeType::Render }; NodeType type{ NodeType::Render };
RenderPassNode* node; RenderPassNode* node;
FrameGraphNodePtr() : node(nullptr){}; FrameGraphNodePtr() : node(nullptr){};
FrameGraphNodePtr(GraphNodeRef ref, NodeType type = NodeType::Present);
FrameGraphNodePtr(GraphNodeRef ref, const RenderPassNodeExecuteFn& executor, NodeType type = NodeType::Render); FrameGraphNodePtr(GraphNodeRef ref, const RenderPassNodeExecuteFn& executor, NodeType type = NodeType::Render);
operator bool() const { operator bool() const {
return node; return node;
@ -40,12 +39,10 @@ namespace api {
RenderPassNode* operator ->()const { RenderPassNode* operator ->()const {
return node; return node;
} }
void Presnet(FrameGraph&, RenderPassContext&);
}; };
struct FrameResource { struct FrameResource {
using Resource = std::variant<TextureDesc, BufferDesc, AttachmentDesc>; using Resource = std::variant<TextureDesc, BufferDesc, AttachmentDesc>;
Name name; Name name;
ResourceState sourceState;
Resource resource; Resource resource;
FrameGraphNodePtr source; FrameGraphNodePtr source;
pmr::vector<FrameGraphNodePtr> targets{ FramePool() }; pmr::vector<FrameGraphNodePtr> targets{ FramePool() };
@ -81,7 +78,6 @@ namespace api {
FrameResource* operator ->()const { FrameResource* operator ->()const {
return resource; return resource;
} }
void Resolve(FrameGraph* graph);
void ResolveView(FrameGraph* graph); void ResolveView(FrameGraph* graph);
}; };
using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>; using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>;

View File

@ -7,15 +7,6 @@ namespace api {
SINGLETON_IMPL(ImguiSystem) SINGLETON_IMPL(ImguiSystem)
public: public:
ImguiSystem(); ImguiSystem();
// 渲染开始和结束
virtual void Render() {
BeginEditorRender();
EditorRender();
EndEditorRender();
}
virtual void BeginEditorRender() = 0;
virtual void EditorRender() = 0;
virtual void EndEditorRender() = 0;
}; };
} }
#endif // WITH_EDITOR #endif // WITH_EDITOR

View File

@ -4,7 +4,7 @@
namespace api { namespace api {
class DemoPass : public RenderPass { class DemoPass : public RenderPass {
public: public:
static bool Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder); static void Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder);
static void Execute(FrameGraph&, RenderPassContext&); static void Execute(FrameGraph&, RenderPassContext&);
}; };

View File

@ -174,6 +174,8 @@ namespace api {
using ImagePtr = void*; using ImagePtr = void*;
using ImageViewPtr = void*; using ImageViewPtr = void*;
using BufferPtr = void*; using BufferPtr = void*;
struct BufferBarrier;
struct TextureBarrier;
struct BufferDesc { struct BufferDesc {
BufferPtr buffer; BufferPtr buffer;
void* mappingAddr; void* mappingAddr;
@ -183,6 +185,7 @@ namespace api {
static BufferDesc Make() { static BufferDesc Make() {
return {}; return {};
} }
BufferBarrier ToBarrier(ResourceState from, ResourceState to);
}; };
struct TextureViewDesc { struct TextureViewDesc {
ImagePtr image; ImagePtr image;
@ -215,6 +218,7 @@ namespace api {
desc.dimension = dimension; desc.dimension = dimension;
return desc; return desc;
} }
TextureBarrier ToBarrier(ResourceState from, ResourceState to);
}; };
struct AttachmentDesc { struct AttachmentDesc {
ImagePtr image; ImagePtr image;
@ -248,6 +252,7 @@ namespace api {
desc.dimension = dimension; desc.dimension = dimension;
return desc; return desc;
} }
TextureBarrier ToBarrier(ResourceState from, ResourceState to);
}; };
struct TextureBarrier struct TextureBarrier
{ {
@ -280,6 +285,29 @@ namespace api {
const TextureBarrier* pTextureBarriers; const TextureBarrier* pTextureBarriers;
uint32_t textureBarriersCount; uint32_t textureBarriersCount;
}; };
inline BufferBarrier BufferDesc::ToBarrier(ResourceState from, ResourceState to)
{
BufferBarrier barrier;
barrier.mSrcState = from;
barrier.mDstState = to;
return barrier;
}
inline TextureBarrier TextureDesc::ToBarrier(ResourceState from, ResourceState to)
{
TextureBarrier barrier;
barrier.mSrcState = from;
barrier.mDstState = to;
barrier.mTexture = *this;
return barrier;
}
inline TextureBarrier AttachmentDesc::ToBarrier(ResourceState from, ResourceState to)
{
TextureBarrier barrier;
barrier.mSrcState = from;
barrier.mDstState = to;
barrier.mTexture = ToTexture();
return barrier;
}
} }
#include "meta/hash.h" #include "meta/hash.h"
namespace std { namespace std {

View File

@ -24,29 +24,17 @@ namespace api {
if (k1.depth != k2.depth) return false; if (k1.depth != k2.depth) return false;
return true; return true;
} }
FrameGraphNodePtr FrameGraph::AddPresent(const FrameGraphEdgePtr& edge)
{
FrameGraphNodePtr node_ptr{ mGraph.addNode()};
RenderPassBuilder builder{ this, node_ptr };
builder.Read(edge, ResourceState::PRESENT);
mNodes.push_back(node_ptr);
return node_ptr;
}
FrameGraphNodePtr FrameGraph::AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor) FrameGraphNodePtr FrameGraph::AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor)
{ {
FrameGraphNodePtr node_ptr{ mGraph.addNode(), executor }; FrameGraphNodePtr node_ptr{ mGraph.addNode(), executor };
RenderPassBuilder builder{ this, node_ptr }; RenderPassBuilder builder{ this, node_ptr };
if(setup(*this, builder)) setup(*this, builder);
mNodes.push_back(node_ptr); mNodes.push_back(node_ptr);
return node_ptr; return node_ptr;
} }
FrameGraphEdgePtr FrameGraph::CreateTexture(const TextureSetupFunction& setup) FrameGraph::TextureBuilder FrameGraph::CreateTextureBuild()
{ {
FrameGraphEdgePtr edge{}; return TextureBuilder{this};
edge.Make();
TextureBuilder builder(this, edge);
setup(*this, builder);
return edge;
} }
void FrameGraph::InitSurface(const pmr::vector<TextureDesc>& surfaces) void FrameGraph::InitSurface(const pmr::vector<TextureDesc>& surfaces)
{ {
@ -76,17 +64,17 @@ namespace api {
case RenderPassType::Render: case RenderPassType::Render:
ExecuteRenderPass(node.node, view); ExecuteRenderPass(node.node, view);
break; break;
case RenderPassType::Present:
ExecutePresentPass(node.node, view);
break;
case RenderPassType::Compute: case RenderPassType::Compute:
ExecuteComputePass(node.node, view); ExecuteComputePass(node.node, view);
break; break;
case RenderPassType::Copy: case RenderPassType::Copy:
ExecuteCopyPass(node.node, view); ExecuteCopyPass(node.node, view);
break; break;
default:
break;
} }
} }
ExecutePresentPass(view);
} }
void FrameGraph::Clear() void FrameGraph::Clear()
{ {
@ -102,9 +90,20 @@ namespace api {
std::get<RenderPassExecuteFunction>(node->executor)(*this, context); std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
RenderAPI::Ptr()->EndRenderPass(node); RenderAPI::Ptr()->EndRenderPass(node);
} }
void FrameGraph::ExecutePresentPass(RenderPassNode* node, FRenderView& view) void FrameGraph::ExecutePresentPass(FRenderView& view)
{ {
ExecuteResourceBarriers(node, RenderPassType::Present); if (mSurface.state == ResourceState::PRESENT) {
return;
}
TextureBarrier barrier{};
barrier.mSrcState = mSurface.state;
barrier.mDstState = ResourceState::PRESENT;
barrier.mTexture = mSurface;
ResourceBarrierDesc desc{};
desc.type = RenderPassType::Present;
desc.textureBarriersCount = 1;
desc.pTextureBarriers = &barrier;
RenderAPI::Ptr()->ExecuteResourceBarriers(desc);
} }
void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view) void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view)
{ {
@ -120,32 +119,23 @@ namespace api {
{ {
pmr::vector<BufferBarrier> bufferBarrier{FramePool()}; pmr::vector<BufferBarrier> bufferBarrier{FramePool()};
pmr::vector<TextureBarrier> textureBarrier{ FramePool() }; pmr::vector<TextureBarrier> textureBarrier{ FramePool() };
auto graph = &RenderAPI::Ptr()->graph;
node->ForeachEdge([&](FrameResource* resource, FrameGraphEdgePtr edge) { node->ForeachEdge([&](FrameResource* resource, FrameGraphEdgePtr edge) {
edge.Resolve(&RenderAPI::Ptr()->graph); std::visit([&](auto& desc) {
if (!edge || edge.targetState == resource->sourceState) { ResourceState targetState = edge.targetState;
return; ResourceState sourceState = graph->Resolve(resource->name, desc, targetState);
} if (sourceState != targetState) {
if (resource->IsBuffer()) { auto barrier = desc.ToBarrier(sourceState, targetState);
BufferBarrier barrier{}; using T = decltype(barrier);
barrier.mSrcState = resource->sourceState; if constexpr (std::is_same_v<T, BufferBarrier>) {
barrier.mDstState = edge.targetState; bufferBarrier.push_back(barrier);
bufferBarrier.push_back(barrier); }
} else {
else { textureBarrier.push_back(barrier);
TextureBarrier barrier{}; }
barrier.mSrcState = resource->sourceState;
barrier.mDstState = edge.targetState;
if (edge->IsTexture()) {
barrier.mTexture = edge->CastTo<TextureDesc>();
} }
else { }, resource->resource);
auto& attach = edge->CastTo<AttachmentDesc>(); });
barrier.mTexture = attach.ToTexture();
}
textureBarrier.push_back(barrier);
}
resource->sourceState = edge.targetState;
});
if (bufferBarrier.empty() && textureBarrier.empty()) { if (bufferBarrier.empty() && textureBarrier.empty()) {
return; return;
} }
@ -157,32 +147,47 @@ namespace api {
desc.pTextureBarriers = textureBarrier.data(); desc.pTextureBarriers = textureBarrier.data();
RenderAPI::Ptr()->ExecuteResourceBarriers(desc); RenderAPI::Ptr()->ExecuteResourceBarriers(desc);
} }
void RenderPassNode::ForeachEdge(RenderPassEdgeIterFn fn) { ResourceState FrameGraph::Resolve(Name name, TextureDesc& desc, ResourceState state)
for (auto& edge : inEdges) { {
fn(edge.resource, edge); ResourceState sourceState = ResourceState::UNDEFINED;
if (name == NameSurface) {
mSurface = desc;
} }
for (auto& edge : outEdges) { return sourceState;
fn(edge.resource, edge); }
ResourceState FrameGraph::Resolve(Name name, AttachmentDesc& desc, ResourceState state)
{
ResourceState sourceState = ResourceState::UNDEFINED;
if (name == NameSurface) {
sourceState = mSurface.state;
mSurface.state = state;
return sourceState;
} }
return sourceState;
}
ResourceState FrameGraph::Resolve(Name name, BufferDesc& desc, ResourceState state)
{
ResourceState sourceState = ResourceState::UNDEFINED;
return sourceState;
} }
ImagePtr FrameGraph::ResolveTexture(TextureDesc desc) ImagePtr FrameGraph::ResolveTexture(TextureDesc desc)
{ {
auto it = mResourcePool.find(desc); auto it = mTexturePool.find(desc);
if (it != mResourcePool.end()) { if (it != mTexturePool.end()) {
return it->second; return it->second;
} }
ImagePtr image = RenderAPI::Ptr()->CreateTexture(desc); ImagePtr image = RenderAPI::Ptr()->CreateTexture(desc);
mResourcePool.emplace(desc, image); mTexturePool.emplace(desc, image);
return image; return image;
} }
ImageViewPtr FrameGraph::ResolveTextureView(TextureViewDesc desc) ImageViewPtr FrameGraph::ResolveTextureView(TextureViewDesc desc)
{ {
auto it = mResourceViewPool.find(desc); auto it = mTextureViewPool.find(desc);
if (it != mResourceViewPool.end()) { if (it != mTextureViewPool.end()) {
return it->second; return it->second;
} }
ImageViewPtr view = RenderAPI::Ptr()->CreateTextureView(desc); ImageViewPtr view = RenderAPI::Ptr()->CreateTextureView(desc);
mResourceViewPool.emplace(desc, view); mTextureViewPool.emplace(desc, view);
return view; return view;
} }
} }

View File

@ -60,13 +60,6 @@ namespace api {
graph.mGraph.addEdge(node.ref, refEdge->source.ref); graph.mGraph.addEdge(node.ref, refEdge->source.ref);
return *this; return *this;
} }
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Present(const FrameGraphEdgePtr& refEdge, ResourceState state)
{
Write(refEdge, state);
graph.mNodes.push_back(node);
graph.AddPresent(refEdge);
return *this;
}
FrameGraph::TextureBuilder& FrameGraph::TextureBuilder::Import(pmr::Name name, AttachmentDesc desc, ResourceState state) FrameGraph::TextureBuilder& FrameGraph::TextureBuilder::Import(pmr::Name name, AttachmentDesc desc, ResourceState state)
{ {
edge->name = name; edge->name = name;

View File

@ -1,51 +1,20 @@
#include "render/graph/type.h" #include "render/graph/type.h"
#include "render/renderapi.h" #include "render/renderapi.h"
namespace api { namespace api {
void FrameGraphEdgePtr::Resolve(FrameGraph* graph)
{
if (!resource) {
Make();
}
ImagePtr* imageptr;
if (resource->IsAttachment()) {
AttachmentDesc& desc = resource->CastTo<AttachmentDesc>();
imageptr = &desc.image;
}
else if (resource->IsTexture()) {
TextureDesc& desc = resource->CastTo<TextureDesc>();
imageptr = &desc.image;
}
if (*imageptr) {
return;
}
TextureDesc desc = graph->Resource(resource->name);
if (!desc.image) {
graph->ResolveTexture(desc);
}
else {
*imageptr = desc.image;
}
}
void FrameGraphEdgePtr::ResolveView(FrameGraph* graph) void FrameGraphEdgePtr::ResolveView(FrameGraph* graph)
{ {
if (!resource) {
Make();
}
if (resource->IsAttachment()) { if (resource->IsAttachment()) {
AttachmentDesc& attach = resource->CastTo<AttachmentDesc>(); AttachmentDesc& attach = resource->CastTo<AttachmentDesc>();
TextureViewDesc desc = attach.ToTextureView(); TextureViewDesc desc = attach.ToTextureView();
attach.imageView = graph->ResolveTextureView(desc); attach.imageView = graph->ResolveTextureView(desc);
} }
} }
FrameGraphNodePtr::FrameGraphNodePtr(GraphNodeRef ref, NodeType type) void RenderPassNode::ForeachEdge(RenderPassEdgeIterFn fn) {
: ref(ref), type(type) for (auto& edge : inEdges) {
{ fn(edge.resource, edge);
node = new (FramePool()) RenderPassNode(); }
node->executor = [&](FrameGraph& graph, RenderPassContext& ctx) { for (auto& edge : outEdges) {
this->Presnet(graph, ctx); fn(edge.resource, edge);
}; }
}
void FrameGraphNodePtr::Presnet(FrameGraph&, RenderPassContext&) {
} }
} }

View File

@ -9,20 +9,18 @@ namespace api {
static RscHandle<Material> material; static RscHandle<Material> material;
static RscHandle<Shader> shader; static RscHandle<Shader> shader;
static RscHandle<Mesh> mesh; static RscHandle<Mesh> mesh;
bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
{ {
AttachmentDesc surface{}; AttachmentDesc surface{};
surface.FromTexture(graph.mSurface); surface.FromTexture(graph.mSurface);
surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB; surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB;
surface.sampleCount = SAMPLE_COUNT_1; surface.sampleCount = SAMPLE_COUNT_1;
surface.dimension = TextureDimension::TEX_2D; surface.dimension = TextureDimension::TEX_2D;
auto edge = graph.CreateTexture( auto edge = graph.CreateTextureBuild()
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) { .Import(FrameGraph::NameSurface, surface, ResourceState::COLOR_ATTACHMENT)
builder.Import("surface", surface, ResourceState::COLOR_ATTACHMENT); .Edge();
});
builder.Name("MiniPass") builder.Name("MiniPass")
.Present(edge, edge.targetState); .Write(edge, edge.targetState);
return false;
} }
void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx) void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx)
{ {

View File

@ -1,11 +1,15 @@
#pragma once #pragma once
#include "render/imgui_system.h" #include "render/imgui_system.h"
#include "render/graph/frame_graph.h"
namespace vkn { namespace vkn {
using api::FrameGraph;
using api::RenderPassContext;
class VulkanImguiSystem : public api::ImguiSystem { class VulkanImguiSystem : public api::ImguiSystem {
public:
void Initialize() override; void Initialize() override;
void Finalize() override; void Finalize() override;
void BeginEditorRender() override; void Render();
void EditorRender() override; static void Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder);
void EndEditorRender() override; static void Execute(FrameGraph&, RenderPassContext&);
}; };
} }

View File

@ -61,7 +61,7 @@ namespace vkn {
{ {
vkEndCommandBuffer(surfaceCommand); vkEndCommandBuffer(surfaceCommand);
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段 VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段
VkSemaphore waitSemaphores[] = { graphSemaphore }; VkSemaphore waitSemaphores[] = { graphSemaphore ? graphSemaphore : surfaceSemaphore };
VkSemaphore signalSemaphores[] = { presentSemaphore };// 渲染完成信号量 VkSemaphore signalSemaphores[] = { presentSemaphore };// 渲染完成信号量
VkSubmitInfo submitInfo{}; VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

View File

@ -8,8 +8,10 @@
#include "vkn/wrapper/queue.h" #include "vkn/wrapper/queue.h"
#include "imgui/imgui_impl_vulkan.h" #include "imgui/imgui_impl_vulkan.h"
#include "imgui/imgui_impl_sdl2.h" #include "imgui/imgui_impl_sdl2.h"
#include "event/event_system.h"
#include "tinyimageformat/tinyimageformat_apis.h" #include "tinyimageformat/tinyimageformat_apis.h"
namespace vkn { namespace vkn {
using api::EventSystem;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static VkCommandPool g_CommandPool = VK_NULL_HANDLE; static VkCommandPool g_CommandPool = VK_NULL_HANDLE;
@ -164,19 +166,27 @@ namespace vkn {
auto& surfaces = window->Swapchain()->GetSurface(); auto& surfaces = window->Swapchain()->GetSurface();
//CreateFrameBuffer(API, renderPass, surfaces); //CreateFrameBuffer(API, renderPass, surfaces);
//CreateCommandPool(backend.GetDevice().Ptr(), pQueue->QueueFamilyIndex(), surfaces.size()); //CreateCommandPool(backend.GetDevice().Ptr(), pQueue->QueueFamilyIndex(), surfaces.size());
EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanImguiSystem::Render, this);
} }
void VulkanImguiSystem::Finalize() void VulkanImguiSystem::Finalize()
{ {
} }
void VulkanImguiSystem::BeginEditorRender() void VulkanImguiSystem::Render()
{
if(false)
VulkanAPI::Ptr()->graph.AddRenderPass<VulkanImguiSystem>();
}
void VulkanImguiSystem::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
{
}
void VulkanImguiSystem::Execute(FrameGraph&, RenderPassContext&)
{ {
ImGui_ImplVulkan_NewFrame(); ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
}
void VulkanImguiSystem::EditorRender()
{
static float my_float = 0.5f; static float my_float = 0.5f;
ImGui::Begin("Hello, ImGui!"); ImGui::Begin("Hello, ImGui!");
ImGui::Text("This is some useful text."); ImGui::Text("This is some useful text.");
@ -184,8 +194,10 @@ namespace vkn {
ImGui::End(); ImGui::End();
ImGui::Render(); ImGui::Render();
} }
void VulkanImguiSystem::EndEditorRender() void EndEditorRender()
{ {
/* /*
VulkanAPI* API = VulkanAPI::Ptr(); VulkanAPI* API = VulkanAPI::Ptr();

View File

@ -70,7 +70,7 @@ namespace vkn {
desc.width = args.width; desc.width = args.width;
desc.height = args.height; desc.height = args.height;
desc.format = TinyImageFormat_FromVkFormat((TinyImageFormat_VkFormat)args.imageFormat); desc.format = TinyImageFormat_FromVkFormat((TinyImageFormat_VkFormat)args.imageFormat);
desc.state = ResourceState::PRESENT; desc.state = ResourceState::UNDEFINED;
desc.sampleCount = SampleCount::SAMPLE_COUNT_1; desc.sampleCount = SampleCount::SAMPLE_COUNT_1;
desc.arraySize = 1; desc.arraySize = 1;
desc.mipLevel = 1; desc.mipLevel = 1;

View File

@ -27,7 +27,7 @@ void ZWorldModule::OnLoad(int argc, char** argv)
#ifdef WITH_EDITOR //绑定窗口交互 #ifdef WITH_EDITOR //绑定窗口交互
ImGui_ImplSDL2_InitForVulkan(window->GetPtr()); ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
#endif #endif
EventSystem::Ptr()->BeginRenderFrame.Subscribe("zworld", []() { EventSystem::Ptr()->BeginRenderFrame.Subscribe(mInfo.name, []() {
API->graph.AddRenderPass<DemoPass>(); API->graph.AddRenderPass<DemoPass>();
}); });
} }