Skip to content
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

Burnout dominator have lighting issue (recursive rendering in framebuffer border) #11100

Closed
marosis opened this issue May 29, 2018 · 39 comments · Fixed by #16908
Closed

Burnout dominator have lighting issue (recursive rendering in framebuffer border) #11100

marosis opened this issue May 29, 2018 · 39 comments · Fixed by #16908
Labels
GE emulation Backend-independent GPU issues
Milestone

Comments

@marosis
Copy link

marosis commented May 29, 2018

screenshot_20180529-085605
Sun in the tunel?!? OK!!!!!
Backend: OpenGL

@hrydgard
Copy link
Owner

hrydgard commented May 29, 2018

Yeah, I believe the game is asynchronously reading from the depth buffer to figure out if the sun might be visible or not. This is hard to implement in GL without murdering performance, but we might be able to get this approximately right (with a frame delay) in Vulkan. Something for the future as it's quite tricky stuff...

EDIT: This is actually not what's going on! See #11100 (comment) below.

@hrydgard hrydgard added this to the Future milestone May 29, 2018
@hrydgard hrydgard changed the title Burnout dominator have lighting issue Burnout dominator have lighting issue (likely depth buffer readback) May 29, 2018
@Leopard20
Copy link
Contributor

Leopard20 commented May 29, 2018

@hrydgard
This is probably the same as this issue #10229, right?

@hrydgard
Copy link
Owner

Not certain but quite likely!

@marosis
Copy link
Author

marosis commented Dec 14, 2018

@hrydgard so what with this? Still waiting?( If yes no problem but depth buffer readback can fix lot of games)

@hrydgard hrydgard modified the milestones: Future, v1.9.0 Dec 14, 2018
@marosis
Copy link
Author

marosis commented Dec 14, 2018

+interresting in this game Is that, when you are rotated to the sun, you will get really big performance decrease.

@hrydgard
Copy link
Owner

Hm, I thought the big perf decrease was only in Burnout Legends, where it currently does do a readback when the sun is visible..

@marosis
Copy link
Author

marosis commented Dec 18, 2018

If we will fix it can it fix performance?

@Leopard20
Copy link
Contributor

@marosis Turning off "Simulate block transfer" fixes the performance issue.

@hrydgard hrydgard modified the milestones: v1.9.0, v1.10.0 Jun 27, 2019
@hrydgard hrydgard modified the milestones: v1.10.0, Future Apr 28, 2020
@Panderner
Copy link
Contributor

Screenshot_2020-08-06-14-56-59-49_2f85358b2198d26f8aca533d68bee793
Here's a GE Dump:
recording.ppdmp.zip

@ghost
Copy link

ghost commented Sep 21, 2020

Screenshot_2020-08-06-14-56-59-49_2f85358b2198d26f8aca533d68bee793
Here's a GE Dump:
recording.ppdmp.zip

No sun light issue on my phone mali-450 gpu opengl
I'm using your ge dump 🤔
Screenshot_20200921-141933

PPSSPP v1.10.3-725 git build

@Panderner
Copy link
Contributor

@Gamemulatorer the sun issue still happens in-game. When i making the GE Dump for sun in the tunnel or building the sun disappears.

Here's a GE Dump:
recording (2).ppdmp.zip

@ghost
Copy link

ghost commented Sep 21, 2020

Maybe opengl 2.0 device are not affected by this issue 😅

@Panderner
Copy link
Contributor

Maybe opengl 2.0 device are not affected by this issue 😅

@Gamemulatorer could you send me the screenshot of this game are you playing?

@ghost
Copy link

ghost commented Sep 21, 2020

This game is very very slow on my phone when the sun is showing :(
Screenshot_20200921-154457
Screenshot_20200921-154508
But when I'm inside the tunnel the sun doesn't show :)
Screenshot_20200921-154621
Screenshot_20200921-155413

@hrydgard
Copy link
Owner

Weird that it's so slow. I'm gonna have to investigate how the sun is done in this game too. We've solved the sun in Legends as good as we can get it, I think, though...

@hrydgard hrydgard added the GE emulation Backend-independent GPU issues label Sep 21, 2020
@hrydgard hrydgard modified the milestones: Future, v1.11.0 Sep 21, 2020
@ghost
Copy link

ghost commented Sep 21, 2020

Performance is good on my phone with sun is showing @1x rendering resolution but the graphics is too much pixelated unlike before 🙁
Screenshot_20200921-193543

@Panderner
Copy link
Contributor

Panderner commented Sep 21, 2020

Performance is good on my phone with sun is showing @1x rendering resolution but the graphics is too much pixelated unlike before 🙁
Screenshot_20200921-193543

@Gamemulatorer change the texture filtering to linear since the auto in texture filtering uses nearest for Burnout games all other games uses linear since the BlockTransferAllowCreateFB change for Burnout Legends

@hrydgard
Copy link
Owner

There's gonna be some new mipmapping option soon that will help fight the pixellated look as well that some games have.

@ghost
Copy link

ghost commented May 11, 2022

I can also reproduce this in motorstorm arctic edge.

@Gamemulatorer screenshot?

Screenshot_2022-05-11-10-29-12-700_org ppsspp ppsspp

@Panderner
Copy link
Contributor

And also Need for Speed: Shift.
Screenshot (40)

@ghost
Copy link

ghost commented Aug 3, 2022

This issue can still reproduce in the latest build v1.13.1-131

@hrydgard
Copy link
Owner

hrydgard commented Sep 10, 2022

Burnout Dominator ULES00703_0002.zip << GE framedump

VRAM locations:

00000/88000 : Main color framebuffers, 8888
04170000: Some unused CLUT? There's a block transfer to it but dunno what for.
04176000: This is the CLUT for the lens flare. It is treated as a framebuffer for manipulation.
04178000: Z buffer when drawing to the CLUT (!)

After step 6432, it does a block transfer, copying away the 14x14 sun location for later to RAM.

Then it draws a red 14x14 rectangle to the framebuffer at the sun position, with an ALWAYS stencil test and keep/keep/keep, ending up writing 0x02 to stencil I think No, stencil is irrelevant, it seems. Standard alpha blend, there's an alpha test but no texture.

Then it draws another one but white, this time with depth test. I think these two draws together extracts a sky mask from the depth buffer, effectively. No difference in the stencil test, so that part might be irrelevant.

Now, for whatever reason it configures a giant 1024x1024 texture size but still 512 stride. This seems to cause us to miss matching the framebuffer, maybe? not sure, looks odd in the GE debugger. Texture and framebuffer are both 40880000 / 4000000, 8888 format.

Renders to itself multiple times out in the border, so a Killzone-like split could be workable to reduce the size of the copy. It does a 2x2 shrink at at time, except the last one is a 4x1, which now thus has a 2x1 gradient of sun brightness stretched across 4 pixels.

image

(The downsampling isn't working too great because we run at too high resolution... Might need trickery here)

Then is does two block transfers: One appears to restore the 14x14 rectangle to the image from RAM (see the first copy).

The other initializes the CLUT at 04176000 with some default data from RAM.
Then it sets up a framebuffer exactly there, 16-bit 565. (here we must initialize it with the just-copied data).
The only draw call that happens on this framebuffer, which is what we'll later use for a CLUT when rendering the flares, covering it, is:

X		Y		Z		U		V		Color		NX		NY		NZ
0.000000	0.000000	0.244144	1.500000	0.500000	ffffffff	0.000000	0.000000	1.000000
512.000000	1.000000	0.244144	1.500000	0.500000	ffffffff	0.000000	0.000000	1.000000
TexSync
Alpha blend enable: 0
Z test enable: 1
ZMask: disable write
MaskRGB: 071fff (bits not to write) << !!!!!! This mask in 565 mode means to write the upper 8 bits, that is all of blue and 3 bits of green! What it does here is write to alpha (and green, but see the z buffer trick below) of the buffer if it was interpreted as 8888.
Stencil op: fail=REPLACE, pass/depthfail=KEEP, pass=REPLACE  (NOTE! Disabled)
Framebuf ptr: 0x04176000
Framebuf stride: 0x200 (extra 040000)
Framebuf PixelFormat: 565
Zbuf ptr: 178000
Zbuf stride: 0x200 (extra 040000)
NOP
NOP
TexFormat CLUT8
Texture size 0: 4x1 (extra 000002)
CLUT addr: high=04  <<unused
CLUT addr: low=177000 <<unused
Clut format: 00ff03 (ABGR 8888)
CLUT addr: high=08
CLUT addr: low=ae4760
Clut load: 08ae4760, 1024 bytes
TexSync
Texture stride 0: 0x0200, address high=04
Texture address 0: low=088780
Texture stride 4: 0x0010, address high=08
Texture address 4: low=809400
VADDR: 9f8570 => 089f8570
DRAW PRIM RECTANGLES: count= 2 vaddr= 089f8570

No idea why it sets up level 4 and 5, only 1 level is used, so we can ignore that.

This draw call is very strange because it doesn't even have blending enabled, I'd have expected it to take the value and brighten/darken the CLUT, but instead it seems to replace some bits in it using the bitmask (which we're gonna have to enable...).

Anyway, while writing to the flare CLUT, it samples a single texel from a 4x1 texture at 88780 which is an offset inside the main framebuffer, specifically the 4x1 summary texels from the pyramid downsampling. BUT! It samples it as if it was CLUT8 and at x=1.5!

Also it uses depth testing when drawing to the CLUT and has its own little Z buffer! No idea what for. Or maybe it uses an alternating-pixel Z buffer in order to avoid writing to the lower bit, when using 16-bit rendering to poke alpha components into a 32-bit buffer? (Yes!)

This is the CLUT it puts it through while drawing to what will become the final CLUT:

image

Does seems like a blue-green gradient. It places the bits into the blue and green channel so they'll come through into a 32-bit alpha channel when masked with the color bits and and the specially prepared z buffer to remove what would otherwise be writes to the 8-bit green channel...

image

In the end, once it has the modified CLUT, it draws a bunch of quads using this texture, and the CLUT as interpreted as 32-bit, thus with modified alpha that comes from the sun coverage.

The messing-around-with-color-channels thing is kinda characteristic for PS2 ports, which this game is...

image

Oh found another bug in the GE debugger, block transfer size isn't consistent between disassembly and the parameter viewer tabs, there's an off by one.

@unknownbrackets
Copy link
Collaborator

Did some tests for width/height of textures, in case related.

For 8888 textures (largest) through or transform, textures up to 512x512 work just as everyone knows and expects.
Larger textures than 512, even 1024x1, "work" but clamp/wrap behavior kicks in at the 512 boundary regardless.

For example, suppose I drew x 1024x1 texture to the screen at 256x256 with S set to CLAMP. I would see the leftmost 512 texels reduced down to the left 128 pixels. The right half would all be the 512th texel repeated. Switching to WRAP would repeat the left side on the right. It would in any case be impossible to sample the right 512 texels. The same behavior replicates for height.

This pattern is consistent for all texture formats, from CLUT4 to 8888.

So in this case, as long as it only samples from the first 512x512, it may "just work", and only really affects the UV -> ST coordinates (1.0f would map to 1024, even though the actual texture data is 512x512.)

-[Unknown]

@hrydgard
Copy link
Owner

OK, so things that go wrong right now:

  • My prototype CLUT8 from 8888 at non-1x resolutions seems to read the wrong pixels or something. hard to tell
  • The buffer copy to the palette that is supposed to initialize it every frame, it copies to the wrong buffer. This shouldn't matter too much though since we're overwriting the alpha bits each frame. Arguably we maybe shouldn't take seq into account for copy destinations? Or just heavily boost exact matches. Hm.
  • No Z upload, so both alpha and green will be inadvertently modified.
  • The rest does appear to work, the CLUT download etc, although alpha .

There's a LOT of moving parts...

@hrydgard
Copy link
Owner

image

Progress:

  • CLUT8-from-8888 now works at 1x at least
  • Using CLUT downloads, so not super fast
  • Not yet implemented Z upload (to mask off each half CLUT color), so evil green infects the CLUT for the flare texture

Still, the flare disappears when the sun is covered quite nicely! Getting there!

@hrydgard
Copy link
Owner

Burnout.Lens.Flare.mp4

Phew, with a pile of hackery it works :) Now to generalize and make nice, and also ideally make it work at higher res...

@ghost
Copy link

ghost commented Sep 22, 2022

The SUN still no show using opengl backend.

@hrydgard
Copy link
Owner

Yeah, I know. It does work on desktop GL, but I'll have a look at mobile too soon...

@hrydgard
Copy link
Owner

hrydgard commented Feb 4, 2023

So this broke again with e5d6711 , which is not all that surprising, but we'll have to add some additional checking.

@hrydgard hrydgard reopened this Feb 4, 2023
@hrydgard hrydgard modified the milestones: v1.14.0, v1.15.0 Feb 4, 2023
hrydgard added a commit that referenced this issue Feb 4, 2023
We have to assume that ForceLowerResolutionForEffects has been set for
good reason - in this case, the effect probably can't safely function
without it.

Fixes #11100 once again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GE emulation Backend-independent GPU issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants