hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.19k stars 2.17k forks source link

Weird alpha bug in Kenka Bancho #8970

Closed LunaMoo closed 8 years ago

LunaMoo commented 8 years ago

Starting from v1.2.2-371-g2c84411 / https://github.com/hrydgard/ppsspp/commit/2c84411426fa74c6b2eefb62c6b7441c696fa697

How it looks now: glitch How it looked/should look: preglitch

Settings:

Clear mode  0
Framebuffer 00088000, w=512
Framebuffer format  8888
Depthbuffer 00110000, w=512
Vertex type u16 texcoords, ABGR 8888 colors, s8 normals, float positions, u16 indexes
Offset addr 09000000
Vertex addr 092e4e88
Index addr  092e25e8
Region  0,0 - 479,271
Scissor 0,0 - 479,271
Min Z   000000
Max Z   00ffff
Viewport Scale  240.000000, -136.000000, -32767.500000
Viewport Offset 2048.000000, 2048.000000, 32767.500000
Offset  1808.000000x1912.000000
Cull mode   front (CW) (disabled)
Color test  pass if (c & 000000) NEVER (000000 & 000000) (disabled)
Alpha test  pass if (a & ff) > (e5 & ff)
Stencil test    pass if (00 & ff) ALWAYS (a & ff)
Stencil test op fail=KEEP, pass/depthfail=KEEP, pass=REPLACE
Depth test  pass if src >= dst
Alpha blend mode    add: src.a, 1.0 - src.a
Blend color A   000000
Blend color B   000000
Logic Op    inverted (disabled)
Fog 1   3800.000000
Fog 2   0.000556
Fog color   ffd6d6
RGB mask    000000
Stencil/alpha mask  000000
Morph Weight 0  0.000000
Morph Weight 1  0.000000
Morph Weight 2  0.000000
Morph Weight 3  0.000000
Morph Weight 4  0.000000
Morph Weight 5  0.000000
Morph Weight 6  0.000000
Morph Weight 7  0.000000
Patch division  001010
Patch primitive triangles
Patch facing    000001
Dither 0    001d0c (disabled)
Dither 1    00f3e2 (disabled)
Dither 2    000c1d (disabled)
Dither 3    00e2f3 (disabled)
Transfer src    00000000, w=0
Transfer src pos    0,0
Transfer dst    00000000, w=0
Transfer dst pos    0,0
Transfer size   0,0

Texture:

Tex U scale 13.543213
Tex V scale 5.000000
Tex U offset    -13.042969
Tex V offset    -4.000000
Tex mapping mode    gen: tex coords, proj: pos
Tex shade srcs  s: 0, t: 0
Tex mode    swizzled, 1 levels
Tex format  CLUT4
Tex filtering   min: linear, mag: linear
Tex wrapping    wrap s, wrap t
Tex level/bias  slope + bias: -7.500000
Tex lod slope   0.799988
Tex func    modulate, RGBA
Tex env color   000000
CLUT    040c3f80, w=0
CLUT format ABGR 8888 ind & ff
Texture L0 addr 090ba3c0, w=128
Texture L1 addr 090b98c0, w=32
Texture L2 addr 090b7080, w=32
Texture L3 addr 09e87210, w=32
Texture L4 addr 00000000, w=0
Texture L5 addr 00000000, w=0
Texture L6 addr 00000000, w=0
Texture L7 addr 00000000, w=0
Texture L0 size 128x128
Texture L1 size 32x32
Texture L2 size 32x32
Texture L3 size 32x8
Texture L4 size 1x1
Texture L5 size 1x1
Texture L6 size 1x1
Texture L7 size 1x1

A bit weird, but when stepping prim in GE debugger for the grass texture, it's drawn correctly for that frame.

LunaMoo commented 8 years ago

Changing:

entry->fullhash = QuickTexHash(replacer, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);

back to:

u32 fullhash = QuickTexHash(replacer, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);

fixes this, @unknownbrackets ? https://github.com/hrydgard/ppsspp/commit/4ce02e0920646fa38f5ab3adf40fc74963141126

unknownbrackets commented 8 years ago

nextNeedsRehash explicitly means entry->fullhash needs updating. That code was just a dumb mistake, introduced in 6bd86f462d1f90c3e65d1e64dfb777248ce4c09c. I assume it worked prior to that commit?

In that scenario, we're rebuilding the texture because of something other than a hash change. If we don't set its hash, we'll rebuild it again if the hash also happened to change, which will just waste time.

If you replace these lines:

        gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
        gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;

With:

        gstate_c.textureFullAlpha = false;
        gstate_c.textureSimpleAlpha = false;

Does it also "fix" it?

-[Unknown]

LunaMoo commented 8 years ago

Yes, changing those to false has same effect as reverting that line. Also yes it worked in earlier versions, I just didn't notice that code in whole was part of it when checking what started the glitches from the end.

unknownbrackets commented 8 years ago

Hmm, is there another game that reproduces this?

I'd suggest logging here:

entry.SetAlphaStatus(alphaStatus, level);

Something like:

if (entry.addr == 0x090ba3c0) {
    NOTICE_LOG(HLE, "alphaStatus -> %x, fmt=%d, bufw=%d, size=%dx%d", alphaStatus, dstFmt, bufw, w, h);
}
entry.SetAlphaStatus(alphaStatus, level);

And see what's different between entry->fullhash and u32 fullhash. Somewhere it must be detecting the alpha status incorrectly... but assuming you're not using replacements, BuildTexture() should always set those, so I don't see why making the hash invalidate once would help...

Maybe somewhere is reading textureFullAlpha too early... you could add logging to each place that reads it (when the current texture matches that address), and see if anywhere reads it before it's set?

-[Unknown]

LunaMoo commented 8 years ago

Didn't played much so don't really know, but Kenka Banchou jp version has a demo ~ http://www.pspdemocenter.com/demos/NPJH90015/EBOOT.PBP the glitch can be reproduced by watching first cutscene, main character hair seems affected althrough it's kind of hard to notice without comparing:

npjh90015_00001 npjh90015_00000

Edit: as for the log from the grass texture, both show only this, once:

alphaStatus -> 4, fmt=5121, bufw=128, size=128x128
unknownbrackets commented 8 years ago

Pretty sure something is reading it early... hunting it down.

By the way, I think I never realized this had a demo. Darn.

Broken by: 010a7ac1af0ca39f2f8cee8ef685069ed582944f, actually not, was wrong even before that.

-[Unknown]

unknownbrackets commented 8 years ago

Okay, that should do the trick. May fix similar glitches in other games too.

-[Unknown]

LunaMoo commented 8 years ago

Thanks for fixing:). As for demo I just found it on this list http://apps.curtrostudios.com/pspdemos/ which someone recently linked either in some other issue or forums. Stores only xpd files, but link can be found inside with any text editor. Might be usefull since it has a lot of japanese games demos and those tend to often be quite literally "hidden" on official game sites even through it should be part of advertisement.