-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] Cache RenderPass/Framebuffer objects on the resolve texture sources. #50142
Changes from all commits
6bbae13
b3f4b88
a292db7
ffcefd1
4463ab8
43dd21c
216e185
6873355
2b7e44f
c11a0e2
089b9ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #include "flutter/testing/testing.h" | ||
| #include "gtest/gtest.h" | ||
| #include "impeller/playground/playground_test.h" | ||
| #include "impeller/renderer/backend/vulkan/texture_vk.h" | ||
| #include "impeller/renderer/render_target.h" | ||
|
|
||
| namespace impeller { | ||
| namespace testing { | ||
|
|
||
| using RendererTest = PlaygroundTest; | ||
|
|
||
| TEST_P(RendererTest, CachesRenderPassAndFramebuffer) { | ||
| if (GetBackend() != PlaygroundBackend::kVulkan) { | ||
| GTEST_SKIP() << "Test only applies to Vulkan"; | ||
| } | ||
|
|
||
| auto allocator = std::make_shared<RenderTargetAllocator>( | ||
| GetContext()->GetResourceAllocator()); | ||
|
|
||
| auto render_target = RenderTarget::CreateOffscreenMSAA( | ||
| *GetContext(), *allocator, {100, 100}, 1); | ||
| auto resolve_texture = | ||
| render_target.GetColorAttachments().find(0u)->second.resolve_texture; | ||
| auto& texture_vk = TextureVK::Cast(*resolve_texture); | ||
|
|
||
| EXPECT_EQ(texture_vk.GetFramebuffer(), nullptr); | ||
| EXPECT_EQ(texture_vk.GetRenderPass(), nullptr); | ||
|
|
||
| auto buffer = GetContext()->CreateCommandBuffer(); | ||
| auto render_pass = buffer->CreateRenderPass(render_target); | ||
|
|
||
| EXPECT_NE(texture_vk.GetFramebuffer(), nullptr); | ||
| EXPECT_NE(texture_vk.GetRenderPass(), nullptr); | ||
|
|
||
| render_pass->EncodeCommands(); | ||
| GetContext()->GetCommandQueue()->Submit({buffer}); | ||
|
|
||
| // Can be reused without error. | ||
| auto buffer_2 = GetContext()->CreateCommandBuffer(); | ||
| auto render_pass_2 = buffer_2->CreateRenderPass(render_target); | ||
|
|
||
| EXPECT_TRUE(render_pass_2->EncodeCommands()); | ||
| EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok()); | ||
| } | ||
|
|
||
| } // namespace testing | ||
| } // namespace impeller | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,9 +44,37 @@ class TextureVK final : public Texture, public BackendCast<TextureVK, Texture> { | |
|
|
||
| bool IsSwapchainImage() const { return source_->IsSwapchainImage(); } | ||
|
|
||
| // These methods should only be used by render_pass_vk.h | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comments look good 👍 |
||
|
|
||
| /// Store the last framebuffer object used with this texture. | ||
| /// | ||
| /// This field is only set if this texture is used as the resolve texture | ||
| /// of a render pass. By construction, this framebuffer should be compatible | ||
| /// with any future render passes. | ||
| void SetFramebuffer(const SharedHandleVK<vk::Framebuffer>& framebuffer); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to save this on the RenderTarget, not the Texture? This isn't applicable to every Texture, right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The RenderTarget itself is const/immutable whereas the Texture is stateful.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's not a problem though. We can make the frame buffer and render pass when we create the RenderTarget. We shouldn't ever have a RenderTarget without a render pass and it will never change, right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately that is all constructed above the backend layer, and there are no metal or gles analogs for these objects. |
||
|
|
||
| /// Store the last render pass object used with this texture. | ||
| /// | ||
| /// This field is only set if this texture is used as the resolve texture | ||
| /// of a render pass. By construction, this framebuffer should be compatible | ||
| /// with any future render passes. | ||
| void SetRenderPass(const SharedHandleVK<vk::RenderPass>& render_pass); | ||
|
|
||
| /// Retrieve the last framebuffer object used with this texture. | ||
| /// | ||
| /// May be nullptr if no previous framebuffer existed. | ||
| SharedHandleVK<vk::Framebuffer> GetFramebuffer() const; | ||
|
|
||
| /// Retrieve the last render pass object used with this texture. | ||
| /// | ||
| /// May be nullptr if no previous render pass existed. | ||
| SharedHandleVK<vk::RenderPass> GetRenderPass() const; | ||
|
|
||
| private: | ||
| std::weak_ptr<Context> context_; | ||
| std::shared_ptr<TextureSourceVK> source_; | ||
| SharedHandleVK<vk::Framebuffer> framebuffer_ = nullptr; | ||
| SharedHandleVK<vk::RenderPass> render_pass_ = nullptr; | ||
|
|
||
| // |Texture| | ||
| void SetLabel(std::string_view label) override; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test appears to run with validations locally. There were no validation errors I believe