mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Keep native redraw VRAM journals bounded with an exact spill backup
This commit is contained in:
@@ -279,8 +279,18 @@ int render_pass_vram_policy(const RenderPassJournal *j, int px, int py,
|
||||
if (*x >= j->x[i] && *y >= j->y[i] && *x + *w <= j->x[i] + j->w[i] &&
|
||||
*y + *h <= j->y[i] + j->h[i])
|
||||
return RENDER_PASS_VRAM_ALLOW; /* already covered */
|
||||
return j->n < RENDER_PASS_JOURNAL_MAX ? RENDER_PASS_VRAM_JOURNAL
|
||||
: RENDER_PASS_VRAM_REFUSE;
|
||||
if (j->n >= RENDER_PASS_JOURNAL_MAX) return RENDER_PASS_VRAM_REFUSE;
|
||||
/* Reserve the last entry for a whole-VRAM spill. A sprite scene can
|
||||
* upload more than 64 disjoint animation/CLUT rectangles in one redraw.
|
||||
* Back up the current contents once, including earlier temporary writes;
|
||||
* reverse-order rollback restores this spill FIRST and then restores
|
||||
* those earlier rectangles to their original contents. Subsequent writes
|
||||
* are covered by the spill, so capacity remains bounded without dropping
|
||||
* legitimate texture uploads or disabling native interpolation. */
|
||||
if (j->n == RENDER_PASS_JOURNAL_MAX - 1) {
|
||||
*x = *y = 0; *w = vram_w; *h = vram_h;
|
||||
}
|
||||
return RENDER_PASS_VRAM_JOURNAL;
|
||||
}
|
||||
|
||||
int render_pass_journal_add(RenderPassJournal *j, const uint16_t *vram,
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
* 3. VRAM journal (render_pass_vram_policy / _journal_add / _rollback, the
|
||||
* CPU side of gpu_gl_renderer.c's out-of-rect journal): writes inside the
|
||||
* pass rect are allowed, writes outside are backed up first and rolled
|
||||
* back exactly, covered writes are not journaled twice, a full journal or
|
||||
* a renderer mode that cannot journal refuses.
|
||||
* back exactly, covered writes are not journaled twice, the last slot spills
|
||||
* to a whole-VRAM backup, and a mode that cannot journal refuses.
|
||||
*
|
||||
* The GPU, presenter and remaining devices are mocks. Build/run:
|
||||
* ctest -R render_pass_sandbox_test */
|
||||
@@ -648,10 +648,16 @@ static void test_journal(void) {
|
||||
int k = j.n;
|
||||
CHECK(POLICY(400 + 8 * k, 100, 4, 4, 1) == RENDER_PASS_VRAM_JOURNAL, "fill journal");
|
||||
render_pass_journal_add(&j, s_vram, VW, x, y, w, h);
|
||||
paint(x, y, w, h, (uint16_t)(0x8000 + k));
|
||||
/* Policy can enlarge the BACKUP, never the actual GPU write. */
|
||||
paint(400 + 8 * k, 100, 4, 4, (uint16_t)(0x8000 + k));
|
||||
}
|
||||
CHECK(j.n == RENDER_PASS_JOURNAL_MAX && n == 5, "journal full");
|
||||
CHECK(POLICY(900, 400, 4, 4, 1) == RENDER_PASS_VRAM_REFUSE, "full journal refuses");
|
||||
CHECK(j.x[j.n-1] == 0 && j.y[j.n-1] == 0 &&
|
||||
j.w[j.n-1] == VW && j.h[j.n-1] == VH, "last slot protects all VRAM");
|
||||
CHECK(POLICY(900, 400, 4, 4, 1) == RENDER_PASS_VRAM_ALLOW, "spill covers later writes");
|
||||
paint(900, 400, 4, 4, 0x9999);
|
||||
CHECK(POLICY(650, 4, 16, 16, 1) == RENDER_PASS_VRAM_ALLOW, "spill permits overlapping rewrites");
|
||||
paint(650, 4, 16, 16, 0xAAAA);
|
||||
CHECK(render_pass_journal_add(&j, s_vram, VW, 900, 400, 4, 4) == -1,
|
||||
"add refuses past the limit");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user