Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remaining range culling problems #17397

Open
hrydgard opened this issue May 3, 2023 · 14 comments
Open

Remaining range culling problems #17397

hrydgard opened this issue May 3, 2023 · 14 comments
Labels
GE emulation Backend-independent GPU issues Guardband / Range Culling Involves vertices outside fustrum.
Milestone

Comments

@hrydgard
Copy link
Owner

hrydgard commented May 3, 2023

Most of this is likely to be specific to hardware that can't use one of our various techniques to do clipping and culling properly with planes and geo shaders.

Previously we had [DisableRangeCulling] in compat.ini (which isn't a good universal solution since some games rely on range culling).

There's one issue in N.O.V.A on Samsung Galaxy A04E with PowerVR GE8320, reported by Ματchα and HeyImFranco on Discord:

020523_181715_001.mp4

This was previously worked around with DisableRangeCulling in #13989 .

GE dump:

NOVA range cull 17397 NPUZ00179.zip

Another issue seems to be Kidou Keisatsu Patlabor - see issue #17061

1

@hrydgard hrydgard added the Guardband / Range Culling Involves vertices outside fustrum. label May 3, 2023
@hrydgard hrydgard added this to the v1.16.0 milestone May 3, 2023
@hrydgard hrydgard added the GE emulation Backend-independent GPU issues label May 3, 2023
@unknownbrackets
Copy link
Collaborator

The person in question says they're using a Samsung Galaxy A04E, which has shaderClipDistance and shaderCullDistance for Vulkan. GLES doesn't support clip/cull, though.

That said, both frame dumps look the same as a PSP even when forcing off those. If I force off GPU_USE_VS_RANGE_CULLING, it does make one of the framedumps incorrectly differ from the PSP.

#17397_NPUZ00179_nova_culling.zip

Might need a better frame dump. Hard to imagine this happens in the game, but there was a homebrew that had someone similarly complain and the actual homebrew had the problems on a real PSP. Maybe it's some math issue.

-[Unknown]

@unknownbrackets
Copy link
Collaborator

Also the same with an additional frame dump:
#17397_NPUZ00179_nova_culling_3.zip

In this one, I assume the wall would be drawn by 4/39. It appears to match rendering on a PSP...

-[Unknown]

@hrydgard
Copy link
Owner Author

hrydgard commented May 4, 2023

As you say, if you forcibly disable range culling in the code, we do indeed get what's almost certainly the intended image.

Maybe some subtle CPU bug is missing to set the correct clipping flag? Or not saved in the dump correctly? Or, it's actually never set by the game and PPSSPP resorts to the wrong default?

@unknownbrackets
Copy link
Collaborator

Noting here for clarity - that's only if I force us never to range cull. The PSP GE (at least as far as I've seen) always range-culls.

There was a time when I thought that it didn't range cull when depth was clamped, but I was wrong - it was only when triangles were clipped against negative Z and said clipping put them within X/Y range. Since learning that I've found no way to reproduce a scenario where range culling doesn't happen.

The way the registers work, it really seems like the GE can only deal with rasterization within its fixed 12.4 space, and simply discards things that go anywhere outside that.

The software renderer (unlike Vulkan/GL which get it subtly wrong and also clip against W which is wrong and can result in over and under culling) should reproduce the negative Z clip scenario decently well. The frame dumps look the same with and without the depth clamp / near Z clip flag. It would have to be down to the verts or something.

I did search for reviews quickly on this game. They're scant, but not very positive. Maybe it's more possible than I thought before that it was just a buggy mess... in which case, maybe this is a hack that makes the game better because it was a lazy iPhone port, although less faithfully emulating the actual PSP experience.

-[Unknown]

@hrydgard
Copy link
Owner Author

hrydgard commented May 5, 2023

It makes some sense that it can only deal with raster coordinates in that small coordinate system, I guess it saves on gates in the chip to reduce those counters as much as possible.

Anyway, this is weird. Because when actually playing the game on hardware and not replaying our framedumps, for whatever bizarre reason, it does seem like the bad culling isn't happening. Here's footage from what appears to be a real PSP, and there are no signs of the culling:

https://www.youtube.com/watch?v=3tFD4Z4Rkz0

@unknownbrackets
Copy link
Collaborator

Where are these issues actually seen, though? I kinda wish I'd bought this when the store was still available, I guess.

I had some save state in some early part of the game, loading it in another mini obviously doesn't let me go very far, but I don't see any of this happening walking near walls, etc.

-[Unknown]

@hrydgard
Copy link
Owner Author

hrydgard commented May 6, 2023

If you post the save state, I'll load it up on a phone with this GPU and try it.

Yeah there's no way to actually get this legally now is there, at all? Kind of abandonware...

@unknownbrackets
Copy link
Collaborator

NPEZ00222_nova.zip

Well, actually, maybe it's still possible on a PS3 or Vita if you fund a wallet, hm. If it's still listed.

-[Unknown]

@hrydgard
Copy link
Owner Author

hrydgard commented May 6, 2023

Hm, I tried to load the savestate on top of psp-flower (by replacing one), and the result was a crash in PspOskDialog::DoState for some reason, which we should probably fix:

05-06 22:42:41.683  9557  9557 F DEBUG   : Abort message: 'terminating with uncaught exception of type std::length_error: basic_string'
05-06 22:42:41.683  9557  9557 F DEBUG   :     x0  0000000000000000  x1  000000000000247d  x2  0000000000000006  x3  000000782c332810
05-06 22:42:41.683  9557  9557 F DEBUG   :     x4  736f646277641f73  x5  736f646277641f73  x6  736f646277641f73  x7  7f7f7f7f7f7f7f7f
05-06 22:42:41.684  9557  9557 F DEBUG   :     x8  00000000000000f0  x9  00000079564400d8  x10 ffffff00fffffbdf  x11 0000000000000001
05-06 22:42:41.684  9557  9557 F DEBUG   :     x12 00000000060ec036  x13 00000a694f0be7cb  x14 000e8262a0f87a9f  x15 000000004cec4ec5
05-06 22:42:41.684  9557  9557 F DEBUG   :     x16 0000007956515d20  x17 00000079564f0310  x18 0000000000003069  x19 00000000000000ac
05-06 22:42:41.684  9557  9557 F DEBUG   :     x20 00000000000023d6  x21 00000000000000b2  x22 000000000000247d  x23 00000000ffffffff
05-06 22:42:41.684  9557  9557 F DEBUG   :     x24 000000782c332950  x25 000000782c332990  x26 b400007847b7bb59  x27 3fffffffffffffef
05-06 22:42:41.684  9557  9557 F DEBUG   :     x28 b400007847b7beb9  x29 000000782c332890
05-06 22:42:41.684  9557  9557 F DEBUG   :     lr  00000079564a18f4  sp  000000782c3327f0  pc  00000079564a1924  pst 0000000000000000
05-06 22:42:41.684  9557  9557 F DEBUG   : backtrace:
05-06 22:42:41.684  9557  9557 F DEBUG   :       #00 pc 0000000000089924  /apex/com.android.runtime/lib64/bionic/libc.so (abort+180) (BuildId: 8f222942dc272b9a57d3ee413b6d3106)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #01 pc 0000000000ec34dc  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #02 pc 0000000000ec3634  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #03 pc 0000000000ec0524  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #04 pc 0000000000ebfb50  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #05 pc 0000000000ebfaac  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (__cxa_throw+112) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #06 pc 000000000040b198  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #07 pc 0000000000411c9c  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (std::__ndk1::__basic_string_common<true>::__throw_length_error() const+16) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #08 pc 0000000000726684  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >::__grow_by(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)+284) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #09 pc 0000000000726504  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >::append(unsigned long, wchar_t)+108) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #10 pc 00000000007255a0  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (Do(PointerWrap&, std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >&)+272) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #11 pc 000000000049b2f8  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (PSPOskDialog::DoState(PointerWrap&)+196) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #12 pc 00000000005a5e94  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (__UtilityDoState(PointerWrap&)+192) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #13 pc 000000000050d810  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (__KernelDoState(PointerWrap&)+516) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #14 pc 00000000005f4438  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (SaveState::SaveStart::DoState(PointerWrap&)+572) (BuildId: 76b3acb81fe5c5aa8df123dae97eb5f8586ef076)
05-06 22:42:41.684  9557  9557 F DEBUG   :       #15 pc 00000000005f3cb4  /data/app/~~hqta-k6gq9P0ENNgn5tj_w==/org.ppsspp.ppsspp-xteJolUFj_Bqw3e_sAZnmA==/lib/arm64/libppsspp_jni.so (CChunkFileReader::Error CChunkFileReader::LoadPtr<SaveState::SaveStart>(unsigned char*, SaveState::SaveStart&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >*)+88) (Bui

I'll try loading it on top of something else..

@hrydgard
Copy link
Owner Author

hrydgard commented May 6, 2023

Huh, I'm realizing that void Do(PointerWrap &p, std::wstring &x) is utterly busted - sizeof(wchar_t) differs between platforms!

I don't think we use it pretty much anywhere else than in the old-version fallback for PSPOskDialog::DoState though.

Though hm, fixing it might mean not loading old saves made on the same platform, just to be able to load old PC saves with this on Android. ugh.

@hrydgard
Copy link
Owner Author

hrydgard commented May 6, 2023

Alright, got it loaded up, and indeed, not seeing much in the way of culling issues on the device. Not sure what conclusions to draw here, as it looks ship-blockingly bad in the video above..

@hrydgard
Copy link
Owner Author

hrydgard commented May 6, 2023

I guess the next thing to try is to ask someone with the game to make a new statestate in an affected location on an affected device.. Though, feels like we'd get similar results to the framedump, that it'd weirdly reproduce on both platforms.

Anyway, if we assume that the game is just broken we could view disabling range culling as an "enhancement" here and just do it...

@xdpirate
Copy link

@hrydgard I have this game on an affected device, and found this issue through searching the repo. The affected device is an AYN Odin Pro (SD845, Adreno 630), running PPSSPP v1.15.4 from the Play Store.

The issue presents itself from the start of the game. Here is a save state made right after the first tutorial section, a particularly egregious point with aggressive culling: NPUZ00179_1.01_0.zip

I can provide video footage or help troubleshooting if needed, although I am not familiar with the codebase, so I can only assist as an end user in this.

@hrydgard hrydgard modified the milestones: v1.16.0, v1.17.0 Aug 28, 2023
@hrydgard
Copy link
Owner Author

I've added a workaround for this, the new Speedhack "Disable culling". This can be used to easily investigate these problems and confirm that this is the issue.

Moving further work to the next version.

@hrydgard hrydgard modified the milestones: v1.17.0, v1.18.0 Dec 19, 2023
@hrydgard hrydgard modified the milestones: v1.18.0, Future-Prio Jul 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GE emulation Backend-independent GPU issues Guardband / Range Culling Involves vertices outside fustrum.
Projects
None yet
Development

No branches or pull requests

3 participants