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; }; }