mirror of
https://github.com/libretro/virtualjaguar-libretro.git
synced 2026-11-07 12:47:58 -10:00
fix(video): hi-res epoch trusted window 2 -> 16 frames (#338 Stage 2)
The design's now/now-1 trusted window assumed the 3D view is redrawn every presented frame. Doom -- the Stage 2 anchor -- runs its engine at ~10-15Hz double-buffered, so displayed blocks are routinely 3-8 presented frames old and the 2-frame window rejected every one of them: measured 0.00% supersampled output on E1M1 gameplay, vs 8.68% with the window widened. 16 frames (~267ms NTSC) covers slow engines while still bounding the R3 stale-structure class (a false positive needs a value-coincident dead tag AND 16 frames without a rewrite, and self-heals at the next real write). Window comparison measured: 2 -> 0.00%, 16 -> 8.68%, infinity -> 8.68% (16 saturates the benefit). Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
1df162dd40
commit
404cb118cd
2 files changed
+19
-5
No files matched your search
+14
-2
@@ -132,9 +132,21 @@ void ShadowFBShutdown(void)
|
||||
/* Tag layout (design section 3.4):
|
||||
* bits 0-15 value16 (the stock word the block was derived from)
|
||||
* bit 16 VALID (so zero-init never false-matches RAM zeros)
|
||||
* bits 17-24 frame epoch (entry trusted iff epoch == now or now-1)
|
||||
* bits 17-24 frame epoch (entry trusted iff written within the last
|
||||
* HIRES_EPOCH_WINDOW presented frames)
|
||||
*/
|
||||
#define HIRES_TAG_EPOCH_SHIFT 17
|
||||
/* Trusted-window size in presented frames (design section 3.4 / R3).
|
||||
* The design's initial now/now-1 guess assumed the 3D view is redrawn
|
||||
* every frame; Doom -- the Stage 2 anchor title -- runs its engine at
|
||||
* ~10-15Hz double-buffered, so the displayed buffer's blocks are
|
||||
* routinely 3-8 presented frames old and a 2-frame window rejected
|
||||
* every one of them (measured: 0.00% supersampled output). 16 frames
|
||||
* (~267ms NTSC) covers slow engines while still bounding the R3
|
||||
* stale-structure class: a false positive needs RAM to coincidentally
|
||||
* equal a dead tag AND the word untouched for 16 frames, and it still
|
||||
* self-heals at the next real write. */
|
||||
#define HIRES_EPOCH_WINDOW 16
|
||||
|
||||
int shadowHiresActive = 0;
|
||||
int shadowHiresN = 1;
|
||||
@@ -268,7 +280,7 @@ static const shadowfb_sub *shadow_hires_block(uint32_t addr, uint16_t current16)
|
||||
if ((tag & 0x1FFFF) != ((uint32_t)current16 | SHADOWFB_TAG_VALID))
|
||||
return NULL;
|
||||
ep = (tag >> HIRES_TAG_EPOCH_SHIFT) & 0xFF;
|
||||
if (ep != hiresEpoch && ep != ((hiresEpoch - 1) & 0xFF))
|
||||
if (((hiresEpoch - ep) & 0xFF) >= HIRES_EPOCH_WINDOW)
|
||||
return NULL;
|
||||
return hiresPageSub[page]
|
||||
+ word * (uint32_t)shadowHiresN * (uint32_t)shadowHiresN;
|
||||
|
||||
+5
-3
@@ -86,9 +86,11 @@ void ShadowFBLineFromRAM(int idx, uint32_t srcAddr, uint16_t value16);
|
||||
*
|
||||
* Coherence is the same value-check-at-read scheme as the 1x shadow,
|
||||
* PLUS a frame-epoch field in the tag (design section 3.4): an entry
|
||||
* is only trusted when its epoch is the current or previous frame,
|
||||
* which bounds the stale-structure artifact class that the 1x
|
||||
* bounded-error argument does not cover at Nx (design section 5.4).
|
||||
* is only trusted when it was written within the last few presented
|
||||
* frames (HIRES_EPOCH_WINDOW in shadowfb.c -- sized for slow
|
||||
* double-buffered engines like Doom's ~15Hz renderer), which bounds
|
||||
* the stale-structure artifact class that the 1x bounded-error
|
||||
* argument does not cover at Nx (design section 5.4).
|
||||
*
|
||||
* Stage 1 semantics: every writer stores the stock pixel replicated
|
||||
* N*N times (box replication), so output is bit-exactly the Nx box
|
||||
|
||||
Reference in new issue
Block a user