diff --git a/filament/src/fg/FrameGraph.cpp b/filament/src/fg/FrameGraph.cpp index a3ff301875..ac3a79d76e 100644 --- a/filament/src/fg/FrameGraph.cpp +++ b/filament/src/fg/FrameGraph.cpp @@ -236,8 +236,8 @@ struct RenderTarget { // 32 uint32_t minHeight = std::numeric_limits::max(); uint32_t maxHeight = 0; - for (FrameGraphResource const& attachment : desc.attachments.textures) { - size_t i = &attachment - desc.attachments.textures.data(); + for (size_t i = 0; i < desc.attachments.textures.size(); i++) { + FrameGraphResource attachment = desc.attachments.textures[i]; if (attachment.isValid()) { Resource const* const pResource = resourceNodes[attachment.index].resource; assert(pResource); @@ -273,11 +273,11 @@ struct RenderTarget { // 32 // use the largest size. // We also round dimensions up to avoid lots of small resizes in the driver. // (this is assuming the driver uses some cache internally). - width = (maxWidth + 31) & ~31; - height = (maxHeight + 31) & ~31; + width = (maxWidth + 31u) & ~31u; + height = (maxHeight + 31u) & ~31u; // and update the resource's descriptors that allow it - for (FrameGraphResource const& attachment : desc.attachments.textures) { + for (FrameGraphResource attachment : desc.attachments.textures) { if (attachment.isValid()) { Resource* const pResource = resourceNodes[attachment.index].resource; if (pResource->desc.relaxed || !pResource->needsTexture) { @@ -499,21 +499,25 @@ FrameGraph::Builder::Attachments FrameGraph::Builder::useRenderTarget(const char TextureUsage::DEPTH_ATTACHMENT, TextureUsage::STENCIL_ATTACHMENT }; - for (FrameGraphResource const& attachment : desc.attachments.textures) { - const size_t index = &attachment - desc.attachments.textures.data(); - if (attachment.isValid()) { - // using a resource as a RT implies reading (i.e. adds a reference to that resource) from it - rt.textures[index] = mPass.read(fg, attachment, true); - // using a resource as a RT implies writing (i.e. adds a reference to the pass) into it - rt.textures[index] = mPass.write(fg, rt.textures[index]); - - ResourceNode& node = fg.getResource(rt.textures[index]); + for (size_t i = 0; i < desc.attachments.textures.size(); i++) { + Attachments::AttachmentInfo attachmentInfo = desc.attachments.textures[i]; + if (attachmentInfo.isValid()) { + FrameGraphResource attachment = attachmentInfo.getHandle(); + if (attachmentInfo.getAccess() & Attachments::Access::READ) { + attachment = mPass.read(fg, attachment, true); + } + if (attachmentInfo.getAccess() & Attachments::Access::WRITE) { + attachment = mPass.write(fg, attachment); + } + ResourceNode& node = fg.getResource(attachment); uint8_t usage = node.resource->usage; - usage |= usages[index]; + usage |= usages[i]; node.resource->usage = TextureUsage(usage); // renderTargetIndex is used to retrieve the Descriptor node.renderTargetIndex = renderTarget.index; + + rt.textures[i] = attachment; } } return rt; @@ -829,11 +833,11 @@ TargetBufferFlags FrameGraph::computeDiscardFlags(DiscardPhase phase, for (FrameGraphResource cur : ((phase == DiscardPhase::START) ? pass.writes : pass.reads)) { // for all possible attachments of our renderTarget... Resource const* const pResource = resourceNodes[cur.index].resource; - for (FrameGraphResource const& attachment : desc.attachments.textures) { + for (size_t i = 0; i < desc.attachments.textures.size(); i++) { + FrameGraphResource attachment = desc.attachments.textures[i]; if (attachment.isValid() && resourceNodes[attachment.index].resource == pResource) { // we can't discard this attachment since it's read/written - size_t index = &attachment - desc.attachments.textures.data(); - discardFlags &= ~flags[index]; + discardFlags &= ~flags[i]; } } if (!discardFlags) { @@ -897,7 +901,8 @@ FrameGraph& FrameGraph::compile() noexcept { for (fg::RenderTarget& rt : renderTargets) { auto& textures = rt.desc.attachments.textures; if (textures[0].isValid()) { - ResourceNode const& node = resourceNodes[textures[0].index]; + FrameGraphResource handle = textures[0]; + ResourceNode const& node = resourceNodes[handle.index]; if (node.resource->imported && node.resource == from.resource) { for (size_t i = 1; i < textures.size(); ++i) { textures[i] = {}; diff --git a/filament/src/fg/FrameGraphResource.h b/filament/src/fg/FrameGraphResource.h index 38067cf4a4..21c6ca2755 100644 --- a/filament/src/fg/FrameGraphResource.h +++ b/filament/src/fg/FrameGraphResource.h @@ -88,13 +88,34 @@ public: namespace FrameGraphRenderTarget { struct Attachments { - enum { COLOR, DEPTH }; + enum Access : uint8_t { + READ = 0x1, + WRITE = 0x2, + READ_WRITE = READ | WRITE + }; + struct AttachmentInfo { + AttachmentInfo() noexcept = default; + AttachmentInfo(FrameGraphResource handle) noexcept : mHandle(handle) {} // NOLINT + AttachmentInfo(FrameGraphResource handle, Access access) noexcept + : mHandle(handle), mAccess(access) {} + + operator FrameGraphResource() const noexcept { return mHandle; } // NOLINT + + bool isValid() const noexcept { return mHandle.isValid(); } + FrameGraphResource getHandle() const noexcept { return mHandle; } + Access getAccess() const noexcept { return mAccess; } + private: + FrameGraphResource mHandle{}; + Access mAccess = Access::READ_WRITE; + }; + + enum { COLOR = 0, DEPTH = 1 }; static constexpr size_t COUNT = 2; union { - std::array textures = {}; + std::array textures = {}; struct { - FrameGraphResource color; - FrameGraphResource depth; + AttachmentInfo color; + AttachmentInfo depth; }; }; };