Переглянути джерело

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()`.
Jelle Raaijmakers 3 роки тому
батько
коміт
421a80bf43

+ 19 - 14
Userland/Libraries/LibSoftGPU/Device.cpp

@@ -431,8 +431,13 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera
             set_quad_attributes(quad);
             shade_fragments(quad);
 
-            if (m_options.enable_alpha_test && m_options.alpha_test_func != GPU::AlphaTestFunction::Always && !test_alpha(quad))
-                continue;
+            // Alpha testing
+            if (m_options.enable_alpha_test) {
+                test_alpha(quad);
+                coverage_bits = maskbits(quad.mask);
+                if (coverage_bits == 0)
+                    continue;
+            }
 
             // Write to depth buffer
             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);
 }
 
-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 ref_value = expand4(m_options.alpha_test_ref_value);
 
     switch (m_options.alpha_test_func) {
-    case GPU::AlphaTestFunction::Less:
-        quad.mask &= alpha < ref_value;
+    case GPU::AlphaTestFunction::Always:
+        quad.mask &= expand4(~0);
         break;
     case GPU::AlphaTestFunction::Equal:
         quad.mask &= alpha == ref_value;
         break;
-    case GPU::AlphaTestFunction::LessOrEqual:
-        quad.mask &= alpha <= ref_value;
-        break;
     case GPU::AlphaTestFunction::Greater:
         quad.mask &= alpha > ref_value;
         break;
-    case GPU::AlphaTestFunction::NotEqual:
-        quad.mask &= alpha != ref_value;
-        break;
     case GPU::AlphaTestFunction::GreaterOrEqual:
         quad.mask &= alpha >= ref_value;
         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::Always:
     default:
         VERIFY_NOT_REACHED();
     }
-
-    return any(quad.mask);
 }
 
 void Device::resize(Gfx::IntSize const& size)

+ 1 - 1
Userland/Libraries/LibSoftGPU/Device.h

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