Skip to content

Commit 74a8d79

Browse files
author
Jonah Williams
authored
[Impeller] dont redundantly set stencil reference on vulkan backend. (#164763)
Cache the last stencil reference in RenderPassVK. If the requested stencil reference is set to the same value, don't update it on the cmd buffer. Hypothetical performance improvement, but easy to do.
1 parent 7111628 commit 74a8d79

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

engine/src/flutter/ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
../../../flutter/impeller/renderer/backend/vulkan/pipeline_cache_data_vk_unittests.cc
203203
../../../flutter/impeller/renderer/backend/vulkan/render_pass_builder_vk_unittests.cc
204204
../../../flutter/impeller/renderer/backend/vulkan/render_pass_cache_unittests.cc
205+
../../../flutter/impeller/renderer/backend/vulkan/render_pass_vk_unittests.cc
205206
../../../flutter/impeller/renderer/backend/vulkan/resource_manager_vk_unittests.cc
206207
../../../flutter/impeller/renderer/backend/vulkan/swapchain/README.md
207208
../../../flutter/impeller/renderer/backend/vulkan/swapchain/khr/README.md

engine/src/flutter/impeller/renderer/backend/vulkan/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ impeller_component("vulkan_unittests") {
1919
"pipeline_cache_data_vk_unittests.cc",
2020
"render_pass_builder_vk_unittests.cc",
2121
"render_pass_cache_unittests.cc",
22+
"render_pass_vk_unittests.cc",
2223
"resource_manager_vk_unittests.cc",
2324
"test/gpu_tracer_unittests.cc",
2425
"test/mock_vulkan.cc",

engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ void RenderPassVK::SetCommandLabel(std::string_view label) {
340340

341341
// |RenderPass|
342342
void RenderPassVK::SetStencilReference(uint32_t value) {
343+
if (current_stencil_ == value) {
344+
return;
345+
}
346+
current_stencil_ = value;
343347
command_buffer_vk_.setStencilReference(
344348
vk::StencilFaceFlagBits::eVkStencilFrontAndBack, value);
345349
}

engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class RenderPassVK final : public RenderPass {
3434
vk::CommandBuffer command_buffer_vk_;
3535
std::shared_ptr<Texture> color_image_vk_;
3636
std::shared_ptr<Texture> resolve_image_vk_;
37+
uint32_t current_stencil_ = 0;
3738

3839
// Per-command state.
3940
std::array<vk::DescriptorImageInfo, kMaxBindings> image_workspace_;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/testing/testing.h" // IWYU pragma: keep
6+
#include "gtest/gtest.h"
7+
#include "impeller/core/formats.h"
8+
#include "impeller/renderer/backend/vulkan/render_pass_builder_vk.h"
9+
#include "impeller/renderer/backend/vulkan/render_pass_vk.h"
10+
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
11+
#include "impeller/renderer/render_target.h"
12+
#include "vulkan/vulkan_enums.hpp"
13+
14+
namespace impeller {
15+
namespace testing {
16+
17+
TEST(RenderPassVK, DoesNotRedundantlySetStencil) {
18+
std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
19+
std::shared_ptr<Context> copy = context;
20+
auto cmd_buffer = context->CreateCommandBuffer();
21+
22+
RenderTargetAllocator allocator(context->GetResourceAllocator());
23+
RenderTarget target = allocator.CreateOffscreenMSAA(*copy.get(), {1, 1}, 1);
24+
25+
std::shared_ptr<RenderPass> render_pass =
26+
cmd_buffer->CreateRenderPass(target);
27+
28+
// Stencil reference set once at buffer start.
29+
auto called_functions = GetMockVulkanFunctions(context->GetDevice());
30+
EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
31+
"vkCmdSetStencilReference"),
32+
1);
33+
34+
// Duplicate stencil ref is not replaced.
35+
render_pass->SetStencilReference(0);
36+
render_pass->SetStencilReference(0);
37+
render_pass->SetStencilReference(0);
38+
39+
called_functions = GetMockVulkanFunctions(context->GetDevice());
40+
EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
41+
"vkCmdSetStencilReference"),
42+
1);
43+
44+
// Different stencil value is updated.
45+
render_pass->SetStencilReference(1);
46+
called_functions = GetMockVulkanFunctions(context->GetDevice());
47+
EXPECT_EQ(std::count(called_functions->begin(), called_functions->end(),
48+
"vkCmdSetStencilReference"),
49+
2);
50+
}
51+
52+
} // namespace testing
53+
} // namespace impeller

0 commit comments

Comments
 (0)