Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions impeller/core/formats.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,13 @@ struct ColorAttachmentDescriptor {
BlendOperation alpha_blend_op = BlendOperation::kAdd;
BlendFactor dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;

/// @brief If the advanced blend override is specified, then all other fields
/// are ignored.
///
/// This is only valid if the platform has native support for advanced
/// blend modes.
std::optional<BlendMode> advanced_blend_override = std::nullopt;

std::underlying_type_t<ColorWriteMask> write_mask =
static_cast<uint64_t>(ColorWriteMask::kAll);

Expand All @@ -514,14 +521,17 @@ struct ColorAttachmentDescriptor {
src_alpha_blend_factor == o.src_alpha_blend_factor && //
alpha_blend_op == o.alpha_blend_op && //
dst_alpha_blend_factor == o.dst_alpha_blend_factor && //
write_mask == o.write_mask;
write_mask == o.write_mask && //
advanced_blend_override.value_or(BlendMode::kClear) ==
o.advanced_blend_override.value_or(BlendMode::kClear);
}

constexpr size_t Hash() const {
return fml::HashCombine(format, blending_enabled, src_color_blend_factor,
color_blend_op, dst_color_blend_factor,
src_alpha_blend_factor, alpha_blend_op,
dst_alpha_blend_factor, write_mask);
return fml::HashCombine(
format, blending_enabled, src_color_blend_factor, color_blend_op,
dst_color_blend_factor, src_alpha_blend_factor, alpha_blend_op,
dst_alpha_blend_factor, write_mask,
advanced_blend_override.value_or(BlendMode::kClear));
}
};

Expand Down
16 changes: 7 additions & 9 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "impeller/base/strings.h"
#include "impeller/core/formats.h"
#include "impeller/entity/contents/framebuffer_blend_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/render_target_cache.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/pipeline_descriptor.h"
Expand All @@ -23,14 +22,8 @@ namespace impeller {
void ContentContextOptions::ApplyToPipelineDescriptor(
PipelineDescriptor& desc) const {
auto pipeline_blend = blend_mode;
if (blend_mode > Entity::kLastPipelineBlendMode) {
VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
<< " as a pipeline blend.";
pipeline_blend = BlendMode::kSourceOver;
}

desc.SetSampleCount(sample_count);

ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
color0.format = color_attachment_pixel_format;
color0.alpha_blend_op = BlendOperation::kAdd;
Expand Down Expand Up @@ -132,7 +125,13 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
color0.src_color_blend_factor = BlendFactor::kZero;
break;
default:
FML_UNREACHABLE();
// This is an advanced blend, set the override.
color0.advanced_blend_override = blend_mode;
color0.dst_alpha_blend_factor = BlendFactor::kOne;
color0.dst_color_blend_factor = BlendFactor::kOne;
color0.src_alpha_blend_factor = BlendFactor::kOne;
color0.src_color_blend_factor = BlendFactor::kOne;
break;
}
desc.SetColorAttachmentDescriptor(0u, color0);

Expand All @@ -149,7 +148,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
}

desc.SetPrimitiveType(primitive_type);

desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
}

Expand Down
1 change: 0 additions & 1 deletion impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "flutter/fml/build_config.h"
#include "flutter/fml/hash_combine.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"
#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/entity/entity.h"
Expand Down
15 changes: 10 additions & 5 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,12 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
}

uint32_t EntityPass::GetTotalPassReads(ContentContext& renderer) const {
return renderer.GetDeviceCapabilities().SupportsFramebufferFetch()
? backdrop_filter_reads_from_pass_texture_
: backdrop_filter_reads_from_pass_texture_ +
advanced_blend_reads_from_pass_texture_;
if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch() ||
renderer.GetDeviceCapabilities().SupportsNativeAdvancedBlends()) {
return backdrop_filter_reads_from_pass_texture_;
}
return backdrop_filter_reads_from_pass_texture_ +
advanced_blend_reads_from_pass_texture_;
}

bool EntityPass::Render(ContentContext& renderer,
Expand Down Expand Up @@ -915,7 +917,10 @@ bool EntityPass::OnRender(
///

if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
if (renderer.GetDeviceCapabilities().SupportsNativeAdvancedBlends()) {
// If native support for advanced blends is present, pass the entity
// through as-is.
} else if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
auto src_contents = result.entity.GetContents();
auto contents = std::make_shared<FramebufferBlendContents>();
contents->SetChildContents(src_contents);
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ bool CapabilitiesGLES::SupportsDeviceTransientTextures() const {
return false;
}

bool CapabilitiesGLES::SupportsNativeAdvancedBlends() const {
return false;
}

PixelFormat CapabilitiesGLES::GetDefaultColorFormat() const {
return PixelFormat::kR8G8B8A8UNormInt;
}
Expand Down
3 changes: 3 additions & 0 deletions impeller/renderer/backend/gles/capabilities_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class CapabilitiesGLES final
// |Capabilities|
bool SupportsDeviceTransientTextures() const override;

// |Capabilities|
bool SupportsNativeAdvancedBlends() const override;

// |Capabilities|
PixelFormat GetDefaultColorFormat() const override;

Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/proc_table_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ struct GLProc {
PROC(BindTexture); \
PROC(BlendEquationSeparate); \
PROC(BlendFuncSeparate); \
PROC(BlendEquation); \
PROC(BufferData); \
PROC(CheckFramebufferStatus); \
PROC(Clear); \
Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/gles/render_pass_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/geometry/color.h"
#include "impeller/renderer/backend/gles/context_gles.h"
#include "impeller/renderer/backend/gles/device_buffer_gles.h"
#include "impeller/renderer/backend/gles/formats_gles.h"
Expand Down Expand Up @@ -44,6 +45,7 @@ void RenderPassGLES::OnSetLabel(std::string label) {
void ConfigureBlending(const ProcTableGLES& gl,
const ColorAttachmentDescriptor* color) {
if (color->blending_enabled) {
FML_DCHECK(!color->advanced_blend_override.has_value());
gl.Enable(GL_BLEND);
gl.BlendFuncSeparate(
ToBlendFactor(color->src_color_blend_factor), // src color
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/metal/context_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static bool DeviceSupportsComputeSubgroups(id<MTLDevice> device) {
.SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device))
.SetSupportsReadFromResolve(true)
.SetSupportsDeviceTransientTextures(true)
.SetSupportsNativeAdvancedBlends(false)
.Build();
}

Expand Down
3 changes: 3 additions & 0 deletions impeller/renderer/backend/vulkan/allocator_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(
bool supports_memoryless_textures,
bool supports_framebuffer_fetch) {
vk::ImageUsageFlags vk_usage;
bool supports_advanced_blends = true;

switch (mode) {
case StorageMode::kHostVisible:
Expand All @@ -192,6 +193,8 @@ static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(
}
if (supports_framebuffer_fetch) {
vk_usage |= vk::ImageUsageFlagBits::eInputAttachment;
} else if (supports_advanced_blends) {
vk_usage |= vk::ImageUsageFlagBits::eInputAttachment;
}
}

Expand Down
16 changes: 13 additions & 3 deletions impeller/renderer/backend/vulkan/capabilities_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ static const char* GetDeviceExtensionName(OptionalDeviceExtensionVK ext) {
switch (ext) {
case OptionalDeviceExtensionVK::kEXTPipelineCreationFeedback:
return VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME;
case OptionalDeviceExtensionVK::kEXTBlendOperationAdvanced:
return VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME;
case OptionalDeviceExtensionVK::kARMRasterizationOrderAttachmentAccess:
return VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME;
case OptionalDeviceExtensionVK::kEXTRasterizationOrderAttachmentAccess:
Expand Down Expand Up @@ -363,9 +365,9 @@ bool CapabilitiesVK::SetPhysicalDevice(const vk::PhysicalDevice& device) {

device_properties_ = device.getProperties();

auto physical_properties_2 =
device.getProperties2<vk::PhysicalDeviceProperties2,
vk::PhysicalDeviceSubgroupProperties>();
auto physical_properties_2 = device.getProperties2<
vk::PhysicalDeviceProperties2, vk::PhysicalDeviceSubgroupProperties,
vk::PhysicalDeviceBlendOperationAdvancedPropertiesEXT>();

// Currently shaders only want access to arithmetic subgroup features.
// If that changes this needs to get updated, and so does Metal (which right
Expand Down Expand Up @@ -407,6 +409,10 @@ bool CapabilitiesVK::SetPhysicalDevice(const vk::PhysicalDevice& device) {
}

{
supports_native_advanced_blends_ =
optional_device_extensions_.find(
OptionalDeviceExtensionVK::kEXTBlendOperationAdvanced) !=
optional_device_extensions_.end();
supports_framebuffer_fetch_ =
(optional_device_extensions_.find(
OptionalDeviceExtensionVK::
Expand Down Expand Up @@ -472,6 +478,10 @@ bool CapabilitiesVK::SupportsDecalSamplerAddressMode() const {
return true;
}

bool CapabilitiesVK::SupportsNativeAdvancedBlends() const {
return supports_native_advanced_blends_;
}

// |Capabilities|
bool CapabilitiesVK::SupportsDeviceTransientTextures() const {
return supports_device_transient_textures_;
Expand Down
6 changes: 6 additions & 0 deletions impeller/renderer/backend/vulkan/capabilities_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class ContextVK;
enum class OptionalDeviceExtensionVK : uint32_t {
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_pipeline_creation_feedback.html
kEXTPipelineCreationFeedback,
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_blend_operation_advanced.html
kEXTBlendOperationAdvanced,
kARMRasterizationOrderAttachmentAccess,
kEXTRasterizationOrderAttachmentAccess,
kLast,
Expand Down Expand Up @@ -92,6 +94,9 @@ class CapabilitiesVK final : public Capabilities,
// |Capabilities|
bool SupportsDeviceTransientTextures() const override;

// |Capabilities|
bool SupportsNativeAdvancedBlends() const override;

// |Capabilities|
PixelFormat GetDefaultColorFormat() const override;

Expand All @@ -111,6 +116,7 @@ class CapabilitiesVK final : public Capabilities,
vk::PhysicalDeviceProperties device_properties_;
bool supports_compute_subgroups_ = false;
bool supports_device_transient_textures_ = false;
bool supports_native_advanced_blends_ = false;
bool supports_framebuffer_fetch_ = false;
bool is_valid_ = false;

Expand Down
58 changes: 54 additions & 4 deletions impeller/renderer/backend/vulkan/formats_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,45 @@ constexpr vk::BlendOp ToVKBlendOp(BlendOperation op) {
FML_UNREACHABLE();
}

constexpr vk::BlendOp ToAdvancedVKBlendOp(BlendMode blend_mode) {
switch (blend_mode) {
case BlendMode::kScreen:
return vk::BlendOp::eScreenEXT;
case BlendMode::kOverlay:
return vk::BlendOp::eOverlayEXT;
case BlendMode::kDarken:
return vk::BlendOp::eDarkenEXT;
case BlendMode::kLighten:
return vk::BlendOp::eLightenEXT;
case BlendMode::kColorDodge:
return vk::BlendOp::eColordodgeEXT;
case BlendMode::kColorBurn:
return vk::BlendOp::eColorburnEXT;
case BlendMode::kHardLight:
return vk::BlendOp::eHardlightEXT;
case BlendMode::kSoftLight:
return vk::BlendOp::eSoftlightEXT;
case BlendMode::kDifference:
return vk::BlendOp::eDifferenceEXT;
case BlendMode::kExclusion:
return vk::BlendOp::eExclusionEXT;
case BlendMode::kMultiply:
return vk::BlendOp::eMultiplyEXT;
case BlendMode::kHue:
return vk::BlendOp::eHslHueEXT;
case BlendMode::kSaturation:
return vk::BlendOp::eHslSaturationEXT;
case BlendMode::kColor:
return vk::BlendOp::eHslColorEXT;
case BlendMode::kLuminosity:
return vk::BlendOp::eHslLuminosityEXT;
break;
default:
break;
}
FML_UNREACHABLE();
}

constexpr vk::ColorComponentFlags ToVKColorComponentFlags(
std::underlying_type_t<ColorWriteMask> type) {
using UnderlyingType = decltype(type);
Expand Down Expand Up @@ -105,13 +144,24 @@ ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor& desc) {
res.setBlendEnable(desc.blending_enabled);

res.setSrcColorBlendFactor(ToVKBlendFactor(desc.src_color_blend_factor));
res.setColorBlendOp(ToVKBlendOp(desc.color_blend_op));
res.setDstColorBlendFactor(ToVKBlendFactor(desc.dst_color_blend_factor));
if (desc.advanced_blend_override.has_value()) {
res.setColorBlendOp(
ToAdvancedVKBlendOp(desc.advanced_blend_override.value()));
} else {
res.setColorBlendOp(ToVKBlendOp(desc.color_blend_op));
}

res.setDstColorBlendFactor(ToVKBlendFactor(desc.dst_color_blend_factor));
res.setSrcAlphaBlendFactor(ToVKBlendFactor(desc.src_alpha_blend_factor));
res.setAlphaBlendOp(ToVKBlendOp(desc.alpha_blend_op));
res.setDstAlphaBlendFactor(ToVKBlendFactor(desc.dst_alpha_blend_factor));

if (desc.advanced_blend_override.has_value()) {
res.setAlphaBlendOp(
ToAdvancedVKBlendOp(desc.advanced_blend_override.value()));
} else {
res.setAlphaBlendOp(ToVKBlendOp(desc.alpha_blend_op));
}

res.setDstAlphaBlendFactor(ToVKBlendFactor(desc.dst_alpha_blend_factor));
res.setColorWriteMask(ToVKColorComponentFlags(desc.write_mask));

return res;
Expand Down
28 changes: 28 additions & 0 deletions impeller/renderer/backend/vulkan/pipeline_library_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(
bool supports_framebuffer_fetch) {
std::vector<vk::AttachmentDescription> attachments;

bool supports_advanced_blend = true;
std::vector<vk::AttachmentReference> color_refs;
std::vector<vk::AttachmentReference> subpass_color_ref;
vk::AttachmentReference depth_stencil_ref = kUnusedAttachmentReference;
Expand Down Expand Up @@ -137,6 +138,24 @@ static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(
subpass_desc.setColorAttachments(color_refs);
subpass_desc.setPDepthStencilAttachment(&depth_stencil_ref);

// See
// https://github.com/google/angle/blob/46817856888e74d23169e79ac98064600fd00127/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp#L672-L693
if (supports_advanced_blend) {
vk::SubpassDependency subpass_dependency;
subpass_dependency.setSrcSubpass(0);
subpass_dependency.setDstSubpass(0);
subpass_dependency.dependencyFlags = vk::DependencyFlagBits::eByRegion;
subpass_dependency.srcStageMask =
vk::PipelineStageFlagBits::eColorAttachmentOutput;
subpass_dependency.srcAccessMask =
vk::AccessFlagBits::eColorAttachmentWrite;
subpass_dependency.dstStageMask =
vk::PipelineStageFlagBits::eColorAttachmentOutput;
subpass_dependency.dstAccessMask =
vk::AccessFlagBits::eColorAttachmentReadNoncoherentEXT;
subpass_dependencies.emplace_back(subpass_dependency);
}

vk::RenderPassCreateInfo render_pass_desc;
render_pass_desc.setAttachments(attachments);
render_pass_desc.setPSubpasses(&subpass_desc);
Expand Down Expand Up @@ -383,6 +402,15 @@ std::unique_ptr<PipelineVK> PipelineLibraryVK::CreatePipeline(
blend_state.setAttachments(attachment_blend_state);
pipeline_info.setPColorBlendState(&blend_state);

// vk::PipelineColorBlendAdvancedStateCreateInfoEXT state;
// if (desc.GetColorAttachmentDescriptors()
// .find(0u)
// ->second.advanced_blend_override.has_value()) {
// state.setBlendOverlap(vk::BlendOverlapEXT::eUncorrelated); // dunno
// state.setSrcPremultiplied(true); // double
// check state.setDstPremultiplied(true); blend_state.pNext = &state;
// }

std::shared_ptr<DeviceHolder> strong_device = device_holder_.lock();
if (!strong_device) {
return nullptr;
Expand Down
Loading