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

Final Fantasy I icons incorrectly clipped/positioned #12257

Open
bearoso opened this issue Aug 20, 2019 · 14 comments
Open

Final Fantasy I icons incorrectly clipped/positioned #12257

bearoso opened this issue Aug 20, 2019 · 14 comments
Labels
GE emulation Backend-independent GPU issues
Milestone

Comments

@bearoso
Copy link

bearoso commented Aug 20, 2019

What happens?

In some menus, the icons representing an item type are clipped off at the top.
Example:
ULUS10251_00000

Look at the icons next to the item names, particularly the Staff, Rapier, and Hammer. The top row of pixels for each is clipped off.

This menu can be accessed by starting a new game, entering the town, then entering the weapon shop and talking to the character inside. This is not the only location it occurs, but the easiest to access. It also occurs in the "Equipment" menu and Item and Magic menus in battle.

What should happen?

Using software rendering fixes the problem:
ULUS10251_00001

Note that the icons are positioned one pixel lower relative to the text, which prevents the top from being clipped. Maybe a rounding issue?

What hardware, operating system, and PPSSPP version? On desktop, GPU matters for graphical issues.

RX580 Linux, OpenGL/Vulkan (all 3 ICDs), hardware mode only. As far back as I could test from PPSSPP 1.4 to latest git.

@LunaMoo
Copy link
Collaborator

LunaMoo commented Aug 20, 2019

Increasing render res very commonly will cause slight missplacement in graphics since the PSP games are not ment to render above 1x PSP display res, so just try that and change to x1 render resolution.

@bearoso
Copy link
Author

bearoso commented Aug 20, 2019

Yes, this is at 1x PSP resolution. All compatibility options were tested.

@unknownbrackets
Copy link
Collaborator

Here's how it should look on a real PSP (matches your screenshot):
ULUS10251_ff1_offset_icons

Here's what I get in OpenGL (other backends look the same):
ULUS10251_ff1_offset_icons_opengl

The colors are not perfect, but generally they look the same.

This is 2x render resolution at 1x window size:
ULUS10251_ff1_offset_icons_2x

And event 2x at 2x window size, which you appear to at least be using 2x window size:
ULUS10251_ff1_offset_icons_2xw

I can't reproduce this at all on a US version of the game. To me, it looks like you're either forcing bilinear filtering (not letting the game decide with auto), using 2x render resolution, using texture scaling (2x or higher), or maybe using 1x render res with 2x window size and linear screen scaling.

Software rendering is also correct.

-[Unknown]

@bearoso
Copy link
Author

bearoso commented Aug 20, 2019

No, I've messed with all the settings to make sure nothing was causing it. Even started with a clean config. 1xPSP, Auto texture filtering for PSP API. Toggled all compatibility options to no avail.
Even tried booting up Windows and the same problem. Downloaded a new ROM off the internet and did a checksum to make sure it was different from. That ROM exhibited the same problem.

Software rendering fixes it. Also, turning off buffered rendering for some reason mostly fixes it, but it's still clipping a bit like in your 2xPSP resolution shot:
ULUS10251_00000

I thought that it might be high-dpi related, but was able to disprove that. Might be the video card or drivers doing it. I really don't want to have to dig out a NVIDIA card to test with.

@hrydgard
Copy link
Owner

The game probably draws the symbol offset by a fractional pixel and accidentally relies on a quirk in PSP's GPU's sampler hardware, where it's just slightly offset, and when rendering 1:1 with point sampling it happens to roll over to the next pixel.

Can probably be fixed in hardware rendering too by applying a tiny offset when sampling textures, costing a bit of extra overhead for every pixel. Not something that has top priority, since the game plays just fine even with this visual imperfection visible.

@hrydgard hrydgard added this to the v1.10.0 milestone Aug 20, 2019
@bearoso
Copy link
Author

bearoso commented Aug 20, 2019

I'm kind of curious now why I'm getting it and unknown isn't. It looks like my instance is using a 2x framebuffer even though it's set to 1x, because the top row of the icons is half the height of the other pixels, and that would otherwise be impossible. I've ruled out the driver by using llvmpipe.

@bearoso
Copy link
Author

bearoso commented Aug 20, 2019

I've looked at the frame analysis, and in the instances where the icon is drawn incorrectly, it's sampling from the 256x16 texture with integer U coordinates and half-pixel offset V coordinates.

It's a 12x12 icon, so for the Rapier it's 0.0, 0.5 to 12.0, 12.5. With nearest sampling, it incorrectly rounds that up and ends up sampling 0.0, 1.0 to 12.0, 13.0. The text beside it is drawn with both 0.5 offset U and V coordinates (0.5, 0.5 to 12.5, 12.5), and seems like it might have some heuristic in PPSSPP that causes it to round down correctly to integers. In the locations where the icon is drawn correctly in the game, like the "Item" menu, the game uses integer coordinates (0.0, 0.0, to 12.0, 12.0).

So it looks like 0.5 rounding policy is the problem.

edit
For the text, the debugger says it uses signed 16-bit positions, but for the icon, it says floating point positions. The game is specifying 0.5x0.5 pixel offsets for the text, but PPSSPP opts to use integral coordinates. The icon is 0.0x0.5 offset, but it doesn't.

@unknownbrackets
Copy link
Collaborator

I know the PSP rounds at 0.625 in some cases, but iirc it rounds at 0.5 for texture filtering. That said, I don't remember if it consistently rounds down or up at 0.5 - it might round to even. Maybe even NVIDIA rounds to even, since I don't see this bug on NVIDIA.

It does seem to be wrong on Adreno, though.

The icons are drawn in through-mode, which might possibly behave differently than transform-mode with rounding too. That said, both the text and icons use float texcoords (that's what U and V are) and through-mode, so it ought to round the same way. Maybe there's just space above the font so it isn't noticeable.

-[Unknown]

@bearoso
Copy link
Author

bearoso commented Aug 21, 2019

The icons are drawn in through-mode, which might possibly behave differently than transform-mode with rounding too.

I was referring to this:
float

It's the positions, not the texcoords, but nothing else in the frame but the icons uses float positions, they all show s16 instead:
s16

The texcoords are the problem, but could the position format be influencing rounding somehow?

@hrydgard
Copy link
Owner

Different GPUs do this rounding in different ways - it's right on the edge so your results will be different. To reliably simulate what the PSP does on other GPUs we have to apply a slight, slight offset. The offset we need to apply might even be GPU-dependent. So this is not entirely trivial.

@hrydgard hrydgard modified the milestones: v1.10.0, Future Mar 10, 2020
@unknownbrackets unknownbrackets added the GE emulation Backend-independent GPU issues label Apr 11, 2020
@ghost
Copy link

ghost commented Nov 1, 2021

I cannot reproduce this, can you try the latest git build?
https://buildbot.orphis.net/ppsspp/index.php?m=fulllist

@bearoso
Copy link
Author

bearoso commented Nov 1, 2021

Nope, not fixed. Read above--nvidia cards have the same rounding as PSP. It's a problem with other GPUs.

@unknownbrackets
Copy link
Collaborator

Just for reference, 454/792 is where the first icon is drawn in this frame dump:
#12257_ULUS10251_ff1_offset_icons.zip

It's using nearest filtering + throughmode, with X/Y/U at even pixels and V at 0.5. The PSP's nearest filtering seems to round nearest down to the nearest texel, so even 0.99 would round to 0. Most likely, Adreno is rounding 0.5 to 1 here.

-[Unknown]

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Oct 25, 2022

Actually, strange observation: there's presumably more to it. I had written a test at some point comparing WRAP/CLAMP with 0.5 offsets, and looked at it again. A simple (0,0) - (1,1) rectangle with UV (0, 0.5) - (1, 1.5) in throughmode should actually round up (WRAP/CLAMP doesn't change this.) This is because it samples at pixel centers, so the nearest round down is from that center, which would be exactly even.

But the rendering of this frame dump obviously rounds 0.5 down. So it's probably more complicated than that simple rule.

I haven't tried more hardware tests (just looking at existing results), but some differences between the two draws:

  • The FF1 texture is swizzled and my test was using a simple linear texture (could be it?)
  • Test texture is 4x4 square, stride 4 - FF1 uses 256x16 with 240 stride.
  • Maybe a 1x1 rectangle behaves differently than a 12x12 one.
  • The simple test drew everything at 0,0 where this draws to 44,96.
  • MinZ/MaxZ are non-standard in FF1 (unlikely.)
  • Test uses DECAL/RGB instead of MODULATE/RGBA (unlikely.)
  • Test uses 8888 instead of CLUT8/8888 (unlikely.)

Ordered in maybe the likelihood it could matter. Just noting this for any future accuracy testing.

-[Unknown]

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

No branches or pull requests

4 participants