diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2022-09-17 17:16:31 +0200 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-17 22:39:09 -0700 |
commit | bb28492af07ddf0dce3cd6d6595232d9473d8973 (patch) | |
tree | 80e732ca7574f8e8c5f9dccb2db7e4f286f9a91d /Userland/Libraries/LibSoftGPU | |
parent | c008b6ce18d6eb56105c462a7ab6d8f0b7d1cd90 (diff) | |
download | serenity-bb28492af07ddf0dce3cd6d6595232d9473d8973.zip |
LibSoftGPU: Make output in PixelQuad generic
Same as with inputs, we define outputs as a generic array of floats.
This can later be expanded to accomodate multiple render targets or
vertex attributes in the case of a vertex shader.
Diffstat (limited to 'Userland/Libraries/LibSoftGPU')
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Config.h | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Device.cpp | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/PixelQuad.h | 21 |
3 files changed, 40 insertions, 10 deletions
diff --git a/Userland/Libraries/LibSoftGPU/Config.h b/Userland/Libraries/LibSoftGPU/Config.h index a8b6d1fca3..72ea23c154 100644 --- a/Userland/Libraries/LibSoftGPU/Config.h +++ b/Userland/Libraries/LibSoftGPU/Config.h @@ -32,6 +32,13 @@ static_assert(NUM_SHADER_INPUTS >= 4 + GPU::NUM_TEXTURE_UNITS * 4); static constexpr int SHADER_INPUT_VERTEX_COLOR = 0; static constexpr int SHADER_INPUT_FIRST_TEXCOORD = 4; +static constexpr int NUM_SHADER_OUTPUTS = 4; + +// Verify that we have enough outputs to hold the fragment's color +static_assert(NUM_SHADER_OUTPUTS >= 4); + +static constexpr int SHADER_OUTPUT_FIRST_COLOR = 0; + // See: https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_edge_color_problem // FIXME: make this dynamically configurable through ConfigServer static constexpr bool CLAMP_DEPRECATED_BEHAVIOR = false; diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index 98b5ef26e5..e971ad01a7 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -186,7 +186,7 @@ void Device::setup_blend_factors() ALWAYS_INLINE static void test_alpha(PixelQuad& quad, GPU::AlphaTestFunction alpha_test_function, f32x4 const& reference_value) { - auto const alpha = quad.out_color.w(); + auto const alpha = quad.get_output_float(SHADER_OUTPUT_FIRST_COLOR + 3); switch (alpha_test_function) { case GPU::AlphaTestFunction::Always: @@ -494,11 +494,13 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera if (m_options.enable_blending || m_options.color_mask != 0xffffffff) dst_u32 = load4_masked(color_ptrs[0], color_ptrs[1], color_ptrs[2], color_ptrs[3], quad.mask); + auto out_color = quad.get_output_vector4(SHADER_OUTPUT_FIRST_COLOR); + if (m_options.enable_blending) { INCREASE_STATISTICS_COUNTER(g_num_pixels_blended, maskcount(quad.mask)); // Blend color values from pixel_staging into color_buffer - auto const& src = quad.out_color; + auto const& src = out_color; auto dst = to_vec4(dst_u32); auto src_factor = expand4(m_alpha_blend_factors.src_constant) @@ -513,10 +515,10 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera + dst * m_alpha_blend_factors.dst_factor_dst_color + Vector4<f32x4> { 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; + out_color = src * src_factor + dst * dst_factor; } - auto const argb32_color = to_argb32(quad.out_color); + auto const argb32_color = to_argb32(out_color); if (m_options.color_mask == 0xffffffff) store4_masked(argb32_color, color_ptrs[0], color_ptrs[1], color_ptrs[2], color_ptrs[3], quad.mask); else @@ -1331,7 +1333,6 @@ ALWAYS_INLINE void Device::shade_fragments(PixelQuad& quad) break; } } - quad.out_color = current_color; // Calculate fog // Math from here: https://opengl-notes.readthedocs.io/en/latest/topics/texturing/aliasing.html @@ -1358,13 +1359,16 @@ ALWAYS_INLINE void Device::shade_fragments(PixelQuad& quad) // Mix texel's RGB with fog's RBG - leave alpha alone auto fog_color = expand4(m_options.fog_color); - quad.out_color.set_x(mix(fog_color.x(), quad.out_color.x(), factor)); - quad.out_color.set_y(mix(fog_color.y(), quad.out_color.y(), factor)); - quad.out_color.set_z(mix(fog_color.z(), quad.out_color.z(), factor)); + current_color.set_x(mix(fog_color.x(), current_color.x(), factor)); + current_color.set_y(mix(fog_color.y(), current_color.y(), factor)); + current_color.set_z(mix(fog_color.z(), current_color.z(), factor)); } + quad.set_output(SHADER_OUTPUT_FIRST_COLOR, current_color.x()); + quad.set_output(SHADER_OUTPUT_FIRST_COLOR + 1, current_color.y()); + quad.set_output(SHADER_OUTPUT_FIRST_COLOR + 2, current_color.z()); // Multiply coverage with the fragment's alpha to obtain the final alpha value - quad.out_color.set_w(quad.out_color.w() * quad.coverage); + quad.set_output(SHADER_OUTPUT_FIRST_COLOR + 3, current_color.w() * quad.coverage); } void Device::resize(Gfx::IntSize size) diff --git a/Userland/Libraries/LibSoftGPU/PixelQuad.h b/Userland/Libraries/LibSoftGPU/PixelQuad.h index 643ea4a07e..d318093844 100644 --- a/Userland/Libraries/LibSoftGPU/PixelQuad.h +++ b/Userland/Libraries/LibSoftGPU/PixelQuad.h @@ -40,11 +40,30 @@ struct PixelQuad final { inputs[index + 3]); } + void set_output(int index, f32x4 value) { outputs[index] = value; } + f32x4 get_output_float(int index) const { return outputs[index]; } + + void set_output(int index, Vector4<f32x4> const& value) + { + outputs[index] = value.x(); + outputs[index + 1] = value.y(); + outputs[index + 2] = value.z(); + outputs[index + 3] = value.w(); + } + Vector4<f32x4> get_output_vector4(int index) const + { + return Vector4<f32x4>( + outputs[index], + outputs[index + 1], + outputs[index + 2], + outputs[index + 3]); + } + Vector2<i32x4> screen_coordinates; Vector3<f32x4> barycentrics; f32x4 depth; Array<f32x4, NUM_SHADER_INPUTS> inputs; - Vector4<f32x4> out_color; + Array<f32x4, NUM_SHADER_OUTPUTS> outputs; f32x4 fog_depth; i32x4 mask; f32x4 coverage { expand4(1.f) }; |