1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:57:47 +00:00

LibSoftGPU: Update coverage bits after alpha testing

Also skip the test for the `::Always` alpha test function in the hot
loop. This test function is very unlikely to be set, so leave that up
to `::test_alpha()`.
This commit is contained in:
Jelle Raaijmakers 2022-05-15 00:02:30 +02:00 committed by Andreas Kling
parent 1a338844fa
commit 421a80bf43
2 changed files with 20 additions and 15 deletions

View file

@ -431,8 +431,13 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera
set_quad_attributes(quad); set_quad_attributes(quad);
shade_fragments(quad); shade_fragments(quad);
if (m_options.enable_alpha_test && m_options.alpha_test_func != GPU::AlphaTestFunction::Always && !test_alpha(quad)) // Alpha testing
continue; if (m_options.enable_alpha_test) {
test_alpha(quad);
coverage_bits = maskbits(quad.mask);
if (coverage_bits == 0)
continue;
}
// Write to depth buffer // Write to depth buffer
if (m_options.enable_depth_test && m_options.enable_depth_write) if (m_options.enable_depth_test && m_options.enable_depth_write)
@ -1269,37 +1274,37 @@ ALWAYS_INLINE void Device::shade_fragments(PixelQuad& quad)
quad.out_color.set_w(quad.out_color.w() * quad.coverage); quad.out_color.set_w(quad.out_color.w() * quad.coverage);
} }
ALWAYS_INLINE bool Device::test_alpha(PixelQuad& quad) ALWAYS_INLINE void Device::test_alpha(PixelQuad& quad)
{ {
auto const alpha = quad.out_color.w(); auto const alpha = quad.out_color.w();
auto const ref_value = expand4(m_options.alpha_test_ref_value); auto const ref_value = expand4(m_options.alpha_test_ref_value);
switch (m_options.alpha_test_func) { switch (m_options.alpha_test_func) {
case GPU::AlphaTestFunction::Less: case GPU::AlphaTestFunction::Always:
quad.mask &= alpha < ref_value; quad.mask &= expand4(~0);
break; break;
case GPU::AlphaTestFunction::Equal: case GPU::AlphaTestFunction::Equal:
quad.mask &= alpha == ref_value; quad.mask &= alpha == ref_value;
break; break;
case GPU::AlphaTestFunction::LessOrEqual:
quad.mask &= alpha <= ref_value;
break;
case GPU::AlphaTestFunction::Greater: case GPU::AlphaTestFunction::Greater:
quad.mask &= alpha > ref_value; quad.mask &= alpha > ref_value;
break; break;
case GPU::AlphaTestFunction::NotEqual:
quad.mask &= alpha != ref_value;
break;
case GPU::AlphaTestFunction::GreaterOrEqual: case GPU::AlphaTestFunction::GreaterOrEqual:
quad.mask &= alpha >= ref_value; quad.mask &= alpha >= ref_value;
break; break;
case GPU::AlphaTestFunction::Less:
quad.mask &= alpha < ref_value;
break;
case GPU::AlphaTestFunction::LessOrEqual:
quad.mask &= alpha <= ref_value;
break;
case GPU::AlphaTestFunction::NotEqual:
quad.mask &= alpha != ref_value;
break;
case GPU::AlphaTestFunction::Never: case GPU::AlphaTestFunction::Never:
case GPU::AlphaTestFunction::Always:
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
return any(quad.mask);
} }
void Device::resize(Gfx::IntSize const& size) void Device::resize(Gfx::IntSize const& size)

View file

@ -93,7 +93,7 @@ private:
void rasterize_triangle(Triangle&); void rasterize_triangle(Triangle&);
void setup_blend_factors(); void setup_blend_factors();
void shade_fragments(PixelQuad&); void shade_fragments(PixelQuad&);
bool test_alpha(PixelQuad&); void test_alpha(PixelQuad&);
RefPtr<FrameBuffer<GPU::ColorType, GPU::DepthType, GPU::StencilType>> m_frame_buffer {}; RefPtr<FrameBuffer<GPU::ColorType, GPU::DepthType, GPU::StencilType>> m_frame_buffer {};
GPU::RasterizerOptions m_options; GPU::RasterizerOptions m_options;