mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
gl: fix native-wide band bleed - mirror scissor Y clamps to the draw area
The wide-mirror pass scissored the FULL wide surface (both X and Y). The SW reference (rt_wide) only widens X; its Y clip stays the canonical draw-area clip. Under a vertical double-buffer (MMX6: draw area alternates y=0/y=240, both bands in ONE full-height wide surface keyed by base_x) the full-height Y scissor let draws that canonically clip at the band boundary bleed into the OTHER band's rows, presented a frame later as user-visible top/bottom edge flicker (16:9 GL only). Scissor is now full-width X, draw-area Y, matching rt_wide exactly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1074,17 +1074,28 @@ static void mark_prim_dirty(const int *xs, const int *ys, int n, int textured) {
|
||||
* caller stays inside hr_begin/hr_end; hr_end unbinds and the next hr_begin
|
||||
* resets the viewport, so no viewport restore is needed mid-function.
|
||||
*
|
||||
* The scissor is the FULL wide surface (NOT the draw area): the SW reference
|
||||
* (rt_wide()) clips the wide pass only to the surface bounds, deliberately
|
||||
* letting the shifted geometry fill the revealed 16:9 margins that lie OUTSIDE
|
||||
* the game's 4:3 draw-area x-range. Scissoring to the (translated) draw area
|
||||
* would crop exactly the margin content native-wide exists to reveal. */
|
||||
* The scissor X is the FULL wide surface (NOT the draw area): the SW reference
|
||||
* (rt_wide()) deliberately lets the shifted geometry fill the revealed 16:9
|
||||
* margins that lie OUTSIDE the game's 4:3 draw-area x-range; scissoring X to
|
||||
* the (translated) draw area would crop exactly the margin content native-wide
|
||||
* exists to reveal. The scissor Y stays clamped to the DRAW AREA, exactly like
|
||||
* rt_wide() (t.cy1/cy2 = g_clip_y1/y2): native-wide only widens X. A full-height
|
||||
* Y scissor let draws that canonically clip at a vertical double-buffer band
|
||||
* boundary (MMX6: draw area alternates y=0/y=240, both bands in ONE wide
|
||||
* surface) bleed into the OTHER band's rows — presented one frame later as
|
||||
* top/bottom edge flicker (16:9 GL only). */
|
||||
static void wide_target_begin(int dx, GLint uXoff, GLint uXhalf) {
|
||||
if (s_ws_ablate != 3) /* ablate 3: no FBO rebind (draws land in hr — perf probe) */
|
||||
p_glBindFramebuffer(PSXGL_FRAMEBUFFER, g_wide_cur);
|
||||
glViewport(0, 0, g_wide_w * s_scale, VRAM_H * s_scale);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(0, 0, g_wide_w * s_scale, VRAM_H * s_scale);
|
||||
{
|
||||
int sy = s_area_y1, sh = s_area_y2 - s_area_y1 + 1;
|
||||
if (sy < 0) { sh += sy; sy = 0; }
|
||||
if (sy + sh > VRAM_H) sh = VRAM_H - sy;
|
||||
if (sh < 0) sh = 0;
|
||||
glScissor(0, sy * s_scale, g_wide_w * s_scale, sh * s_scale);
|
||||
}
|
||||
p_glUniform1f(uXoff, (float)dx);
|
||||
p_glUniform1f(uXhalf, (float)g_wide_w / 2.0f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user