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

Black Square Shape Cover the Car - Split Second Velocity USA #7492

Closed tabnk closed 9 years ago

tabnk commented 9 years ago

Black Square Shape Cover the Car. Attached Screenshots

http://i57.tinypic.com/b7j341.jpg http://i62.tinypic.com/27y6v4.jpg

Tested on ppsspp-v1.0-75-g635f43b-windows-amd64.

hrydgard commented 9 years ago

Is this with "Rendering Mode" set to "Buffered Rendering"?

thedax commented 9 years ago

@hrydgard: Apparently this problem has existed for a while, and Buffered on/off doesn't matter:

Sunday, March 9th, 2014, 03:42 AM

"I got mine like this with the newest version of PPSPP
Even Buffered Rendering on/off,the black box won't disseapear.., Undecided
Played on Win 7 32bit"

http://forums.ppsspp.org/showthread.php?tid=1310&pid=77203#pid77203

Getting more up to date info would be useful though.

Edit: We actually have documented this issue somewhat in https://github.com/hrydgard/ppsspp/issues/4472#issuecomment-48102405 but the main subject of the issue is different, so let's continue the discussion here.

tabnk commented 9 years ago

Buffer Rendering Mode is selected and all settings are default. Thank.

http://i58.tinypic.com/23uwwa0.jpg http://i57.tinypic.com/6f06mg.jpg

On Windows 8.1 64-bit.

thedax commented 9 years ago

Renamed for easier searching.

unknownbrackets commented 9 years ago

It seems to be the black box is caused by one of a few possible causes:

  1. The game tries to copy vram to the box before rendering to it, and we don't notice. A breakpoint at 0x041dc000 with a size of at least 0x100 would answer if this is happening.
  2. Blending might have a bug. It's using src * 1.0 + dst * (1.0 - src.alpha). I'm not actually sure why this would result in black, assuming that the src is rgba(0, 0, 0, 0), because that should blend fine. The preview here suggests the texture is that color: https://github.com/hrydgard/ppsspp/issues/4472#issuecomment-48105450
  3. It may be somehow stencil related or related to other settings / logic op / etc. Would need to see GE debugger tabs for this.

It seems like there's a demo so I'm going to try it.

-[Unknown]

unknownbrackets commented 9 years ago

Okay, it does the following:

  1. Renders 0x04000000 (scene) to a temporary buffer at 0x041bc00. This is used to apply bloom.
  2. It clears color/alpha/stencil on 0x041dc000 (this is the black box.) Everything is cleared to 0, so it's rgba(0, 0, 0, 0) at this point.
  3. It then renders the contents of it, which doesn't touch the other portions, so it should still be largely black/transparent.
  4. Then it uses blending to render it. During blending, it's not using any other tests - although depth is disabled. Then blend mode is indeed as described above. The texture is RGBA, no CLUT of course.
  5. The vertices have rgba(255, 255, 255, 255) colors. The texfunc is modulate, but I suppose that should keep a 0 alpha.
  6. It's black right after that; it's not caused by any other rendering or upload or anything.

So, seems like a bug in blending, we may be optimizing it wrongly?

-[Unknown]

unknownbrackets commented 9 years ago

Okay, so using this in StateMapping.cpp:

    if (gstate.isAlphaBlendEnabled() && gstate.getBlendFuncA() == GE_SRCBLEND_FIXA && gstate.getBlendFuncB() == GE_DSTBLEND_INVSRCALPHA && gstate.getTextureAddress(0) == 0x041dc000) {
        //DebugBreak();
        glBlendFuncB = GL_ONE;
    }

Hacks it into working correctly. That means the problem child is the B func - which is GL_ONE_MINUS_SRC_ALPHA otherwise. Dual source is not being used, so I tried this trickery (along with an extra bit for the texture) in the frag shader:

    if (gstate.isAlphaBlendEnabled() && gstate.getBlendFuncA() == GE_SRCBLEND_FIXA && gstate.getBlendFuncB() == GE_DSTBLEND_INVSRCALPHA && gstate.getTextureAddress(0) == 0x041dc000) {
        WRITE(p, "  %s.a = 0.0;\n", fragColor0);
    }

This also fixes it, which means somehow we're ending up with alpha being 1.0 in the shader. It turns out that this fixes it too:

    if (gstate.isAlphaBlendEnabled() && gstate.getBlendFuncA() == GE_SRCBLEND_FIXA && gstate.getBlendFuncB() == GE_DSTBLEND_INVSRCALPHA && gstate.getTextureAddress(0) == 0x041dc000) {
        doTextureAlpha = true;
    }

So, gstate_c.textureFullAlpha is being set incorrectly somewhere.

For some reason the framebuffer is set as 565, but it's drawn as 5551 4444 so that makes no sense. Also, it is used as 4444... hmm. Oh, wait, then it draws 565 on top of that. Weird.

-[Unknown]

unknownbrackets commented 9 years ago

I suppose the color of the text drawn on the car may be incorrect, I think it's switching to 565 to draw maybe a shadow or something (not really sure.) Instead we are just taking the colors as they are.

-[Unknown]

daniel229 commented 9 years ago

Yes,the text colour is not right,and there is a half circle under the car that is missing in OpenGL.

Here is the soft rendering. 01

unknownbrackets commented 9 years ago

Yeah, that requires realizing that it's been rendered to using the wrong format, and converting it on change. Unfortunately, it's going to be hard to handle that correctly without potentially making some games VERY slow unnecessarily (like Kingdom Hearts.)

Anyway, #7509 at least kills the black box. I think we should probably worry about the other glitches separately, since the game is at least playable without the black box.

-[Unknown]

tabnk commented 9 years ago

Will fix be release as upcoming update?

BogdanTheGeek commented 6 years ago

This issue can be fixed by turning on buffered rendering and running in OpenGL (DX 11 is a bit more stuttery).