xemu icon indicating copy to clipboard operation
xemu copied to clipboard

nv2a: Handle framebuffer CPU blit and PVIDEO only rendering

Open abaire opened this issue 3 years ago • 27 comments

Handles two edge cases:

  1. 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).
  2. 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

Tests HW results

abaire avatar Jul 01 '22 04:07 abaire

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

abaire avatar Jul 01 '22 15:07 abaire

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

abaire avatar Jul 01 '22 15:07 abaire

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 avatar Jul 05 '22 21:07 abaire

@abaire you broke Broken-Sword-The-Sleeping-Dragon

https://user-images.githubusercontent.com/71127352/177518264-1057d47f-24e3-437f-9c5c-159630e67c85.mp4

Triticum0 avatar Jul 06 '22 09:07 Triticum0

Tested all the games except -Far Cry Instincts: Evolution -Disney's The Haunted Mansion It didn't fix a single game

Triticum0 avatar Jul 06 '22 09:07 Triticum0

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 avatar Jul 06 '22 14:07 abaire

@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.

abaire avatar Jul 06 '22 14:07 abaire

Looks like it also breaks the FMV for Serious Sam, so hopefully fixing that will fix Broken Sword as well

abaire avatar Jul 06 '22 20:07 abaire

@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).

abaire avatar Jul 06 '22 20:07 abaire

I checked the issue hasn't changed xemu-2022-07-07-11-38-34 Note: this is the title screen doesn't change when in cutscenes

Triticum0 avatar Jul 07 '22 10:07 Triticum0

do you want me to use a debug command in the monitor?

Triticum0 avatar Jul 07 '22 10:07 Triticum0

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.

abaire avatar Jul 07 '22 14:07 abaire

@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.

abaire avatar Jul 15 '22 14:07 abaire

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.

abaire avatar Jul 15 '22 15:07 abaire

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)

abaire avatar Jul 15 '22 15:07 abaire

Seems res scale takes no effert with this build. 6666

ko81e24wy avatar Jun 03 '23 11:06 ko81e24wy

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: fix_652_1x

4x: fix_652_4x

And for comparison purposes, here's a clean build: 1x: master_1x

4x: master_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

abaire avatar Jun 03 '23 15:06 abaire

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: fix_652_1x

4x: fix_652_4x

And for comparison purposes, here's a clean build: 1x: master_1x

4x: master_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.

ko81e24wy avatar Jun 04 '23 12:06 ko81e24wy

Ah, I see it now, along the character's arms. Hopefully just a simple mismerge, will look at it when I have a chance.

abaire avatar Jun 04 '23 14:06 abaire

@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:

new_fix_652_4x

abaire avatar Jun 05 '23 05:06 abaire

Resolved.latest version of this branch. 2023-06-05 141043

ko81e24wy avatar Jun 05 '23 06:06 ko81e24wy

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 avatar Mar 05 '25 00:03 abaire

@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. xemu-2025-03-17-00-58-36

Triticum0 avatar Mar 17 '25 00:03 Triticum0

Testing this pr opengl crashes with File: hw/xbox/nv2a/pgraph/gl/surface.c Line: 618

Triticum0 avatar May 31 '25 01:05 Triticum0

Testing this pr opengl crashes with File: hw/xbox/nv2a/pgraph/gl/surface.c Line: 618

Mismerge rebasing onto master, hopefully it works now

abaire avatar May 31 '25 03:05 abaire

It fixed

Triticum0 avatar Jun 01 '25 11:06 Triticum0

Fixes #2220

Triticum0 avatar Jun 01 '25 13:06 Triticum0

Fixes #2443 xemu-2025-09-19-13-28-30

Triticum0 avatar Sep 19 '25 12:09 Triticum0

Fixes Army Men Series. Ranges from flickering to black screen when upscaling on masters but fixed in this build. Master xemu-2025-11-08-22-40-47

Pr xemu-2025-11-08-22-41-25

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 xemu-2025-11-08-22-53-38

Pr xemu-2025-11-08-22-54-38

Triticum0 avatar Nov 08 '25 22:11 Triticum0