summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSoftGPU
diff options
context:
space:
mode:
authorJelle Raaijmakers <jelle@gmta.nl>2022-09-08 10:10:01 +0200
committerTim Flynn <trflynn89@pm.me>2022-09-08 12:07:03 -0400
commitb42feb76a09f6e7ec36b7dc251961c1fe6d09f16 (patch)
tree3760165ebf5ae99cf6b130b7ca85be51ae42494b /Userland/Libraries/LibSoftGPU
parent08204efe1fcce4b077759e998c46bb2f5f5cce7f (diff)
downloadserenity-b42feb76a09f6e7ec36b7dc251961c1fe6d09f16.zip
LibSoftGPU: Use approximation for maximum depth slope
OpenGL allows GPUs to approximate a triangle's maximum depth slope which prevents a number computationally expensive instructions. On my machine, this gives me +6% FPS in Quake III. We are able to reuse `render_bounds` here since it is the containing rect of the (X, Y) window coordinates of the triangle, thus its width and height are the maximum delta X and delta Y, respectively.
Diffstat (limited to 'Userland/Libraries/LibSoftGPU')
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.cpp34
1 files changed, 7 insertions, 27 deletions
diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp
index 81977569f9..7ab7f3bb34 100644
--- a/Userland/Libraries/LibSoftGPU/Device.cpp
+++ b/Userland/Libraries/LibSoftGPU/Device.cpp
@@ -743,33 +743,13 @@ void Device::rasterize_triangle(Triangle& triangle)
// Calculate depth offset to apply
float depth_offset = 0.f;
if (m_options.depth_offset_enabled) {
- // Edge value deltas
- auto edge_value_step_x = FloatVector3 {
- static_cast<float>(v1.y() - v2.y()),
- static_cast<float>(v2.y() - v0.y()),
- static_cast<float>(v0.y() - v1.y()),
- };
- auto edge_value_step_y = FloatVector3 {
- static_cast<float>(v2.x() - v1.x()),
- static_cast<float>(v0.x() - v2.x()),
- static_cast<float>(v1.x() - v0.x()),
- };
-
- // Barycentric deltas
- auto barycentric_step_x = edge_value_step_x * one_over_area;
- auto barycentric_step_y = edge_value_step_y * one_over_area;
-
- // Depth delta vector and slope (magnitude)
- auto depth_coordinates = FloatVector3 {
- vertex0.window_coordinates.z(),
- vertex1.window_coordinates.z(),
- vertex2.window_coordinates.z(),
- };
- auto depth_step = FloatVector2 {
- depth_coordinates.dot(barycentric_step_x),
- depth_coordinates.dot(barycentric_step_y),
- };
- auto depth_max_slope = depth_step.length();
+ // OpenGL 2.0 ยง 3.5.5 allows us to approximate the maximum slope
+ auto delta_z = max(
+ max(
+ abs(vertex0.window_coordinates.z() - vertex1.window_coordinates.z()),
+ abs(vertex1.window_coordinates.z() - vertex2.window_coordinates.z())),
+ abs(vertex2.window_coordinates.z() - vertex0.window_coordinates.z()));
+ auto depth_max_slope = max(delta_z / render_bounds.width(), delta_z / render_bounds.height());
// Calculate total depth offset
depth_offset = depth_max_slope * m_options.depth_offset_factor + NumericLimits<float>::epsilon() * m_options.depth_offset_constant;