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
10.81k stars 2.12k forks source link

Fire and Gas Flickering in LittleBigPlanet #16030

Open Jaklyy opened 1 year ago

Jaklyy commented 1 year ago

Game or games this happens in

UCUS98744 - LittleBigPlanet™

What area of the game

Any burning or gas hazard material.

What happens

On all rendering backends besides software, burning or gas materials appears to flicker. changing rendering resolution seems to randomly result in either correct or incorrect behavior, seems to always start with broken visuals regardless of rendering resolution when launching the game. erroneous behavior on latest dev build: (flashing lights warning on all videos) https://user-images.githubusercontent.com/102590697/190550711-cd43d9c2-4c87-4507-ab50-1ec4aa95e323.mp4 example of toggling render resolution changing behavior (on an older build but i can confirm it still happens currently): https://user-images.githubusercontent.com/102590697/190552089-ec3144dd-8513-464b-a145-72f6adc411f3.mp4

What should happen

should result in a smooth gaseous effect. image

GE frame capture

UCUS98744_0001.zip

Platform

Windows

Mobile phone model or graphics card

Radeon RX 480 Graphics

PPSSPP version affected

v1.13.2-959-g1b9bc141f

Last working version

No response

Graphics backend (3D API)

Vulkan

Checklist

unknownbrackets commented 1 year ago

The frame dump should look like this:

#16030_UCUS98744_lbp_gas

Software doesn't get the fire blur right:

#16030_UCUS98744_lbp_gas_softgpu

At least in the frame dump, the gas is just missing in GLES/Vulkan.

The flaming box is drawn at 85/151. Interesting stuff starts at 94/151, though. It draws to a temporary buffer at 0x04198200, and it actually ultimately uses 4 temp buffers (each 128 pixels wide) within the 512 stride here: 0x04198000, 0x04198200, 0x04198400, and 0x04198600. 0x00198600 is a black/white mask, 0x00198200 is the gas, and each of those -0x200 is a blurred version rendered afterward.

Then it uses a depth test to stencil out areas, which it then blends the mask in with (making the gas areas black as long as their depth was in the background.) Finally it blends in the gas on top.

In hardware, 0x04198200 is all detected as a single, wide framebuffer. Then 0x04198000 (rendered later in the frame) is detected as a separate, also wide framebuffer. Because the blurring offsets are slightly into the other framebuffer, things get confused with texture framebuffer selection. Ultimately, it doesn't blur anything - it reads from the initially black areas of the alternate framebuffer. This is why there's no gas.

Flickering probably means it's either alternating this, or getting it right depending on something else in the frame.

-[Unknown]

hrydgard commented 1 year ago

This appears to works correctly if we simply disallow horizontally merging framebuffers and matching framebuffers at offsets.

Thinking I should just throw in a compat flag... messing with the heuristics is a bit risky at this point in the release process.

hrydgard commented 1 year ago

This should work now - but this issue is now about removing the compat flag I added in #16520 and making sure our heuristics can handle this case.

ghost commented 1 year ago

This was accidentally close?