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

IronMan No clipping of 3d characters behind backgrounds based on depth within screen and also performance issue. #16530

Closed
5 tasks done
ghost opened this issue Dec 9, 2022 · 12 comments · Fixed by #16961
Closed
5 tasks done
Labels
Depth / Z Issue involves depth drawing parameters.
Milestone

Comments

@ghost
Copy link

ghost commented Dec 9, 2022

Game or games this happens in

ULUS10347

What area of the game

At the start of the game.

What happens

No clipping of 3d characters behind backgrounds based on depth within screen.
Vulkan/Opengl
Screenshot_20221209_181450_2f85358b2198d26f8aca533d68bee793

Software
Screenshot_20221209_181510_2f85358b2198d26f8aca533d68bee793

What should happen

Must render the graphics correctly.

GE frame capture

ULUS10347.ppdmp.zip

Platform

Android

Mobile phone model or graphics card

Vivo Y11 Android 11 Snapdragon 439 Adreno 505

PPSSPP version affected

v1.13.2-2369

Last working version

v1.13.2+

Graphics backend (3D API)

Vulkan

Checklist

  • Test in the latest git build in case it's already fixed.
  • Search for other reports of the same issue.
  • Try resetting settings or older versions and include if the issue is related.
  • Try changing graphics settings to determine if one causes the glitch (especially speed hacks or enhancements/replacements.)
  • Include logs or screenshots of issue.
@hrydgard hrydgard added the Depth / Z Issue involves depth drawing parameters. label Dec 9, 2022
@hrydgard hrydgard added this to the v1.14.0 milestone Dec 9, 2022
@hrydgard
Copy link
Owner

hrydgard commented Dec 9, 2022

Some weird stuff being drawn at the end of the main renderpass:

image

Additionally apparently 044000 is unusually used as a depth buffer, and it's drawn to as well in the renderpass after the main one, zero sized draws though so no pixels are emitted

There's also probably some stuff being done every second frame here, or something - the drawing of the failing-to-depth-test character doens't seem to be happening, it's getting on the screen by a blit from a previous frame. EDIT: Actually it does get drawn here and the depth test properly fails when running the dump, for whatever reason.

@hrydgard
Copy link
Owner

hrydgard commented Dec 9, 2022

Looks like depth issues with this game is nothing new: https://youtu.be/_6wbMzrbbqY?t=2401

IronMan is clipping through the floor in a weird way that I can't imagine is supposed to happen.

The nature of the problem seems to have changed with recent fixes though indeed and there's some puzzle piece missing here...

Anyway let's step through the frame.

Framebuffer 04000000, texture from 04088000. Five rects drawn. No idea what for?

Framebuffer 04088000, depth 04040000, clear all 480x272

Framebuffer 04088000, scene is rendered., color depth 8888

Around draw 528 some block transfers and stuff is going on, block transfering depth. This is something we don't currently support. There's a mix of rectangle prims and block transfers, gonna need to look into this in more detail:

image

After all of that, it draws the iron man character on top of 04088000, and then renders HUD. So presumably it has biased the depth buffer or something to suit it? probably rendered with a different projection or something, who knows why...

As part of the weird sequence above, this gets logged: CLUT16 fb_format not matching framebuffer of format 8888 at 04088000/512.

As simple as the game looks, won't be able to solve this before the release.

@hrydgard hrydgard modified the milestones: v1.14.0, v1.15.0 Dec 9, 2022
@ghost
Copy link
Author

ghost commented Dec 9, 2022

In v1.13.2 the character is render properly but there's a clipping issue and also have better FPS.

Video_ppsspp_v1.13.2.mp4

But in the recently build the game become slow and render incorrectly.

Video_ppsspp_v1.13.2-2369.mp4

@hrydgard
Copy link
Owner

hrydgard commented Dec 9, 2022

I could do a compat.ini hack that restores the game to how it was in 13.2, I guess (disable color->depth reinterpret, which is what seems to be happening here but only half of the process is working due to the missing block transfers, breaking it).

Also, any real solution will make it at least as slow as it is now, unfortunately :(

@ghost ghost changed the title IronMan No clipping of 3d characters behind backgrounds based on depth within screen. IronMan No clipping of 3d characters behind backgrounds based on depth within screen and also performance issue. Dec 9, 2022
@ghost
Copy link
Author

ghost commented Dec 10, 2022

Another glitch found
Screenshot_20221210_223813_2f85358b2198d26f8aca533d68bee793
ULUS10347.ppdmp.zip

I also notice that Opengl performance is better compare to vulkan on this game.

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Dec 10, 2022

Here's an edited frame dump of that:
#16530_ULUS10347_ironman_sky_edit.zip

It looks the same from a real PSP (I stripped out all the block transfers, etc.):
#16530_ULUS10347_ironman_sky_edit

So I don't think that's a bug.

After all of that, it draws the iron man character on top of 04088000, and then renders HUD. So presumably it has biased the depth buffer or something to suit it? probably rendered with a different projection or something, who knows why...

As part of the weird sequence above, this gets logged: CLUT16 fb_format not matching framebuffer of format 8888 at 04088000/512.

So here's what's happening:

  • It draws the scene using regular depth testing, >=, proj scales Z by 1.041656 and subtracts double that.
  • Starting at 525/753, it does the following:
    • Block transfer a 64x272 slice of the depth buffer from 0x04044000 (zbuf) -> 0x04088780 (framebuffer margin.)
    • It packs this into the 32 pixel wide 32-bit margin (so 64 at 16-bit), so we're effectively converting depth to 32-bit in the renderer. It'd be more efficient to just create a new framebuf for the margin and keep it 16 bit...
    • It does a CLUT16 pass that looks at (depth >> 8), i.e. ignoring the lower 8 bits.
    • It loads a CLUT where the values are essentially 125, 250, 376, ..., 31848, 31973. This effectively scales the depth by about 49%, and rounds it off as well.
    • The scaled depth is written back to the depthbuffer using 565.
  • At 534/753, we're drawing using the new depthbuffer. Viewport is the same, test is the same - but now proj matrix uses 1.020386 and subtracts 1.020386. Note that 1.020386/(2*1.041656) is approximately the factor it scaled depth by.
  • Since it does a >= test, that means larger is nearer. So effectively the scaling added double the space for objects to be near the camera (maybe for z clipping reasons?)
  • In the particular scene above, the character is so far away, they ought to fail the depth test even if the scaling didn't happen.
  • After drawing the character in the background, it wipes depth at 746/753, confirming the scaling was just for that part.
  • Note that it also clears depth again at 5/753 (i.e. next frame), so the clear at 746 seems pointless (maybe there's some other thing it sometimes depth tests on top...)

Ultimately, the confusion comes from packing the temp data in the margin, probably because they didn't want to render-to-self (which as we've seen in other games, might've actually worked fine, especially 1:1.)

I suspect this entire effect could've been done more efficiently by the game by simply manipulating the viewport Z params with margin, to control clipping and what depth values were written. Or even using max Z, perhaps.

Here's an edited version of the original framedump, which uses rendering for all the block transfers:
#16530_ULUS10347_ironman_clip_edit.zip

-[Unknown]

@hrydgard
Copy link
Owner

hrydgard commented Feb 13, 2023

Thanks for the writeup @unknownbrackets . Finally got around to implementing this, it simply took detecting these block transfers and handling them as depth blits (plus allowing it to create and choose a new framebuffer for that margin instead of detecting the color one), the rest just worked.

There is a little bit of polygon glitchiness in few locations similar to what @Gamemulatorer reported above, but doens't hinder playability. I'm gonna test on real hardware tomorrow as well.

@hrydgard hrydgard modified the milestones: v1.15.0, v1.16.0 Feb 15, 2023
@hrydgard hrydgard reopened this Feb 15, 2023
@hrydgard
Copy link
Owner

hrydgard commented Feb 15, 2023

Some mobile devices still have issues here plus it runs really slow, reported in #16961.

I might look at different solutions for them in the future.

@ghost
Copy link
Author

ghost commented Feb 24, 2023

The no clipping of 3d character behind background is fix in the recently build maybe fix via #16961 I'm loading the game using my savestate.

Screenrecording_20230225_002756_org.ppsspp.ppsspp.mp4

But the performance is worst in vulkan compared to opengl.

@hrydgard
Copy link
Owner

Is the "clipping" fixed for you in OpenGL too?

It's expected that the fix isn't very fast, unfortunately. The game is doing some evil tricks.

@ghost
Copy link
Author

ghost commented Feb 25, 2023

Is the "clipping" fixed for you in OpenGL too?

Yes!

Screenrecording_20230225_104815.mp4

@ghost
Copy link
Author

ghost commented Mar 6, 2023

Closing this because the real issue of this game is fix.

@ghost ghost closed this as completed Mar 6, 2023
@unknownbrackets unknownbrackets modified the milestones: v1.16.0, v1.15.0 Apr 20, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Depth / Z Issue involves depth drawing parameters.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants