Post Reply 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Graphics Issues
05-22-2013, 12:26 AM
Post: #1
Graphics Issues
I found the source of the problem, build 0.7.6-461-gf2b4c4a.

Pre rounding the colortest/alphatest reference value seems to mess up Naruto Shippuden Kizuna Drive and probably other games like Ultimate Ninja Heroes 3. Since that build the games won't render properly.

I think this could also be the cause of the text rendering issues.

Naruto Shippuden Kizuna Drive

[Image: device_2013_05_21_204936.png]

[Image: device_2013_05_21_210319.png]

Text Rendering

[Image: device_2013_05_21_205438.png]

[Image: device_2013_05_21_205708.png]

Naruto Shippuden Ultimate Ninja Heroes 3

[Image: device_2013_05_21_203240.png]

[Image: pong8.png]
Find all posts by this user
Quote this message in a reply
05-22-2013, 05:13 AM
Post: #2
RE: Graphics Issues
Well, I shouldn't say preround maybe. A better way to put it would be "don't convert colortest/alphatest values to float just to convert them back to integers again." Clearly there's something wrong, but I'm not sure what it is.

I suspect that the rounding (0.5) is not working correctly, but on my Android, it doesn't work correctly without it (at least for alphatest.) Maybe it needs to use even/odd rounding or something... ugh.

Do you have a compiler to test a few things? The trouble is, I don't have any games (that I know of) which this caused problems for, so it's hard for me to debug. If you (or someone reading this topic) can try things, this is the line to try a few variations of:

WRITE(p, "if (roundAndScaleTo255v(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);

First off, does it change things to comment it out? That will confirm that it's incorrectly discarding when it shouldn't.

Next, what about:

WRITE(p, "if (floor(v.rgb * 255.0) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);

If that does work, then it's a rounding issue. Another thing worth trying:

WRITE(p, "if (floor(v.rgb * 255.0) %s u_alphacolorref.rgb) if (roundAndScaleTo255v(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);

If that works, it probably doesn't discard quite enough, but it could be a better situation than currently, and I think (?) it might not hurt performance for the common case.

Find all posts by this user
Quote this message in a reply
05-24-2013, 12:05 AM (This post was last modified: 05-24-2013 12:58 AM by Denizen.)
Post: #3
RE: Graphics Issues
The problem appears to be the alpha.

This appears to fix the problem:

WRITE(p, "if (floor(v.a * 255.0 + 1.75) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);


Now I see artifacts that weren't in 0.7.6-460-g6cdf5ea:
[Image: device_2013_05_23_215511.png]
Find all posts by this user
Quote this message in a reply
05-24-2013, 12:58 AM (This post was last modified: 05-24-2013 12:58 AM by [Unknown].)
Post: #4
RE: Graphics Issues
Well, 1.75 is *definitely* wrong. But there are a few things that could be going on here... let me explain.

PSP games can set an "alphatest". It has four separate settings: enable/disable, reference value, mask, and operation.

Masks aren't currently supported (GLES doesn't support integer masking), although I have an idea for supporting most of the values we've seen ( but I'm not sure of any issues it causes to verify it well..

That said, assuming you have turned on server compatibility reporting, this game isn't showing in that list so it's not likely to be using an alphatest mask. Most games don't.

Anyway, the alphatest otherwise compares the alpha of *each pixel* to the reference value. The comparison operator can be ==, !=, <, <=, etc. If the alphatest passes (e.g. if they are ==), it draws the pixel.

Due to either simplicity or (iirc?) bugs in certain cards/drivers, we reverse the operation: we change "==" into "!=", and don't draw it if it fails. That's the "discard" in the line.

Anyway, the reference value is between 0 and 255 - the alpha value. It's specified as an integer.

The alpha value in OpenGL is a float, and is affected by things like texture mapping. So, for example, the alpha value it calculates may be "0.498" (between 0.0 = 0 and 1.0 = 255), which actually means "127" is "alpha reference value" language. Make sense?

So, floor(v.a * 255.0) scales this properly to 0 - 255, so that it looks like the reference value. The problem is, it still has a pesky decimal point. For example, "0.5" would turn into "127.5". If the alphatest is "!= 128", then it will draw things it shouldn't, because 127.5 != 128.0 is true. And floor makes that 127.0, not 128.0.

Adding 0.5 makes it always round up (like you were taught in math class.) I don't know, but the PSP itself might be doing even/odd rounding (common in computers to prevent bias) or it may do its math in a way that doesn't even need rounding for alpha.

In any case, 1.75 is too high - that's more than rounding up, that's totally changing the value. So now, "127.5 != 128.0" turns into floor(127.5 + 1.75) = floor(129.25) = 129, so "129.0 != 128.0". The test still won't pass correctly.

It'd be useful to see what operator it's using. Can you do a frame dump (Debug -> Dump Next Frame To Log) and paste a link to the result here? You may have to select the option more than once if the game doesn't (internally) run at 60 fps.

Find all posts by this user
Quote this message in a reply
05-24-2013, 02:59 PM (This post was last modified: 05-25-2013 09:27 PM by Denizen.)
Post: #5
RE: Graphics Issues
But it worked fine before this build:

I reverted to the same code as before the commit and the graphics still aren't perfect.
Perhaps other files were changed that are causing the problem.

It seem this problem was discussed here:

The problem was fixed in build 0.7.6-556-g3601723

However the problem still appeared, so any commits between 461-556 should be examined.
Find all posts by this user
Quote this message in a reply
05-26-2013, 12:08 AM
Post: #6
RE: Graphics Issues
The following is a list of all changes to GPU/GLES from v0.7.6-461 to v0.7.6-556:

Fix objects showing through road in Ridge Racer. Clears can set whether...
Keep track of whether a texture has alpha.
Ignore texfunc RGBA when texture is full alpha
Detect clears, replace with glClear(). Needs more testing, disabled for now
Only double the color with color doubling.
Implement DXT3 alpha.
Improve GE disasm for a few commands.
Merge pull request #1767 from unknownbrackets/texcache
Merge pull request #1787 from unknownbrackets/gpu-minor
Don't use ivec in the fragment shader.

One of these are the source of the problem...
Find all posts by this user
Quote this message in a reply
Post Reply 

Forum Jump: