xemu
xemu copied to clipboard
nv2a: Handle framebuffer CPU blit and PVIDEO only rendering
Handles two edge cases:
- CPU blits to the framebuffer without using 3D rendering or after 3D rendering was previously done with a surface shape that does not match the framebuffer (e.g., a different pitch).
- Fullscreen PVIDEO rendering without any 3D rendering.
In both cases this change prevents the pgraph code from returning early,
bypassing the special case VGA handling in sdl2_gl_refresh and instead
using a special framebuffer texture to render the contents of VRAM.
Fixes #652 Fixes #1165 Fixes #2220
There appears to be a race condition going on that causes stale frames to be displayed (on my machine if you let it run long enough there will be periods where things sync up and look fine and periods where it jumps back to a stale frame for a bit and jitters)
Attached is a video of one such run. The test alternates frames between different colored checkerboards, performing a buffer swap between each blit.
WARNING: THIS CONTAINS RAPIDLY FLASHING VIDEO
https://user-images.githubusercontent.com/448413/176922431-40483453-3c57-4fb2-8f60-d723ea200191.mp4
The video is captured at 120hz so it's expected that each color should be displayed for ~2 frames of video, but significantly longer runs can be seen (e.g., by extracting frames: ffmpeg -i CPUBlitJitterTest.mp4 frame%04d.png -hide_banner).
Colors should alternate: black & white, red & black, black & blue, green & black, black & magenta, yellow & black
However frames 122-130 (as well as others) show a sequence break, in this case green&black is skipped entirely as the black&blue frame is repeated.
Note: The issue is less pronounced on an M1
Some numbers illustrating the problem (running the same test program that just blits checkerboards and swaps frames). This shows that the framebuffer surface used by the xemu UI can get out of sync with the buffer being written to by the guest.
get_fb_surface: 0x3AA8A00
get_fb_surface: 0x3AA8A00
get_fb_surface: 0x3BD4A00
CPU write: 0x3D00000
get_fb_surface: 0x3BD4A00
get_fb_surface: 0x3D00A00 // Flip handled correctly
CPU write: 0x3AA8000 // This frame is skipped entirely
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
CPU write: 0x3BD4000 // This frame is skipped entirely
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
CPU write: 0x3D00000 // This effectively writes to the frontbuffer and may tear
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
get_fb_surface: 0x3D00A00
CPU write: 0x3AA8000
get_fb_surface: 0x3D00A00
CPU write: 0x3BD4000
get_fb_surface: 0x3AA8A00 // Things start to get resync'd at this point
CPU write: 0x3D00000
get_fb_surface: 0x3BD4A00
CPU write: 0x3AA8000
A similar run tracking changes to PCRTC_START:
pgraph_surface_access_callback - 0x3BD4000
nv2a_get_framebuffer_surface - 0x3AA8A00
PCRTC_START - 0x3BD4000 cc cc cc ff
pgraph_surface_access_callback - 0x3D00000
nv2a_get_framebuffer_surface - 0x3BD4A00
PCRTC_START - 0x3D00000 0 0 0 ff
pgraph_surface_access_callback - 0x3AA8000
nv2a_get_framebuffer_surface - 0x3D00A00
nv2a_get_framebuffer_surface - 0x3D00A00
PCRTC_START - 0x3AA8000 44 cc cc ff
pgraph_surface_access_callback - 0x3BD4000
nv2a_get_framebuffer_surface - 0x3AA8A00
nv2a_get_framebuffer_surface - 0x3AA8A00
PCRTC_START - 0x3BD4000 cc 44 cc ff
pgraph_surface_access_callback - 0x3D00000 // This frame is never displayed, the flip is missing.
nv2a_get_framebuffer_surface - 0x3BD4A00
nv2a_get_framebuffer_surface - 0x3BD4A00
nv2a_get_framebuffer_surface - 0x3BD4A00
nv2a_get_framebuffer_surface - 0x3BD4A00
pgraph_surface_access_callback - 0x3AA8000
nv2a_get_framebuffer_surface - 0x3BD4A00
nv2a_get_framebuffer_surface - 0x3BD4A00
PCRTC_START - 0x3AA8000 0 0 0 ff
pgraph_surface_access_callback - 0x3BD4000
nv2a_get_framebuffer_surface - 0x3AA8A00
PCRTC_START - 0x3BD4000 cc cc cc ff
pgraph_surface_access_callback - 0x3D00000
nv2a_get_framebuffer_surface - 0x3BD4A00
nv2a_get_framebuffer_surface - 0x3BD4A00
pgraph_surface_access_callback - 0x3AA8000
nv2a_get_framebuffer_surface - 0x3BD4A00
PCRTC_START - 0x3AA8000 44 cc cc ff
pgraph_surface_access_callback - 0x3BD4000
nv2a_get_framebuffer_surface - 0x3AA8A00
PCRTC_START - 0x3BD4000 0 0 0 ff
pgraph_surface_access_callback - 0x3D00000
nv2a_get_framebuffer_surface - 0x3BD4A00
PCRTC_START - 0x3D00000 cc cc cc ff
pgraph_surface_access_callback - 0x3AA8000
nv2a_get_framebuffer_surface - 0x3D00A00
PCRTC_START - 0x3AA8000 0 0 0 ff
pgraph_surface_access_callback - 0x3BD4000
nv2a_get_framebuffer_surface - 0x3AA8A00
PCRTC_START - 0x3BD4000 cc cc cc ff
Updated to take a different approach. Rather than fall back to the VGA handling in xemu.c, cases with a valid framebuffer but missing/non-matching SurfaceBinding are special cased to allow proper interaction with the PVIDEO overlay.
@abaire you broke Broken-Sword-The-Sleeping-Dragon
https://user-images.githubusercontent.com/71127352/177518264-1057d47f-24e3-437f-9c5c-159630e67c85.mp4
Tested all the games except -Far Cry Instincts: Evolution -Disney's The Haunted Mansion It didn't fix a single game
Tested all the games except -Far Cry Instincts: Evolution -Disney's The Haunted Mansion It didn't fix a single game
Thanks, then it's probably safe to assume they're due to a different underlying cause.
@abaire you broke Broken-Sword-The-Sleeping-Dragon
Looks like the pitch ends up being incorrect for this case. I just ordered it, will look at it again in a week or two when it arrives.
Looks like it also breaks the FMV for Serious Sam, so hopefully fixing that will fix Broken Sword as well
@Triticum0 can you check Broken Sword again with the latest commit? I'm not sure it'll actually work given the video you posted, but it now properly handles framebuffers other than 32bpp (like Serious Sam's intro video).
I checked the issue hasn't changed
Note: this is the title screen doesn't change when in cutscenes
do you want me to use a debug command in the monitor?
do you want me to use a debug command in the monitor?
No, it seems like there's either something interesting about that specific game, or about this patch in general. @theboy181 has similar output for games that I know work with this patch (e.g., Pirates... which is the primary game I tested with on my machine) so I'm suspicious that there is something else I'm missing, possibly driver version related since I think all three of us are using nvidia hardware.
@Triticum0 I was able to debug Broken Sword, it used a non-packed pitch for the VGA buffer but should be fixed now.
Can you re-test everything just to make sure there's no regressions? I've checked Pirates! and Stake, but want to make sure they're still fixed on your machine as well.
I was able to reproduce the issue reported by @theboy181 by enabling widescreen and 480p mode and running with -machine avpack=hdtv. The fix for the Broken Sword pitch issue also fixes that case (confirmed by reverting the pitch fix, which produces corrupt video).
Still a small problem when running with widescreen enabled in the dashboard but no avpack, the title screen of Pirates... wraps around.
When widescreen is enabled but no avpack is set, Pirates ends up using a vga resolution of 704x480 with a vga line offset of 2560 (640x4). Added handling for this case, anytime the vga width is set larger than the pitch it will calculate the correct width and ignore the excess (matching the behavior of the GL surface bypass case)
Seems res scale takes no effert with this build.
Seems res scale takes no effert with this build.
Thanks for testing @ko81e24wy - can you double check? I just did a build of this branch and it seems to work for me:
1x:
4x:
And for comparison purposes, here's a clean build:
1x:
4x:
To my eye, the textures on the rocks in the 4x case are substantially sharper than the 1x, both on this fix branch and on master
Seems res scale takes no effert with this build.
Thanks for testing @ko81e24wy - can you double check? I just did a build of this branch and it seems to work for me:
1x:
4x:
And for comparison purposes, here's a clean build: 1x:
4x:
To my eye, the textures on the rocks in the 4x case are substantially sharper than the 1x, both on this fix branch and on
master
yes,its sharper,but still has aliasing,master build is smoother.
Ah, I see it now, along the character's arms. Hopefully just a simple mismerge, will look at it when I have a chance.
@ko81e24wy mind testing again with the latest version? There was an issue with the merge and the original patch that I think are resolved now:
Resolved.latest version of this branch.
Rebased on 0.8.20. I haven't tested anything in Vulkan but confirmed that this still fixes #652 and #1165 on macOS/OpenGL
@abaire Retested Disney's The Haunted Mansion and Broken Sword The Sleeping Dragon. Look like the regression seems to be fixed. FMV issues still need to be investigated, but if that was the only issue stopping it from being merge you can merge it to masters.
Testing this pr opengl crashes with File: hw/xbox/nv2a/pgraph/gl/surface.c Line: 618
Testing this pr opengl crashes with
File: hw/xbox/nv2a/pgraph/gl/surface.c Line: 618
Mismerge rebasing onto master, hopefully it works now
It fixed
Fixes #2220
Fixes #2443
Fixes Army Men Series. Ranges from flickering to black screen when upscaling on masters but fixed in this build.
Master
Pr
Edit: some reason issue I got original at 1x during first boot, seems to not be reproducible after first boot so info maybe cached into shaders. still fixes the issue but this what I got orginally
Master
Pr



