diff --git a/src/core/gpu.h b/src/core/gpu.h index 6dffc0383..22f1ca174 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -299,22 +299,6 @@ protected: return (m_drawing_area.left <= m_drawing_area.right && m_drawing_area.top <= m_drawing_area.bottom); } - /// Clamps the specified coordinates to the drawing area. - ALWAYS_INLINE void ClampCoordinatesToDrawingArea(s32* x, s32* y) - { - const s32 x_value = *x; - if (x_value < static_cast(m_drawing_area.left)) - *x = m_drawing_area.left; - else if (x_value >= static_cast(m_drawing_area.right)) - *x = m_drawing_area.right - 1; - - const s32 y_value = *y; - if (y_value < static_cast(m_drawing_area.top)) - *y = m_drawing_area.top; - else if (y_value >= static_cast(m_drawing_area.bottom)) - *y = m_drawing_area.bottom - 1; - } - void AddCommandTicks(TickCount ticks); void WriteGP1(u32 value); @@ -332,15 +316,21 @@ protected: virtual void UpdateDisplay(); virtual void DrawRendererStats(); - ALWAYS_INLINE void AddDrawTriangleTicks(s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, bool shaded, bool textured, - bool semitransparent) + ALWAYS_INLINE_RELEASE void AddDrawTriangleTicks(s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, bool shaded, + bool textured, bool semitransparent) { // This will not produce the correct results for triangles which are partially outside the clip area. // However, usually it'll undershoot not overshoot. If we wanted to make this more accurate, we'd need to intersect // the edges with the clip rectangle. - ClampCoordinatesToDrawingArea(&x1, &y1); - ClampCoordinatesToDrawingArea(&x2, &y2); - ClampCoordinatesToDrawingArea(&x3, &y3); + // TODO: Coordinates are exclusive, so off by one here... + const s32 clip_right = static_cast(m_drawing_area.right) + 1; + const s32 clip_bottom = static_cast(m_drawing_area.bottom) + 1; + x1 = std::clamp(x1, static_cast(m_drawing_area.left), clip_right); + x2 = std::clamp(x2, static_cast(m_drawing_area.left), clip_right); + x3 = std::clamp(x3, static_cast(m_drawing_area.left), clip_right); + y1 = std::clamp(y1, static_cast(m_drawing_area.top), clip_bottom); + y2 = std::clamp(y2, static_cast(m_drawing_area.top), clip_bottom); + y3 = std::clamp(y3, static_cast(m_drawing_area.top), clip_bottom); TickCount pixels = std::abs((x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2) / 2); if (textured) @@ -352,24 +342,44 @@ protected: AddCommandTicks(pixels); } - ALWAYS_INLINE void AddDrawRectangleTicks(u32 width, u32 height, bool textured, bool semitransparent) + ALWAYS_INLINE_RELEASE void AddDrawRectangleTicks(s32 x, s32 y, u32 width, u32 height, bool textured, + bool semitransparent) { - u32 ticks_per_row = width; + // We do -1 on the inside of the clamp, in case the rectangle is entirely clipped. + u32 drawn_width = static_cast( + std::clamp(x + static_cast(width), static_cast(m_drawing_area.left), + static_cast(m_drawing_area.right) + 1) - + std::clamp(x, static_cast(m_drawing_area.left), static_cast(m_drawing_area.right) + 1)); + u32 drawn_height = static_cast( + std::clamp(y + static_cast(height), static_cast(m_drawing_area.top), + static_cast(m_drawing_area.bottom) + 1) - + std::clamp(y, static_cast(m_drawing_area.top), static_cast(m_drawing_area.bottom) + 1)); + + u32 ticks_per_row = drawn_width; if (textured) - ticks_per_row += width; + ticks_per_row += drawn_width; if (semitransparent || m_GPUSTAT.check_mask_before_draw) - ticks_per_row += (width + 1u) / 2u; + ticks_per_row += (drawn_width + 1u) / 2u; if (m_GPUSTAT.SkipDrawingToActiveField()) - height = std::max(height / 2, 1u); + drawn_height = std::max(drawn_height / 2, 1u); - AddCommandTicks(ticks_per_row * height); + AddCommandTicks(ticks_per_row * drawn_height); } - ALWAYS_INLINE void AddDrawLineTicks(u32 width, u32 height, bool shaded) + ALWAYS_INLINE_RELEASE void AddDrawLineTicks(s32 min_x, s32 min_y, s32 max_x, s32 max_y, bool shaded) { - if (m_GPUSTAT.SkipDrawingToActiveField()) - height = std::max(height / 2, 1u); + // We do -1 on the inside of the clamp, in case the rectangle is entirely clipped. + // Lines are inclusive? + u32 drawn_width = static_cast( + std::clamp(max_x + 1, static_cast(m_drawing_area.left), static_cast(m_drawing_area.right) + 1) - + std::clamp(min_x, static_cast(m_drawing_area.left), static_cast(m_drawing_area.right) + 1)); + u32 drawn_height = static_cast( + std::clamp(max_y + 1, static_cast(m_drawing_area.top), static_cast(m_drawing_area.bottom) + 1) - + std::clamp(min_y, static_cast(m_drawing_area.top), static_cast(m_drawing_area.bottom) + 1)); - AddCommandTicks(std::max(width, height)); + if (m_GPUSTAT.SkipDrawingToActiveField()) + drawn_height = std::max(drawn_height / 2, 1u); + + AddCommandTicks(std::max(drawn_width, drawn_height)); } std::unique_ptr m_crtc_tick_event; diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index f1eb9ffcd..e9080e396 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -2213,14 +2213,7 @@ void GPU_HW::LoadVertices() } IncludeDrawnDirtyRectangle(pos_x, pos_y, pos_x + rectangle_width, pos_y + rectangle_height); - - const u32 clip_left = static_cast(std::clamp(pos_x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = - static_cast(std::clamp(pos_x + rectangle_width, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(pos_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(pos_y + rectangle_height, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - AddDrawRectangleTicks(clip_right - clip_left, clip_bottom - clip_top, rc.texture_enable, rc.transparency_enable); + AddDrawRectangleTicks(pos_x, pos_y, rectangle_width, rectangle_height, rc.texture_enable, rc.transparency_enable); if (m_sw_renderer) { @@ -2276,15 +2269,8 @@ void GPU_HW::LoadVertices() return; } - IncludeDrawnDirtyRectangle(min_x, min_y, max_x, max_y); - - const u32 clip_left = static_cast(std::clamp(min_x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = static_cast(std::clamp(max_x, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(min_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(max_y, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - - AddDrawLineTicks(clip_right - clip_left, clip_bottom - clip_top, rc.shading_enable); + IncludeDrawnDirtyRectangle(min_x, min_y, max_x + 1, max_y + 1); + AddDrawLineTicks(min_x, min_y, max_x, max_y, rc.shading_enable); // TODO: Should we do a PGXP lookup here? Most lines are 2D. DrawLine(static_cast(start_x), static_cast(start_y), start_color, static_cast(end_x), @@ -2343,16 +2329,8 @@ void GPU_HW::LoadVertices() } else { - IncludeDrawnDirtyRectangle(min_x, min_y, max_x, max_y); - - const u32 clip_left = static_cast(std::clamp(min_x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = - static_cast(std::clamp(max_x, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(min_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(max_y, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - - AddDrawLineTicks(clip_right - clip_left, clip_bottom - clip_top, rc.shading_enable); + IncludeDrawnDirtyRectangle(min_x, min_y, max_x + 1, max_y + 1); + AddDrawLineTicks(min_x, min_y, max_x, max_y, rc.shading_enable); // TODO: Should we do a PGXP lookup here? Most lines are 2D. DrawLine(static_cast(start_x), static_cast(start_y), start_color, static_cast(end_x), diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 052798981..4d05a0365 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -677,15 +677,7 @@ void GPU_SW::DispatchRenderCommand() if (!IsDrawingAreaIsValid()) return; - const u32 clip_left = static_cast(std::clamp(cmd->x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = - static_cast(std::clamp(cmd->x + cmd->width, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(cmd->y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(cmd->y + cmd->height, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - - // cmd->bounds.Set(Truncate16(clip_left), Truncate16(clip_top), Truncate16(clip_right), Truncate16(clip_bottom)); - AddDrawRectangleTicks(clip_right - clip_left, clip_bottom - clip_top, rc.texture_enable, rc.transparency_enable); + AddDrawRectangleTicks(cmd->x, cmd->y, cmd->width, cmd->height, rc.texture_enable, rc.transparency_enable); m_backend.PushCommand(cmd); } @@ -737,14 +729,7 @@ void GPU_SW::DispatchRenderCommand() return; } - const u32 clip_left = static_cast(std::clamp(min_x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = static_cast(std::clamp(max_x, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(min_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(max_y, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - // cmd->bounds.Set(Truncate16(clip_left), Truncate16(clip_top), Truncate16(clip_right), - // Truncate16(clip_bottom)); - AddDrawLineTicks(clip_right - clip_left, clip_bottom - clip_top, rc.shading_enable); + AddDrawLineTicks(min_x, min_y, max_x, max_y, rc.shading_enable); m_backend.PushCommand(cmd); } @@ -760,7 +745,6 @@ void GPU_SW::DispatchRenderCommand() cmd->vertices[0].x = start_vp.x + m_drawing_offset.x; cmd->vertices[0].y = start_vp.y + m_drawing_offset.y; cmd->vertices[0].color = m_render_command.color_for_first_vertex; - // cmd->bounds.SetInvalid(); const bool shaded = m_render_command.shading_enable; for (u32 i = 1; i < num_vertices; i++) @@ -780,16 +764,7 @@ void GPU_SW::DispatchRenderCommand() } else { - const u32 clip_left = static_cast(std::clamp(min_x, m_drawing_area.left, m_drawing_area.right)); - const u32 clip_right = - static_cast(std::clamp(max_x, m_drawing_area.left, m_drawing_area.right)) + 1u; - const u32 clip_top = static_cast(std::clamp(min_y, m_drawing_area.top, m_drawing_area.bottom)); - const u32 clip_bottom = - static_cast(std::clamp(max_y, m_drawing_area.top, m_drawing_area.bottom)) + 1u; - - // cmd->bounds.Include(Truncate16(clip_left), Truncate16(clip_right), Truncate16(clip_top), - // Truncate16(clip_bottom)); - AddDrawLineTicks(clip_right - clip_left, clip_bottom - clip_top, m_render_command.shading_enable); + AddDrawLineTicks(min_x, min_y, max_x, max_y, rc.shading_enable); } }