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.36k stars 2.18k forks source link

"Fog" in 3rd Birthday #1778

Closed dbz400 closed 11 years ago

dbz400 commented 11 years ago

The "fog" is basically the side effect of our current fake grey image .It can only be resolved by implmenting the video support .

3ead3ec6-baa2-11e2-9a29-3a1d6148108b

unknownbrackets commented 11 years ago

That branch has this commit which fixed it, right?

bb99e72c5c5966cbdbf249cafec50cdbd5d07557

I'm not at all sure this is the right fix (since I still suspect the video should not be rendered on top at this point in the game...), but that implies that full video support is not needed to fix this bug, right? Before this commit, it had horrible artifacts (much worse than simple fog.)

(that said, it's definitely possible that sceMpeg or some call wipes the memory to 0 after the last frame, or else that the last frame of the video should be black, and that this game is just being lazy.)

-[Unknown]

dbz400 commented 11 years ago

Let me test it , not too sure if it is the same bug :)

Definitely full video support will fix this bug , i already tested on my own mpeg build

dbz400 commented 11 years ago

Just tested , it fixed this bug indeed. However , i think oioitff reverted in later time as it crash God of War

https://github.com/oioitff/ppsspp/commit/a056e270f71fe43d6620f8807dfa25d0bf0ac85f

Anyway , i think our current master sceMpeg is pretty out of dated and oiotff one may be already fixed that not ending properly issue .

unknownbrackets commented 11 years ago

FWIW, Sword Art Online has this issue too (or something very similar to it.)

-[Unknown]

unknownbrackets commented 11 years ago

Is backbufTex ever cleared back to black after hitting a RAM texture? Not sure of my understanding of the code.

-[Unknown]

dbz400 commented 11 years ago

Retested with latest source here for 3rd birthday . Audio chopping in CG issued fixed however fog issue is still here and pretty serious

3rd

dbz400 commented 11 years ago

Getting better but still some visible dotted line on the right side .

3rd

dbz400 commented 11 years ago

Looks like those dotted lines are come from the incorrect return from sceMpegAvcDecodeFlush()

unknownbrackets commented 11 years ago

Sword Art Online works with this hack, so I can confirm it's the same underlying issue:

        if (psmfplayer->mediaengine->stepVideo(videoPixelMode)) {
            int displaybufSize = psmfplayer->mediaengine->writeVideoImage(Memory::GetPointer(displaybuf), frameWidth, videoPixelMode);
            gpu->InvalidateCache(displaybuf, displaybufSize, GPU_INVALIDATE_SAFE);
        } else if (psmfplayer->status == PSMF_PLAYER_STATUS_PLAYING_FINISHED) {
            NOTICE_LOG(HLE, "I could be blanking out the frame right now.");
            switch (videoPixelMode) {
            case TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888:
                Memory::Memset(displaybuf, 0, frameWidth * 272 * 4);
                break;
            default:
                Memory::Memset(displaybuf, 0, frameWidth * 272 * 2);
                break;
            }
        }

In fact, when status == PSMF_PLAYER_STATUS_PLAYING_FINISHED, the firmware does seem to draw something (for 2 frames)... which appears to just be the last frame. It definitely does not zero out the memory AFAICT. So the above is wrong.

3rd Birthday uses sceMpeg instead of scePsmfPlayer, and you can end the video early. It doesn't seem to call sceMpegAvcDecode() again in this case, so the above tactic doesn't seem like it could apply...

Hmm.

-[Unknown]

unknownbrackets commented 11 years ago

Looks like the issue with Sword Art Online is the alpha channel. On a PSP, alpha channel is 0, but we fill it. This means the last frame is not all zeroes.

My worry is that some games may expect alpha? Not sure. Hmm.

The problem in 3rd Birthday is different (I was really hoping they'd be the same.) After you exit, it just calls sceMpegAvcDecodeFlush() and deletes. Shortly after, an FBO is created for the RAM it used to render to.

What's more, 3rd Birthday uses sceDmacCopy() to copy the decoded video to the framebuffer, and after canceling the video, it doesn't seem to do this. So even blanking out the decode output would change nothing here.

Hmm. Doing a bunch of logging, here's where it creates the FBO from that dirty VRAM:

11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexWrap mode: 1 Offset: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexFunc 0 RGBA modulate
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 CullFace enable: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Lighting enable: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Z test enable: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Alpha test enable: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Fog enable: 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexWrap 000101
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture U scale: 1.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture V scale: 1.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture U offset: 0.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture V offset: 0.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Blend mode: add src.a, 1.0 - src.a
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Blend fix A: 000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Blend fix B: 000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 FramebufPixelFormat: 2
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 FramebufWidth: 262272
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 FramebufPtr: 00154000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Scissor TL: 0, 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Scissor BR: 127, 63
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Region TL: 0 0
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Region BR: 127 63
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Offset X: 31744
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Offset Y: 32256
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Viewport param 0: 64.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Viewport param 1: -32.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Viewport param 3: 2048.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Viewport param 4: 2048.000000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture map enable: 1
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexFilter min: 1 mag: 1
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture BUFWIDTHess 0: 040200
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture address 0: 088000
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 Texture size 0: 000909, width : 512, height : 512
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexFlush
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexMode 000000 (no swizzle, 0 levels, shared clut)
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexFormat 000007 (CLUT32)
11:46:467 idle0                N[HLE]: GPUCommon.cpp:450 TexFlush
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Clut format: 000f32 (ABGR 4444)
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 TexFunc 0 RGBA modulate
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 CLUT addr upper 00080000
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 CLUT base addr: c9b2c0
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Clut load: 000001
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 TexFlush
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Alpha blend enable: 0
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Material ambient color: ffffff
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Material alpha color: 0000ff
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Material diffuse color: ffffff
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 Material specular color: ffffff
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 BASE: 080000
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 CMD JUMP - 08c5ca50 to 08c5ca68
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 SetVertexType: through, u16 UVs, u16 coords
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 BASE: 080000
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 VADDR: c5ca54 => 08c5ca54
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 DrawPrim type: RECTANGLES count: 2 vaddr= 08c5ca54
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 BASE: 080000
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 CMD JUMP - 08c5ca7c to 08c5ca94
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 SetVertexType: through, u16 UVs, u16 coords
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 BASE: 080000
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 VADDR: c5ca80 => 08c5ca80
11:46:468 idle0                N[HLE]: GPUCommon.cpp:450 DrawPrim type: RECTANGLES count: 2 vaddr= 08c5ca80

The source is actually an FBO - curious that it uses it as a CLUT32 texture. Hmm.

-[Unknown]

ShradeTriviant commented 11 years ago

Can someone tell me which version/how to fix Sword Art Online? I can't even play it. (Stuck at the first image)

dbz400 commented 11 years ago

Issue resolved. Closed

unknownbrackets commented 11 years ago

I don't really consider this resolved, it's still a bug. There's a hack that changes the situation in Sword Art Online to missing text.

It turns out that the fog in 3rd Birthday for example is actually a badly detected render-to-texture. At the time, there's a 128x64 FBO at 0x04154000, and there's also a texture being rendered from 0x04154000 that happens to be 128x64. Both have the same stride too. I should've found this before.

Looking into that, which will probably be the correct fix to this problem...

SAO is more complex. Here are some FBOs (256 is the stride): 041a2000 480/256x272 041b4000 480/256x272 (note: 144 lines after the last one) 041bc000 480/256x272 (64 lines after) 041c0000 480/256x272 (32 lines) 041c2000 480/256x272 (you guessed it, 16 lines)

Here are some textures (256 is the stride): 041a2d00 512/256x512 (6.5 lines into first FBO? stride overwritten?) 041b4500 512/256x512 (140 lines after last texture) 041bd100 512/256x512 (70) 041c1700 512/256x512 (35) 041c3b00 512/256x512 (18) 041d3000 512/384x512 (122.5 lines later, so probably its own thing...)

These textures and FBOs overlap in evil ways. Both use BGR5650 so it's likely this is intentional. The FBOs in total theoretically cover the range between 041a2000 - 41e4000, and the textures use 041a2d00 - 41fffff (well, per the height and stride 4233000, but that's outside VRAM...)

I'm not sure what they're doing, but I'm guessing it was to try to get the most out of the GPU. Seems like some sort of effect.

There are others though, like the texture at 041cefc0 (256/256x64, format CLUT8) which might be inside the FBO at 041c2000 (480/256x272, format BGR565) I assume this is just the height of the FBO being wrong, though (it might be the text that goes away with the copy to memory setting.) This is a little lower than 100 lines from the top of the FBO. They're probably simply not drawing there.

-[Unknown]

unknownbrackets commented 11 years ago

Ah, the 3rd Birthday texture is GE_TFMT_CLUT16. Maybe we just need to set the FB dirty and needing a flush (to the RAM that the texture needs, so it doesn't overflow)? Probably the FBO has a solid color and they're just using it to render fog/flash effects when necessary?

-[Unknown]

unknownbrackets commented 11 years ago

Looks like this affects Tales of Phantasia X and Narikiri Dungeon X as well, most likely. Need to look into them more.

-[Unknown]

dbz400 commented 11 years ago

@unknownbrackets , fog in 3rd birthday , if it is badly render-to-texture , i think non-buffered rendering should fix it since it will ignore those stuff but somehow it is not .....

unknownbrackets commented 11 years ago

@raven02 so here's what's happening, basically:

  1. Video writes random pixels to memory @0x04154000.
  2. GPU renders a bunch of 0 pixels to 0x04154000, using BGR5650 (which is 16 bits per pixel.) On a PSP, the video RAM now contains 0s.
  3. A texture is referenced from 0x04154000. However, it uses a 16-bit CLUT. It's still using exactly the same area of VRAM. On a PSP, this means the texture is fully black.
  4. In PPSSPP, we detect the render-to-texture, but since it's a CLUT texture, we ignore it (exactly like buffered rendering would.)

-[Unknown]

dbz400 commented 11 years ago

I see. So did the FB set dirty trick work ? I can help to test it out if needed.

hrydgard commented 11 years ago

@unknownbrackets , nice investigation and summary!

I guess there are a couple of alternatives:

unknownbrackets commented 11 years ago

I wonder if we can send an array of 256 vec4s to the GPU, and render to an FBO just for the texture? We can know the palette it can use and parameters at that point. Then we could keep the de-CLUTing cached, and it would still optimize palette swapping a bit (if we kept around the origin.)

I'm not sure. Flushing the FBO at that point makes sense, although I would use some sort of dirty impl (just how far into the texture is dirty based on texture size, so that inaccurate height estimation doesn't break things.)

-[Unknown]

hrydgard commented 11 years ago

I think a lot of mobile GPUs don't allow as many as 256 vec4 uniforms. Putting them in a secondary 256x1 texture is probably the way to go.

unknownbrackets commented 11 years ago

Hmm, okay. Anyway, with that method, we can't have any filtering, right? (https://github.com/hrydgard/ppsspp/issues/970#issuecomment-17140845)

-[Unknown]

hrydgard commented 11 years ago

We can, but manually and expensively ( mix(mix(sample(palette, texel1), sample(palette, texel2), frac(u)), mix(sample(palette, texel3), sample(palette, texel4), frac(u)), v) .

Same goes for the vec4 array, you just replace the texture sampling with array lookups and you still have to filter manually.

unknownbrackets commented 11 years ago

Oh, sorry. If we still use a temporary (1:1 scale) FBO or something, we could still get bilinear filtering without such a hit, though, I think. I know we are starved for VRAM on some devices, though...

-[Unknown]

hrydgard commented 11 years ago

Oh yeah, that's possible too, do the palette lookups into another fbo then sample that normally. Should work fine.

JulianoAmaralChaves commented 11 years ago

Personally, I have nothing of experience in the subject, but I found a patch of "oioitff" two months ago that corrected this problem, I did a test here and it worked fine on my PC but do not know if this will cause any problems.

Includes the fix in patch # 2541, but I think it is not the most appropriate solution

3rd

dbz400 commented 11 years ago

Read framebuffer to memory should fix this issue right now . Closing it .

solarmystic commented 11 years ago

This specific 3rd Birthday issue still seems to be resolved(?) in the latest revisions (0.8.1.-795) tested provided you've switched the rendering mode to use Framebuffers to memory (CPU) (or (GPU) on NVIDIA cards)

I'm not sure why it ought to be reopened again.

With Framebuffers to memory (CPU) enabled:-

cpuon

Without Framebuffers to memory (CPU):-

cpuoff

hrydgard commented 11 years ago

Hm, alright then. Closing this again and reopening the new one.

unknownbrackets commented 11 years ago

God to know. Sounds like we will be able to close all bugs once the software renderer is finished since performance doesn't matter. Then they won't even need to be hacks either.

-[Unknown]

hrydgard commented 11 years ago

It would be great if this worked without the framebuffer copies but it seems that it will indeed require hacks no matter what (lack of framebuffer copy can itself be considered a speed hack).

Anyway, I'm mostly closing this issue because it's becoming large and unwieldy and contains lots of not necessarily relevant stuff.

unknownbrackets commented 11 years ago

Well, the framebuffer copy wouldn't be a hack only if it loaded from ram, drew, and then copied back to ram for each displaylist/framebuffer. The feature as it exists now is imho a hack, although it isn't practical to trash OpenGL like that.

The texture cache, framebuffers, even jit can be considered a hack. But for example, the LittleBigPlanet video issue wasn't closed when jit no longer had that issue. It seems to have been fixed upstream in MSVC 2012, which might be the end of that story, though.

Same with the "God of War speed issues" bug. It's still open, even though a hack was introduced which works around it (which did fix a bug, but only by removing another hack that wasn't as effective and was breaking other games.)

-[Unknown]

kelvinren commented 11 years ago

about the issue that i post which can fix by enabling Framebuffers to memory (CPU / GPU) When i enable that option, it seem thoose texture bug fixed but all the words are gone. glitch

dbz400 commented 10 years ago

Just for record . Blue fog in latest build .

2dd0dfca-5ce3-11e3-954f-dc0bb6e95bc1

papel commented 10 years ago

Blue fog explained in https://github.com/hrydgard/ppsspp/issues/3354.

hrydgard commented 10 years ago

Now the blue fog seems to display a slight bloom effect. I think it's partially intended but too strong, like what we've previously seen in God Eater but the mechanism must be a bit different.

thedax commented 10 years ago

I think a screenshot from a real PSP would help here, so we have a better idea of what it should look like.