PCSX2 / pcsx2

PCSX2 - The Playstation 2 Emulator
https://pcsx2.net
GNU General Public License v3.0
11.85k stars 1.63k forks source link

[BUG]: Battlefield 2 - Modern combat 2 - 1e Flickering bug (v1.7.3859) #8869

Closed IamLupo closed 1 year ago

IamLupo commented 1 year ago

Describe the Bug

The bug consist of heavy flickering graphics issues that happends for Battlefield 2 Modern Combat in multiplayer mode. This starts to happen for any hardware as renderer. Software renderer does work correctly without flickering! Our discord community all confirms they experience the same issue thats why i jumped in for investigation and a solution.

The flickering issues I manage to track down by testing version 1.7.3858 that has not the flickering issue. The version 1.7.3859 has the flickering issue. By checking the pull 7797 for version v1.7.3859. You see that Battlefield 2 got a specific patch GSHwHack::OI_Battlefield2.

By disable "beforeDraw" for "GSHwHack::OI_Battlefield2" in the "GameIndex.yaml", I manage to stop the 1e flickering issue. Because we disabled the Hardware fix in "beforeDraw" we triggered a old bug called "black main menu". This basically didn't draw the full main menu on the screen that caused for a large black screen. With the "GSHwHack::OI_Battlefield2" it patched the width and height of that image.

After debugging this "GSHwHack::OI_Battlefield2" patch i manage to understand better how it worked. Thats why i changed the code to not let it trigger anymore in multiplayer.

bool GSHwHack::OI_Battlefield2MP(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
    if (rt && t && RCONTEXT->FRAME.Block() == 0 && RCONTEXT->TEX0.TBP0 == 0x1000)
    {
        const GSVector4i rc(0, 0, std::min(rt->GetWidth(), t->m_texture->GetWidth()), std::min(rt->GetHeight(), t->m_texture->GetHeight()));
        g_gs_device->CopyRect(t->m_texture, rt, rc, 0, 0);

        r.m_tc->InvalidateTemporarySource();
        return false;
    }

    return true;
}

Basically i patch the code that it only can trigger false when he detect the main menu. If he is not in the main menu he return true and no patch is applied on the GS.

In the orginal "GSHwHack::OI_Battlefield2" line 959 you see it has a extra if statement to return true. I didnt fully get the reason behind this desision. Because of this it returns to much false returns. This was the main cause of this flicker issue in multiplayer.

My idea is to split this into 2 patches: "GSHwHack::OI_Battlefield2SP"(default) and "GSHwHack::OI_Battlefield2MP". This way our BF2:MC online community can switch what patch to choose in "GameIndex.yaml" file. I notice right now that the BF2:MC community keeps on a lower PCSX2 version because of this issue.

Reproduction Steps

Expected Behavior

No response

PCSX2 Revision

v1.7.3859

Operating System

Windows 10 (64bit)

If Linux - Specify Distro

No response

CPU

AMD Ryzen 9 5900X

GPU

RTX 3080

GS Settings

SLUS-21026: name: "Battlefield 2 - Modern Combat" region: "NTSC-U" compat: 5 gsHWFixes: autoFlush: 1 # Post-processing. halfPixelOffset: 2 # Offset post-processing. texturePreloading: 1 # Spikes all over the place otherwise. getSkipCount: "GSC_Battlefield2" # Depth clear. beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen.

Emulation Settings

settings

GS Window Screenshots

Ingame The screenshot doesn't show it correctly, but the screen keeps flickering,..

BlackMainMenu This is how the "Black main menu" looks like. It is filled for 90% unrendered screen.

Logs & Dumps

Battlefield 2 - Modern Combat_SLUS-21026_20230517121505

GS Dump: https://mega.nz/file/Acpx2KbZ#ipJWX53b0KDEPQ1C-sE0ZHVlvIE9p1uDGzrl3ESt0HE

stenzek commented 1 year ago

Won't fix. Use software mode.

(the hw fix/GSC/OI has no effect on sw mode)

Some of my rambling:

Stenzek — 04/24/2023 1:14 AM so it's clearing 8 pages at a time, row by row I wonder if I can cheat and just peek at the next draw WHY ARE YOU CHANGE TEX1 YOU STUPID GAME later on it copies rows but only the MSB it's clearing and copying shit so many times per frame I could hardcode all the BPs I guess but idk if they're the same between PAL and US it can stay broken

IamLupo commented 1 year ago

I put a lot of effort to provide this information and a concrete solution,... and you dont even look at it or comment on the arguments i provide... I understand this is a hard issue, but the best thing is to split it appart and work on that... I see only rambling and no real pinpoint arguments why you went stuck with battlefield 2. Why not provide the information you discovered and document it. Like other people can continue on it?

I compiled the latest version with my patches and both of the issues i posted got resolved....