From 68a1727547c1bfeb87b6ef5e4fb796ae7782d213 Mon Sep 17 00:00:00 2001 From: Stephan Unverwerth Date: Thu, 6 Jan 2022 18:47:35 +0100 Subject: [PATCH] LibSoftGPU: Move alpha blend factor setup out of triangle rasterization Since the alpha blend configuration should not change between most calls of draw_primitives it makes no sense to reinitialize the blend factors for every rasterized triangle. The alpha blend factors are now set up whenever the device config changes. The blend factors are stored in struct AlphaBlendFactors. --- .../Libraries/LibSoftGPU/AlphaBlendFactors.h | 27 ++++ Userland/Libraries/LibSoftGPU/Device.cpp | 138 ++++++++++-------- Userland/Libraries/LibSoftGPU/Device.h | 3 + 3 files changed, 107 insertions(+), 61 deletions(-) create mode 100644 Userland/Libraries/LibSoftGPU/AlphaBlendFactors.h diff --git a/Userland/Libraries/LibSoftGPU/AlphaBlendFactors.h b/Userland/Libraries/LibSoftGPU/AlphaBlendFactors.h new file mode 100644 index 0000000000..623f3db33b --- /dev/null +++ b/Userland/Libraries/LibSoftGPU/AlphaBlendFactors.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021, Stephan Unverwerth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace SoftGPU { + +struct AlphaBlendFactors final { + FloatVector4 src_constant {}; + float src_factor_src_alpha = 0; + float src_factor_dst_alpha = 0; + float src_factor_src_color = 0; + float src_factor_dst_color = 0; + + FloatVector4 dst_constant {}; + float dst_factor_src_alpha = 0; + float dst_factor_dst_alpha = 0; + float dst_factor_src_color = 0; + float dst_factor_dst_color = 0; +}; + +} diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index fb74d6d922..22572d88a1 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -85,51 +85,94 @@ static Gfx::IntRect scissor_box_to_window_coordinates(Gfx::IntRect const& scisso return scissor_box.translated(0, window_rect.height() - 2 * scissor_box.y() - scissor_box.height()); } -static constexpr void setup_blend_factors(BlendFactor mode, FloatVector4& constant, float& src_alpha, float& dst_alpha, float& src_color, float& dst_color) +void Device::setup_blend_factors() { - constant = { 0.0f, 0.0f, 0.0f, 0.0f }; - src_alpha = 0; - dst_alpha = 0; - src_color = 0; - dst_color = 0; + m_alpha_blend_factors.src_constant = { 0.0f, 0.0f, 0.0f, 0.0f }; + m_alpha_blend_factors.src_factor_src_alpha = 0; + m_alpha_blend_factors.src_factor_dst_alpha = 0; + m_alpha_blend_factors.src_factor_src_color = 0; + m_alpha_blend_factors.src_factor_dst_color = 0; - switch (mode) { + switch (m_options.blend_source_factor) { case BlendFactor::Zero: break; case BlendFactor::One: - constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.src_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; break; case BlendFactor::SrcColor: - src_color = 1; + m_alpha_blend_factors.src_factor_src_color = 1; break; case BlendFactor::OneMinusSrcColor: - constant = { 1.0f, 1.0f, 1.0f, 1.0f }; - src_color = -1; + m_alpha_blend_factors.src_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.src_factor_src_color = -1; break; case BlendFactor::SrcAlpha: - src_alpha = 1; + m_alpha_blend_factors.src_factor_src_alpha = 1; break; case BlendFactor::OneMinusSrcAlpha: - constant = { 1.0f, 1.0f, 1.0f, 1.0f }; - src_alpha = -1; + m_alpha_blend_factors.src_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.src_factor_src_alpha = -1; break; case BlendFactor::DstAlpha: - dst_alpha = 1; + m_alpha_blend_factors.src_factor_dst_alpha = 1; break; case BlendFactor::OneMinusDstAlpha: - constant = { 1.0f, 1.0f, 1.0f, 1.0f }; - dst_alpha = -1; + m_alpha_blend_factors.src_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.src_factor_dst_alpha = -1; break; case BlendFactor::DstColor: - dst_color = 1; + m_alpha_blend_factors.src_factor_dst_color = 1; break; case BlendFactor::OneMinusDstColor: - constant = { 1.0f, 1.0f, 1.0f, 1.0f }; - dst_color = -1; + m_alpha_blend_factors.src_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.src_factor_dst_color = -1; break; case BlendFactor::SrcAlphaSaturate: - // FIXME: How do we implement this? + default: + VERIFY_NOT_REACHED(); + } + + m_alpha_blend_factors.dst_constant = { 0.0f, 0.0f, 0.0f, 0.0f }; + m_alpha_blend_factors.dst_factor_src_alpha = 0; + m_alpha_blend_factors.dst_factor_dst_alpha = 0; + m_alpha_blend_factors.dst_factor_src_color = 0; + m_alpha_blend_factors.dst_factor_dst_color = 0; + + switch (m_options.blend_destination_factor) { + case BlendFactor::Zero: break; + case BlendFactor::One: + m_alpha_blend_factors.dst_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + break; + case BlendFactor::SrcColor: + m_alpha_blend_factors.dst_factor_src_color = 1; + break; + case BlendFactor::OneMinusSrcColor: + m_alpha_blend_factors.dst_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.dst_factor_src_color = -1; + break; + case BlendFactor::SrcAlpha: + m_alpha_blend_factors.dst_factor_src_alpha = 1; + break; + case BlendFactor::OneMinusSrcAlpha: + m_alpha_blend_factors.dst_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.dst_factor_src_alpha = -1; + break; + case BlendFactor::DstAlpha: + m_alpha_blend_factors.dst_factor_dst_alpha = 1; + break; + case BlendFactor::OneMinusDstAlpha: + m_alpha_blend_factors.dst_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.dst_factor_dst_alpha = -1; + break; + case BlendFactor::DstColor: + m_alpha_blend_factors.dst_factor_dst_color = 1; + break; + case BlendFactor::OneMinusDstColor: + m_alpha_blend_factors.dst_constant = { 1.0f, 1.0f, 1.0f, 1.0f }; + m_alpha_blend_factors.dst_factor_dst_color = -1; + break; + case BlendFactor::SrcAlphaSaturate: default: VERIFY_NOT_REACHED(); } @@ -166,36 +209,6 @@ void Device::rasterize_triangle(const Triangle& triangle) auto const one_over_area = 1.0f / area; - FloatVector4 src_constant {}; - float src_factor_src_alpha = 0; - float src_factor_dst_alpha = 0; - float src_factor_src_color = 0; - float src_factor_dst_color = 0; - - FloatVector4 dst_constant {}; - float dst_factor_src_alpha = 0; - float dst_factor_dst_alpha = 0; - float dst_factor_src_color = 0; - float dst_factor_dst_color = 0; - - if (m_options.enable_blending) { - setup_blend_factors( - m_options.blend_source_factor, - src_constant, - src_factor_src_alpha, - src_factor_dst_alpha, - src_factor_src_color, - src_factor_dst_color); - - setup_blend_factors( - m_options.blend_destination_factor, - dst_constant, - dst_factor_src_alpha, - dst_factor_dst_alpha, - dst_factor_src_color, - dst_factor_dst_color); - } - auto render_bounds = m_render_target->rect(); auto window_scissor_rect = scissor_box_to_window_coordinates(m_options.scissor_box, m_render_target->rect()); if (m_options.scissor_enabled) @@ -441,17 +454,17 @@ void Device::rasterize_triangle(const Triangle& triangle) Vector4 const& src = quad.out_color; auto dst = to_vec4(dst_u32); - auto src_factor = expand4(src_constant) - + src * src_factor_src_color - + Vector4 { src.w(), src.w(), src.w(), src.w() } * src_factor_src_alpha - + dst * src_factor_dst_color - + Vector4 { dst.w(), dst.w(), dst.w(), dst.w() } * src_factor_dst_alpha; + auto src_factor = expand4(m_alpha_blend_factors.src_constant) + + src * m_alpha_blend_factors.src_factor_src_color + + Vector4 { src.w(), src.w(), src.w(), src.w() } * m_alpha_blend_factors.src_factor_src_alpha + + dst * m_alpha_blend_factors.src_factor_dst_color + + Vector4 { dst.w(), dst.w(), dst.w(), dst.w() } * m_alpha_blend_factors.src_factor_dst_alpha; - auto dst_factor = expand4(dst_constant) - + src * dst_factor_src_color - + Vector4 { src.w(), src.w(), src.w(), src.w() } * dst_factor_src_alpha - + dst * dst_factor_dst_color - + Vector4 { dst.w(), dst.w(), dst.w(), dst.w() } * dst_factor_dst_alpha; + auto dst_factor = expand4(m_alpha_blend_factors.dst_constant) + + src * m_alpha_blend_factors.dst_factor_src_color + + Vector4 { src.w(), src.w(), src.w(), src.w() } * m_alpha_blend_factors.dst_factor_src_alpha + + dst * m_alpha_blend_factors.dst_factor_dst_color + + Vector4 { dst.w(), dst.w(), dst.w(), dst.w() } * m_alpha_blend_factors.dst_factor_dst_alpha; quad.out_color = src * src_factor + dst * dst_factor; } @@ -936,6 +949,9 @@ void Device::set_options(const RasterizerOptions& options) m_options = options; + if (m_options.enable_blending) + setup_blend_factors(); + // FIXME: Recreate or reinitialize render threads here when multithreading is being implemented } diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index bd821c1b31..63621689a0 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ private: void draw_statistics_overlay(Gfx::Bitmap&); void rasterize_triangle(const Triangle& triangle); + void setup_blend_factors(); void shade_fragments(PixelQuad&); private: @@ -107,6 +109,7 @@ private: Vector m_clipped_vertices; Array m_samplers; Vector m_enabled_texture_units; + AlphaBlendFactors m_alpha_blend_factors; }; }