Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for transient attachments #8021

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Conversation

mdagois
Copy link
Contributor

@mdagois mdagois commented Aug 7, 2024

Changes

  • Added support for transient attachment in the VulkanTexture class.
  • Used transient attachment for the MSAA sidecar texture.

Testing on a Pixel 8 Pro, AGI traces show a difference of roughly 100MB in GPU memory consumption.
The device was rebooted after each test to reduce the noise.

Figure 1: Transient disabled
transient_disabled

Figure 2: Transient enabled
transient_enabled

The actual difference is likely smaller.
The resolution is 1008x1920 with 4 samples and a 32-bit format (VK_FORMAT_B10G11R11_UFLOAT_PACK32).
In that configuration, the reduction in memory consumption should be around 30MB.

For reference, here are the perfetto traces: perfetto_traces.zip.

@mdagois
Copy link
Contributor Author

mdagois commented Aug 8, 2024

As an additional note, I used the vkGetDeviceMemoryCommitment function to make sure the memory was not committed when using the transient attachment.
The results are that, for the allocation size was 30,965,760 bytes, the committed size is zero.
This is the expected behavior.
Unfortunately, the vkGetDeviceMemoryCommitment function cannot be used for non-lazily allocated memory, so we cannot do a apple-to-apple comparison.

Copy link
Contributor

@poweifeng poweifeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good, but it might be missing a bit, which is the part that was undone in #7680. See also the "// DONT_CARE is critical here" comment in this document: https://arm-software.github.io/vulkan-sdk/multisampling.html

@mdagois
Copy link
Contributor Author

mdagois commented Aug 13, 2024

I think this looks good, but it might be missing a bit, which is the part that was undone in #7680. See also the "// DONT_CARE is critical here" comment in this document: https://arm-software.github.io/vulkan-sdk/multisampling.html

That means the number I got showing a 100MB saving is probably just happenstance then. :)
Let me try with the method you told me about offline (adb shell dumpsys meminfo app.name).

@mdagois
Copy link
Contributor Author

mdagois commented Aug 14, 2024

I think this looks good, but it might be missing a bit, which is the part that was undone in #7680. See also the "// DONT_CARE is critical here" comment in this document: https://arm-software.github.io/vulkan-sdk/multisampling.html

I fixed the issue by setting the loadOp based on whether the attachement uses lazily allocated memory.
Please have a look.

@mdagois
Copy link
Contributor Author

mdagois commented Aug 14, 2024

With the discard storeop, I can see the committed memory stays at zero for the MSAA attachement for as long as the application runs.
When switching to a store storeop, I can see the committed memory turning to 30MB.
So, the transient system seems to work as intended.

Copy link
Contributor

@poweifeng poweifeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome work!

@poweifeng poweifeng added the internal Issue/PR does not affect clients label Aug 14, 2024
assert_invariant(sidecar);
if (sidecar && sidecar->isTransientAttachment()) {
rpkey.usesLazilyAllocatedMemory |= (1 << i);
assert_invariant(sidecar->samples > 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this assert just bellow the sidecar assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// Lazily allocated memory is available.
context.isLazilyAllocatedMemorySupported() &&
// Usage consists of attachment flags only.
!any(tusage & ~TextureUsage::ALL_ATTACHMENTS) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use none() instead of !any()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines +355 to +356
// Clear all usage flags that are not related to attachments, so that we can
// use the transient usage flag.
const TextureUsage usage = texture->usage & TextureUsage::ALL_ATTACHMENTS;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? what if there was some other usage bits set? Shouldn't we instead passing the usage as is and let the VulkanTexture decide if it can use it?

Copy link
Contributor Author

@mdagois mdagois Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, texture->usage is the usage of the resolved texture.
We cannot use that for MSAA, as the requirements are stricter for transient attachments.

In this particular case, the SAMPLEABLE flag is raised for the original texture, but it is not necessary nor desirable for the MSAA texture, and it prevents us from setting the attachment as transient. We cannot have any flags besides the four ***_ATTACHMENT_BIT for transient attachments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it... we could eventually remove the preferTransientAttachment parameter from the VulkanTexture. I don't think there is a case where you would not want to create a transient attachment if it is possible to do so.
What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, texture->usage is the usage of the resolved texture. We cannot use that for MSAA, as the requirements are stricter for transient attachments.

In this particular case, the SAMPLEABLE flag is raised for the original texture, but it is not necessary nor desirable for the MSAA texture, and it prevents us from setting the attachment as transient. We cannot have any flags besides the four ***_ATTACHMENT_BIT for transient attachments.

mh... I want to understand why the SAMPLEABLE flag is set then. Did the framegraph set it? if it did, it's probably that it needs it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know the frame graph well enough to confirm that. I am not sure if that helps, but by the time ResourceAllocator::createTexture is called, the SAMPLEABLE flag is already there.

However, I think it is not relevant for MSAA. Whether the resolved texture is sampled or not should not impact the MSAA texture usage in any way. But, we still need to use the right attachment flags, hence the mask with TextureUsage::ALL_ATTACHMENTS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, I checked the way filament handles the MSAA resolve.
The VK_IMAGE_USAGE_TRANSFER_SRC_BIT flag is only needed when using vkCmdResolveImage. Filament uses the more efficient VkSubpassDescription::pResolveAttachments for the sidecar textures, so we are safe masking the flags unrelated to attachments.

Comment on lines 116 to 119
const VkImageUsageFlags blittable =
useTransientAttachment ?
0U :
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably revisit why blitable usages are systematically added, regardless of the BLIT_ flags -- we shouldn't have to do these shenanigans with blitable.

Copy link
Contributor Author

@mdagois mdagois Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. I think forcing everything to be blittable silently is not good, because of the potential use cases, like transient, where it gets in the way.
It is a broader change though, unrelated with transient support perse. Should we just add a separate todo?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, let's add a todo, and maybe you can have a look next? (or we will). you can even file a github issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can definitely have a look. I think some usage flags that are silently added might also be getting in the way of protected content.

@pixelflinger
Copy link
Collaborator

@mdagois could you rebase the branch and resolve the conflicts? thanks!

@mdagois
Copy link
Contributor Author

mdagois commented Sep 2, 2024

@mdagois could you rebase the branch and resolve the conflicts? thanks!

I rebased the branch.
I also simplified the code in the constructor (like removing the preferTransient boolean) since we don't have the blittable flags raised by default anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal Issue/PR does not affect clients
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants