summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSoftGPU
diff options
context:
space:
mode:
authorStephan Unverwerth <s.unverwerth@serenityos.org>2022-09-17 17:16:31 +0200
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-17 22:39:09 -0700
commitbb28492af07ddf0dce3cd6d6595232d9473d8973 (patch)
tree80e732ca7574f8e8c5f9dccb2db7e4f286f9a91d /Userland/Libraries/LibSoftGPU
parentc008b6ce18d6eb56105c462a7ab6d8f0b7d1cd90 (diff)
downloadserenity-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.h7
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.cpp22
-rw-r--r--Userland/Libraries/LibSoftGPU/PixelQuad.h21
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) };