-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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 4 - dialog boxes have "holes" #4617
Comments
Oops, forgot - actually the top middle and top left corner aren't connected either. Editing with details. -[Unknown] |
Hm, are these coordinates supplied as s8, s16 or float? It could be that OpenGL's interpretation of say s16 attributes is off by half or something. In software transform we do the conversion ourselves. |
How to check are these coordinates supplied as s8, s16 or float? (VertexDecoder??) |
Just check the vertex type command before the drawcall in the ge debugger |
SetVertexType: through ,ARGB 8888 colors, u16 coords |
It can just as well be the frame that is off as the box filling background. Are both really through? If so it shouldn't be bothering to set transform matrices per quad.. |
@hrydgard , i think should be this screenshot .It is Float UV , u8 coords |
u8 coords, OK (actually S8). I can imagine that our software mode might be scaling them slightly differently than OpenGL does in hw mode.. |
Well it looks like #5134 6eb493a has made it worse somehow, the issue is still present when HW TnL is enabled:- But now SW TnL (disabling HW TnL) doesn't rectify it anymore. Instead, you'll get the following screen:- In previous revisions (e.g. v0.9.6-463-g091ddd9 091ddd9), disabling HW TnL would solve holes in the dialogue box issue:- |
Oh, maybe I need to ignore hasTexcoord in software. -[Unknown] |
I had actually tested software transform before, but clearly not in the right places. Does it work better now? -[Unknown] |
Much better now with SW TnL, thanks! |
This also affects the world map, and causes a white line to appear persistently (from it drawing the sky.) The game uses raw positions (0,0)-(64,64) using a triangle strip to draw the sky in both cases. The first draw (right side) uses this world matrix: The second draw (left side) uses this world matrix: Unfortunately, this doesn't work properly with or without hardware transform. In both cases, there's overlap. Software actually has greater overlap. The softgpu has the same overlap. Possibly the world matrix is being calculated incorrectly? This hack "fixes" it: if (dirty & DIRTY_WORLDMATRIX) {
if (gstate.worldMatrix[9] == 113.0f) {
NOTICE_LOG(HLE, "HACK");
gstate.worldMatrix[9] = 115.0f;
}
SetMatrix4x3(u_world, gstate.worldMatrix);
} 114 isn't sufficient, but 115 looks perfect. So it seems like it's pretty far off... This happens with jit on or off. -[Unknown] |
Is the game using fixed point coordinates (8-bit or 16-bit)? We may be off by 1/2 unit or so as we rely on OpenGL to convert them to float and it might do it wrong. Although if it's drawing rectangles, we're doing that transform in software ourselves. If it's a mix of draws that go through the two pipes, it may mismatch enough that it becomes a real issue... |
Hm, but maybe we are dequantizing 8-bit coordinates slightly wrong in all modes. I don't have a better explanation that would be plausible... |
With: for (int i = 0; i < 3; i++)
pos[i] = b[i] * (1.f / 128.f); The problem goes away in software transform. Also in the softgpu. -[Unknown] |
Maybe it's that simple then. But then we need to compensate in the shader for OpenGL's 8-bit and 16-bit conversions being wrong, and in that case maybe we might as well expand them to float like that manually in the vertex decoder... |
Okay, I've written a test to verify it. For s8, non-through (these are x coords):
Changing it to 128 makes these match. I still have no idea what I'm doing wrong for s8/through, I can only get it to draw 1 pixel at 0,0 with any coords I throw at it. Still figuring out s16. Throughmode there works as one would expect. Maybe s8/through is simply unsupported, since you couldn't use it very usefully anyway. -[Unknown] |
So s16, these should be the cutoffs:
This is with a "normal" viewport and offset (2048, 2048, 480, 272 - 2048-480/2, 2048-272/2 like most games use.) On the other side, 32708 is the last pixel that should fill 478. 32709 - 32767 fill all through 479. I guess that means they reference 480, since I think (even in throughmode) polygons are non-inclusive or something. Anyway, this suggests that it could be not 128 as above but something more involved. Our cutoffs are wrong, 1 is at -32698, 2 is at -32561, and 3 is at -32425. 32768 makes this -32426, so clearly not the right fix. -[Unknown] |
s8/through is not too useful, dunno if it's used in any games at all. Strange that /128 would work for 8-bit but 32768 not for 16-bit. Polygons probably follow standard fill conventions like OpenGL so that adjacent polys that share some vertices don't overlap (avoids double-drawn pixels which matters when blending). |
I don't understand normals well. Is there any way I could test normals between 127 and 128? -[Unknown] |
Normals can only be tested indirectly, by how they affect lighting and texcoord generation... Should be possible to set up a test but in both cases there will be other factors/precision issues involved too. Getting the lighting very slightly wrong matters a lot less than getting positions wrong though. |
That's true enough. By the way, we've logged s8 being used in throughmode, but maybe they were all corrupted displaylists: http://report.ppsspp.org/logs/kind/526 -[Unknown] |
If we assume it's converted to fixed s.11 point... it might be scaled to ((x + 32768) * 480/4096) on width? I think the drawing space is that size. -32768 -> 0 <-- 0 -32692 -> 8.9063 <-- 0 -32555 -> 24.9609 <-- 1 -32419 -> 40.8984 <-- 2 32708 -> 7672.9688 <-- 478 Those numbers look sorta promising, but I'm just guessing. Obviously it's scaled to the wrong cap, though... The space between pixels (above) would be 16 (4 bits, maybe it's s.11.4?) The point it goes over is at 9, 9+16, 9+16+16, etc. so that would make sense... -[Unknown] |
Well, I think that's basically it. Here's some data: https://docs.google.com/spreadsheets/d/1b2nocvhQw4wfrein6YUxOt8uIvSS4bp7WBtqimZXCBo/edit#gid=0 -[Unknown] |
Floating point seems similar: So basically, it's first scaled to a fixed point with 4 bits behind the decimal, essentially int(pos * 8 * viewport_width) / 16, with the viewport offset applied. It rounds up at 10/16 (1010) which seems odd... Anything that goes outside the bounds of the drawing area [0, 4095] is entirely clipped (no portion of it is drawn.) Games generally center within the drawing area. Haven't tested depth yet. -[Unknown] |
That roundup sounds odd, and not sure how we can emulate that (maybe it's enough to apply a very small lateral offset and then let things round?), but having 4 bits of subpixel precision is pretty normal for the age of hardware the PSP is (2006+ -era chips usually do 8 bits). |
Depth is definitely scaled wrong. Trying to work my head around what z1/z2/minz/maxz do still. -[Unknown] |
Alright, so minz/maxz just clip the entire fragment based on depth (only outside throughmode.) Depth (only tested s8 so far) is definitely scaled by 128 as well, not 127. See: However, there are some rounding issues I'm not sure about. It seems like it rounds the same way as positions (at 0.625 fixed point .4), perhaps so that 0.5 is the "center" of 0? Hmm, actually, not sure. I guess it would make it easier to test this if memcpy() supported depth. That's tricky due to overlapping framebuffers... but maybe best effort would help anyway. Obviously won't work on mobile... -[Unknown] |
Should I add this to the depth metaissue? |
So here's a change that fixes it. Not sure what the performance impact will be on various configurations. https://github.com/unknownbrackets/ppsspp/compare/pos-scale -[Unknown] |
My guess would be a tiny, tiny, maybe not even noticeable performance impact on most hardware, but hard to be sure without testing. |
@unknownbrackets @hrydgard |
Well, @solarmystic this will affect pretty much ALL games. I'm most concerned about games that push a lot of vertices (maybe God of War?), and also not sure how mobile chipsets will react. But it sounds like ATI is reacting well enough. I forget, do you have SSE 4 or not? The s16/s8 stuff uses SSE4 so on supported processors I'm expecting performance not to be much different on desktop, gpu drivers willing. -[Unknown] |
@unknownbrackets My laptop's mobile Core 2 CPU (T9550) is of the Penryn family which supports SSE4.1 so that could be why the performance wasn't visibly impacted |
@unknownbrackets @hrydgard In case you needed a more "holistic" view of the potential impact of your pos-scale branch in other games on my hardware configuration (pretty much ancient tech by 2014 standards):- As you will note, most of the games tested before and after the branch was merged are unaffected performance-wise and the few that are (e.g. Gods Eater Burst, DOA:P, Crisis Core and GTA:VCS) aren't heavily affected. (x<5%) |
This may also be affecting Final Fantasy 3 and Patapon, which have similar "lines" in various places. I have not checked those yet.
Rendering resolution does not impact this. Enabling the vertex cache makes it flicker, but with vertex cache off, the issue is persistent. It looks like this:
Where the ?s represent transparency. Clearly it seems to be an off-by-one sort of issue.
Anyway, FF4's drawing philosophy appears to be "the spoon does not bend." I haven't checked the actual vertices, but it generally adjusts the world matrix for every tile it draws, and this applies to the dialogs as well (for the letters, it adjusts the offset for each letter... this results in a lot of flushes, heh.)
Anyway, the middle center matrix looks like this:
And here's the top left (note, this doesn't meet the middle center above):
And here's the top left (doesn't meet the left side or center):
And the left middle (which DOES meet the top left, but not the middle center):
For good measure, here's the bottom right (this does meet):
My matrix math may suck, but the .5's there are conspicuous. Also, to note the order in which it draws the box, in case it matters:
Where 9, 4, and 2 do not connect to 1.
I suppose this either means an FPU rounding difference, or (more likely?) a difference in the way the GE rounds coordinates.
-[Unknown]
The text was updated successfully, but these errors were encountered: