diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 90b68bbf2f..a7d6c92d2f 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -240,7 +240,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { const bool colorPassNeedsDepthBuffer = hasPostProcess; const backend::Handle viewRenderTarget = getRenderTarget(view); - FrameGraphId output = fg.importResource("viewRenderTarget", + FrameGraphRenderTargetHandle fgViewRenderTarget = fg.importRenderTarget("viewRenderTarget", { .viewport = vp }, viewRenderTarget, vp.width, vp.height, view.getDiscardedTargetBuffers()); @@ -386,7 +386,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { fg.present(input); - fg.moveResource(output, input); + fg.moveResource(fgViewRenderTarget, input); fg.compile(); //fg.export_graphviz(slog.d); diff --git a/filament/src/fg/FrameGraph.cpp b/filament/src/fg/FrameGraph.cpp index ea4d09e4ff..214d06af4a 100644 --- a/filament/src/fg/FrameGraph.cpp +++ b/filament/src/fg/FrameGraph.cpp @@ -294,6 +294,12 @@ fg::ResourceEntryBase& FrameGraph::getResourceEntryBaseUnchecked(FrameGraphHandl return *node.resource; } +FrameGraphRenderTarget::Descriptor const& FrameGraph::getDescriptor( + FrameGraphRenderTargetHandle handle) const noexcept { + assert(handle < mRenderTargets.size()); + return mRenderTargets[handle].desc; +} + bool FrameGraph::equals(FrameGraphRenderTarget::Descriptor const& cacheEntry, FrameGraphRenderTarget::Descriptor const& rt) const noexcept { const Vector& resourceNodes = mResourceNodes; @@ -334,24 +340,26 @@ bool FrameGraph::equals(FrameGraphRenderTarget::Descriptor const& cacheEntry, }) && samplesMatch; } -FrameGraphId FrameGraph::importResource(const char* name, +FrameGraphRenderTargetHandle FrameGraph::importRenderTarget(const char* name, FrameGraphRenderTarget::Descriptor descriptor, backend::Handle target, uint32_t width, uint32_t height, TargetBufferFlags discardStart, TargetBufferFlags discardEnd) { - // TODO: for now we don't allow imported targets to specify textures + // Imported render target can't specify textures -- it's meaningless assert(std::all_of( - descriptor.attachments.textures.begin(), - descriptor.attachments.textures.end(), + descriptor.attachments.textures.begin(), descriptor.attachments.textures.end(), [](FrameGraphHandle t) { return !t.isValid(); })); - // create the resource that will be returned to the user - FrameGraphTexture::Descriptor desc{ .width = width, .height = height }; - FrameGraphId rt = import(name, desc, {}); - descriptor.attachments.textures[0] = rt; + // create a fake imported attachment for this render target, + // so we can do a moveResource() for instance. + FrameGraphTexture::Descriptor desc{ + .width = width, .height = height, .usage = TextureUsage::COLOR_ATTACHMENT }; + descriptor.attachments.color = import(name, desc, {}); - // Populate the cache with a RenderTargetResource - // create a cache entry + // create a fg::RenderTarget, so we can get an handle + fg::RenderTarget& renderTarget = createRenderTarget(name, descriptor); + + // And pre-populate the cache with the concrete render target RenderTargetResource* pRenderTargetResource = mArena.make(name, descriptor, true,TargetBufferFlags::COLOR, width, height, TextureFormat{}); pRenderTargetResource->targetInfo.target = target; @@ -359,10 +367,7 @@ FrameGraphId FrameGraph::importResource(const char* name, pRenderTargetResource->discardEnd = discardEnd; mRenderTargetCache.emplace_back(pRenderTargetResource, *this); - // NOTE: we don't even need to create a fg::RenderTarget, all is needed is a cache entry - // so that, resolve() will find us. - - return rt; + return FrameGraphRenderTargetHandle(renderTarget.index); } TargetBufferFlags FrameGraph::computeDiscardFlags(DiscardPhase phase, diff --git a/filament/src/fg/FrameGraph.h b/filament/src/fg/FrameGraph.h index 96077ad562..2006c6b096 100644 --- a/filament/src/fg/FrameGraph.h +++ b/filament/src/fg/FrameGraph.h @@ -183,8 +183,13 @@ public: return entry.descriptor; } + // Return the FrameGraphRenderTarget Descriptor associated to this resource handle. + // The handle must be valid. + FrameGraphRenderTarget::Descriptor const& getDescriptor( + FrameGraphRenderTargetHandle handle) const noexcept; + // Import a write-only render target from outside the framegraph and returns a handle to it. - FrameGraphId importResource(const char* name, + FrameGraphRenderTargetHandle importRenderTarget(const char* name, FrameGraphRenderTarget::Descriptor descriptor, backend::Handle target, uint32_t width, uint32_t height, backend::TargetBufferFlags discardStart = backend::TargetBufferFlags::NONE, @@ -209,6 +214,12 @@ public: return FrameGraphId(moveResource(FrameGraphHandle(from), FrameGraphHandle(to))); } + // Helper for aliasing a render target's color attachment + template + FrameGraphId moveResource(FrameGraphRenderTargetHandle from, FrameGraphId to) { + return moveResource(getDescriptor(from).attachments.color.getHandle(), to); + } + // allocates concrete resources and culls unreferenced passes FrameGraph& compile() noexcept;