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

Refactor framebuffer attachment. Fixes Test Drive Unlimited performance #13355

Merged
merged 5 commits into from
Aug 31, 2020

Conversation

hrydgard
Copy link
Owner

@hrydgard hrydgard commented Aug 29, 2020

Turns on virtual framebuffer copies for Test Drive Unlimited. With this, the game now runs great even on mobile (with Vulkan, at least - haven't yet tested other backends).

Switches framebuffer attachment to a scoring model, where we add a little bonus for matching stride.

Unfortunately, there's some banding, as can be seen in this screenshot, look at the shadow:

ULET00386_00002

Explanation for the banding:

The slow thing the game is doing (which, with this change, no longer requires CPU readbacks) is color correction. It does this by tiling the display, and for each tile look up R, G and B of the rendered framebuffer in a table, separately, adding the outputs of the lookups together. Now, on the real PSP it renders to a 16-bit buffer (565) with dithering, and the dither kind of comes along for the ride through the lookup so the banding isn't so bad.

Now, in PPSSPP, we always render at full 8888 color resolution. When the game uses channels of the framebuffer to look up in a palette, we simply downgrade the (undithered) color and use that for the lookup. No dithering, so we get banding.

We could either dither the converted color values during the lookup according to the pixel coordinate, or we could linearly filter the palette with the extra precision. The latter would not work in many situations though so would require a game specific flag.

The dithering on the original PSP can be seen clearly in this screenshot I found:

787613-932168_20070329_002

Anyway, this at least makes the game very playable without any cheats.

Test Drive has another problem too - the vertex range culling is inaccurate with this game (as we've seen in some other games too), leading to missing triangles. I think we might have to add a compat.ini setting for that unless we can figure out the PSP's clipping once and for all.... (this only affects a beta version of TDU).

@hrydgard hrydgard added the GE emulation Backend-independent GPU issues label Aug 29, 2020
@hrydgard hrydgard added this to the v1.11.0 milestone Aug 29, 2020
@unknownbrackets
Copy link
Collaborator

In theory, the dither should be very easy to apply in the shader.

// Dithering happens before the logic op and regardless of framebuffer format or clear mode.

So basically we'd end up with a 4x4 for the displacements converted from 4 bit signed (applied equally to each of rgb), and then we'd just need to get the X/Y to index into that 4x4. Really, we should probably be applying this even on a CPU download, I guess? Correctly, we should use the dither matrix that was used on draw, but I don't think I've ever seen a game change the dither matrix during drawing.

-[Unknown]

@unknownbrackets
Copy link
Collaborator

If we're uploading the palette from the CPU anyway, we can detect if it's linear, right?

-[Unknown]

GPU/Common/TextureCacheCommon.cpp Show resolved Hide resolved
GPU/Common/TextureCacheCommon.cpp Show resolved Hide resolved
@unknownbrackets
Copy link
Collaborator

Ideally, I'd like to get as many cases of range culling working inaccurately as I can to narrow down the use cases. What would really help me is a simple pspautotest with parameters I could tune, so I could find the break off points. I suspect there's just some case the hardware doesn't cull for, but the behavior has seemed wonky so far and to me that just means I need more data.

-[Unknown]

Reuses the same mechanism.

This is the second part of the Test Drive fix.
…er expensive readbacks.

Write some comments in Depal about how we could get rid of the banding.
@hrydgard hrydgard force-pushed the refactor-framebuffer-attach-2 branch from 65b8c36 to eda4bb2 Compare August 30, 2020 14:22
@hrydgard
Copy link
Owner Author

hrydgard commented Aug 30, 2020

Good idea to detect CLUT ramps on upload - we can do some heuristic (such as "always incrementing values") and decided to interpolate the palette in that case indeed.

Anyway, I'll do that later.

@hrydgard
Copy link
Owner Author

I'm leaving the dither and/or filtered CLUT lookups to future PRs.

@hrydgard hrydgard merged commit f220ab0 into master Aug 31, 2020
@hrydgard hrydgard deleted the refactor-framebuffer-attach-2 branch August 31, 2020 08:25
@hrydgard
Copy link
Owner Author

I checked the CLUT ramps used - they are indeed nice and consistently increasing up to white, where it stays after the first 32 entries (5 bit lookups since the source image has 5 bit color components). So they are detectable.

hrydgard added a commit that referenced this pull request Jul 19, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Jul 19, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Jul 31, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Aug 16, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Aug 21, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Aug 22, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
hrydgard added a commit that referenced this pull request Aug 22, 2022
This implements the hack I suggested in #13355, where instead of first
reducing the color to RGB565 as the real game does, we just take each
channel at full precision and do the lookup according to the mask,
linearly filtering the palette.

This makes the game look a lot nicer and is also a small optimization,
but the hack is very specific so kinda ugly in a way.
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants