mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] remove transfer barriers from render pass, drop blit, tighten up graphics on level 3. (#165584)
The change to fix PowerVR barriers regressed Mali (see https://github.com/flutter/flutter/issues/165538) We need to tighten the barriers to remove the transfer barrier to get back mali performance. however, this requires us to drop the usage of the blit for onscreen restore. not a huge loss imo. At any rate, all of these changes should be visible in benchmarks.
This commit is contained in:
parent
46969e531b
commit
33cf3b65bc
@ -1718,8 +1718,8 @@ bool Canvas::SupportsBlitToOnscreen() const {
|
||||
return renderer_.GetContext()
|
||||
->GetCapabilities()
|
||||
->SupportsTextureToTextureBlits() &&
|
||||
renderer_.GetContext()->GetBackendType() !=
|
||||
Context::BackendType::kOpenGLES;
|
||||
renderer_.GetContext()->GetBackendType() ==
|
||||
Context::BackendType::kMetal;
|
||||
}
|
||||
|
||||
bool Canvas::BlitToOnscreen(bool is_onscreen) {
|
||||
|
||||
@ -378,7 +378,7 @@ TEST_P(AiksTest, SupportsBlitToOnscreen) {
|
||||
auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
|
||||
/*requires_readback=*/true);
|
||||
|
||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||
if (GetBackend() != PlaygroundBackend::kMetal) {
|
||||
EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
|
||||
} else {
|
||||
EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
|
||||
|
||||
@ -56,11 +56,7 @@ vk::UniqueImage CreateVKImageWrapperForAndroidHarwareBuffer(
|
||||
}
|
||||
if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
|
||||
image_usage_flags |= vk::ImageUsageFlagBits::eColorAttachment;
|
||||
}
|
||||
if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY) {
|
||||
image_usage_flags |= vk::ImageUsageFlagBits::eColorAttachment;
|
||||
image_usage_flags |= vk::ImageUsageFlagBits::eInputAttachment;
|
||||
image_usage_flags |= vk::ImageUsageFlagBits::eTransferDst;
|
||||
}
|
||||
|
||||
vk::ImageCreateFlags image_create_flags;
|
||||
@ -302,7 +298,7 @@ TextureDescriptor ToTextureDescriptor(const AHardwareBuffer_Desc& ahb_desc) {
|
||||
desc.mip_count = (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
|
||||
? ahb_size.MipCount()
|
||||
: 1u;
|
||||
if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY) {
|
||||
if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
|
||||
desc.usage = TextureUsage::kRenderTarget;
|
||||
}
|
||||
return desc;
|
||||
|
||||
@ -196,12 +196,20 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build(
|
||||
// to the onscreen.
|
||||
deps[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
deps[0].dstSubpass = 0u;
|
||||
deps[0].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
|
||||
vk::PipelineStageFlagBits::eFragmentShader |
|
||||
vk::PipelineStageFlagBits::eTransfer;
|
||||
deps[0].srcAccessMask = vk::AccessFlagBits::eShaderRead |
|
||||
vk::AccessFlagBits::eTransferRead |
|
||||
vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
// If this render pass is performed using the onscreen attachment, then we
|
||||
// know that the previous stage does not include sampling - only color
|
||||
// attachment. According to various vulkan documentation, the correct access
|
||||
// flag bits for this stage with a queue submit in-between is `{}` as the
|
||||
// access is not otherwise expressable.
|
||||
if (is_swapchain_) {
|
||||
deps[0].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
|
||||
deps[0].srcAccessMask = {};
|
||||
} else {
|
||||
deps[0].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
|
||||
vk::PipelineStageFlagBits::eFragmentShader;
|
||||
deps[0].srcAccessMask = vk::AccessFlagBits::eShaderRead |
|
||||
vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
}
|
||||
deps[0].dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
|
||||
deps[0].dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
deps[0].dependencyFlags = kSelfDependencyFlags;
|
||||
@ -217,22 +225,23 @@ vk::UniqueRenderPass RenderPassBuilderVK::Build(
|
||||
deps[1].dependencyFlags = kSelfDependencyFlags;
|
||||
|
||||
// Outgoing dependency. The resolve step or color attachment must complete
|
||||
// before we can sample from the image, or use it as a blit src.
|
||||
// before we can sample from the image. This dependency is ignored for the
|
||||
// onscreen as we will already insert a barrier before presenting the
|
||||
// swapchain.
|
||||
deps[2].srcSubpass = 0u; // first subpass
|
||||
deps[2].dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
deps[2].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
|
||||
deps[2].srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
deps[2].dstStageMask = vk::PipelineStageFlagBits::eFragmentShader |
|
||||
vk::PipelineStageFlagBits::eTransfer;
|
||||
deps[2].dstAccessMask =
|
||||
vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferRead;
|
||||
deps[2].dstStageMask = vk::PipelineStageFlagBits::eFragmentShader;
|
||||
deps[2].dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||
deps[2].dependencyFlags = kSelfDependencyFlags;
|
||||
|
||||
vk::RenderPassCreateInfo render_pass_desc;
|
||||
render_pass_desc.setPAttachments(attachments.data());
|
||||
render_pass_desc.setAttachmentCount(attachments_index);
|
||||
render_pass_desc.setSubpasses(subpass0);
|
||||
render_pass_desc.setDependencies(deps);
|
||||
render_pass_desc.setPDependencies(deps);
|
||||
render_pass_desc.setDependencyCount(3);
|
||||
|
||||
auto [result, pass] = device.createRenderPassUnique(render_pass_desc);
|
||||
if (result != vk::Result::eSuccess) {
|
||||
@ -272,6 +281,10 @@ void InsertBarrierForInputAttachmentRead(const vk::CommandBuffer& buffer,
|
||||
);
|
||||
}
|
||||
|
||||
void RenderPassBuilderVK::SetSwapchain(bool value) {
|
||||
is_swapchain_ = value;
|
||||
}
|
||||
|
||||
const std::map<size_t, vk::AttachmentDescription>&
|
||||
RenderPassBuilderVK::GetColorAttachments() const {
|
||||
return colors_;
|
||||
|
||||
@ -28,6 +28,10 @@ class RenderPassBuilderVK {
|
||||
|
||||
RenderPassBuilderVK& operator=(const RenderPassBuilderVK&) = delete;
|
||||
|
||||
/// Whether this builder should configure barriers for the onscreen render
|
||||
/// pass.
|
||||
void SetSwapchain(bool value);
|
||||
|
||||
RenderPassBuilderVK& SetColorAttachment(
|
||||
size_t index,
|
||||
PixelFormat format,
|
||||
@ -66,6 +70,7 @@ class RenderPassBuilderVK {
|
||||
std::optional<vk::AttachmentDescription> GetColor0Resolve() const;
|
||||
|
||||
private:
|
||||
bool is_swapchain_ = false;
|
||||
std::optional<vk::AttachmentDescription> color0_;
|
||||
std::optional<vk::AttachmentDescription> color0_resolve_;
|
||||
std::optional<vk::AttachmentDescription> depth_stencil_;
|
||||
|
||||
@ -81,6 +81,7 @@ SharedHandleVK<vk::RenderPass> RenderPassVK::CreateVKRenderPass(
|
||||
const std::shared_ptr<CommandBufferVK>& command_buffer,
|
||||
bool is_swapchain) const {
|
||||
RenderPassBuilderVK builder;
|
||||
builder.SetSwapchain(is_swapchain);
|
||||
|
||||
render_target_.IterateAllColorAttachments([&](size_t bind_point,
|
||||
const ColorAttachment&
|
||||
|
||||
@ -186,10 +186,9 @@ KHRSwapchainImplVK::KHRSwapchainImplVK(const std::shared_ptr<Context>& context,
|
||||
: surface_caps.maxImageCount // max zero means no limit
|
||||
);
|
||||
swapchain_info.imageArrayLayers = 1u;
|
||||
// Swapchain images are primarily used as color attachments (via resolve),
|
||||
// blit targets, or input attachments.
|
||||
// Swapchain images are primarily used as color attachments (via resolve) or
|
||||
// input attachments.
|
||||
swapchain_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment |
|
||||
vk::ImageUsageFlagBits::eTransferDst |
|
||||
vk::ImageUsageFlagBits::eInputAttachment;
|
||||
swapchain_info.preTransform = vk::SurfaceTransformFlagBitsKHR::eIdentity;
|
||||
swapchain_info.compositeAlpha = composite.value();
|
||||
|
||||
@ -19,13 +19,11 @@ std::shared_ptr<YUVConversionVK> TextureSourceVK::GetYUVConversion() const {
|
||||
}
|
||||
|
||||
vk::ImageLayout TextureSourceVK::GetLayout() const {
|
||||
ReaderLock lock(layout_mutex_);
|
||||
return layout_;
|
||||
}
|
||||
|
||||
vk::ImageLayout TextureSourceVK::SetLayoutWithoutEncoding(
|
||||
vk::ImageLayout layout) const {
|
||||
WriterLock lock(layout_mutex_);
|
||||
const auto old_layout = layout_;
|
||||
layout_ = layout;
|
||||
return old_layout;
|
||||
@ -33,10 +31,6 @@ vk::ImageLayout TextureSourceVK::SetLayoutWithoutEncoding(
|
||||
|
||||
fml::Status TextureSourceVK::SetLayout(const BarrierVK& barrier) const {
|
||||
const auto old_layout = SetLayoutWithoutEncoding(barrier.new_layout);
|
||||
if (barrier.new_layout == old_layout) {
|
||||
return {};
|
||||
}
|
||||
|
||||
vk::ImageMemoryBarrier image_barrier;
|
||||
image_barrier.srcAccessMask = barrier.src_access;
|
||||
image_barrier.dstAccessMask = barrier.dst_access;
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_TEXTURE_SOURCE_VK_H_
|
||||
|
||||
#include "flutter/fml/status.h"
|
||||
#include "impeller/base/thread.h"
|
||||
#include "impeller/core/texture_descriptor.h"
|
||||
#include "impeller/renderer/backend/vulkan/barrier_vk.h"
|
||||
#include "impeller/renderer/backend/vulkan/formats_vk.h"
|
||||
@ -159,9 +158,7 @@ class TextureSourceVK {
|
||||
private:
|
||||
SharedHandleVK<vk::Framebuffer> framebuffer_;
|
||||
SharedHandleVK<vk::RenderPass> render_pass_;
|
||||
mutable RWMutex layout_mutex_;
|
||||
mutable vk::ImageLayout layout_ IPLR_GUARDED_BY(layout_mutex_) =
|
||||
vk::ImageLayout::eUndefined;
|
||||
mutable vk::ImageLayout layout_ = vk::ImageLayout::eUndefined;
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user