pcsx2 icon indicating copy to clipboard operation
pcsx2 copied to clipboard

Meta: GSdx HW mipmap support

Open gregory38 opened this issue 8 years ago • 221 comments

Let's collect games that suffer from lack of mipmap. It would allow to avoid multiple bugs reports and easily see which games are impacted (and how many too).

Active issues:

  • [x] Ape Escape 2 #869 - major issue, requires Full mipmapping(still glitchy) and Trilinear for ground
  • [ ] FIFA 2003 & 2005 - "Trilinear" Texture Filtering further improves field textures
  • [ ] FIFA 2004 - textures flickering remains in midfield with the goal to goal cam
  • [x] ICO - minor issue, god rays are still missing
  • [x] No One Lives Forever #2124 - LODs are glitchy/has alignment issues.

Active issues, but not broken without mipmapping:

  • [x] Gran Turismo 4 comment - Ground textures
  • [ ] 2002 FIFA World Cup - Mipmapping does not work for any hardware renderer
  • [ ] SOCOM II - Enabling mipmapping on hardware will cause graphical issues

Fixed with automatic mipmapping option, but missing CRCs:

  • [x] Legacy of Kain Defiance - minor issue, wrong textures on 3D objects
  • [x] Legacy of Kain Soul Reaver 2 - minor issue, wrong textures on 3D objects

Fixed with automatic mipmapping option:

  • [x] Ace Combat 4: Shattered Skies / Distant Thunder - major terrain flickering (resolved)
  • [x] Ace Combat 5: The Unsung War / Squadron Leader - major terrain flickering (resolved)
  • [x] Ace Combat Zero: The Belkan War - major terrain flickering (resolved)
  • [x] Brian Lara International Cricket 2007 - major issue (resolved)
  • [x] Dark Cloud - minor issue, needed for some background scenery (resolved)
  • [x] Destroy All Humans
  • [x] Destroy All Humans 2
  • [x] Jak and Daxter: The Precursor Legacy - tri linear for sea
  • [x] Jak 2
  • [x] Jak 3
  • [x] Jurassic Park : Operation Genesis - major issue
  • [x] Ratchet and Clank
  • [x] Ratchet and Clank Going Commando / Locked and Loaded
  • [x] Ratchet and Clank Up your Arsenal / 3
  • [x] Ricky Ponting International Cricket 2005 - major issue (resolved)
  • [x] Tomb Raider: Anniversary
  • [x] Tribes: Aerial Assault - minor issue, very noticable on vehicle landingpads
  • [x] Whiplash

gregory38 avatar Sep 12 '16 09:09 gregory38

*Ratchet and Clank *Ratchet and Clank Going Commando/ Locked and Loaded *Ratchet and Clank Up your Arsenal / 3 *Ace Combat 4 Shattered Skies *Ace Combat 5 Skies of Deception

Nobbs66 avatar Sep 12 '16 10:09 Nobbs66

A quick search showed #168, #775, #869. Also, iirc Ace Combat zero/belkan war also exhibited the issue, but afaik not Shattered Skies.

mirh avatar Sep 12 '16 12:09 mirh

Ratchet: Gladiator (aka Ratchet: Deadlocked) is affected as well afaik

pepiczech77 avatar Sep 12 '16 12:09 pepiczech77

Also, iirc Ace Combat zero/belkan war also exhibited the issue, but afaik not Shattered Skies.

You recalled incorrectly: http://wiki.pcsx2.net/index.php/Ace_Combat_04:_Shattered_Skies http://forums.pcsx2.net/Thread-Ace-Combat-Distant-Thunder-SCES-50410-E

FlatOutPS2 avatar Sep 12 '16 14:09 FlatOutPS2

Wipeout Fusion, Gran Turismo 4, and Hot Shots Golf 4 have minor flickering due to lack of mip levels. I don't know if they really apply to this list; since they are minor anomalies (other than HSG4 having speed issues w/ depth)

MrCK1 avatar Sep 12 '16 14:09 MrCK1

Added the two Destroy All Humans games

refractionpcsx2 avatar Sep 12 '16 17:09 refractionpcsx2

I think there at least one tomb raider. But I don't know which one.

@prafullpcsx2 gives me also some cricket games with mipmap issue.

gregory38 avatar Sep 15 '16 09:09 gregory38

I could be completely wrong, but doesn't one of the Hot Shot Golf games have mipmapping as well? I can't remember. I also vaguely remember an FPS game using it as well, but I can't remember what it was.

refractionpcsx2 avatar Sep 15 '16 12:09 refractionpcsx2

There's a difference between having mipmapping, and having serious issues with mipmapping. The Everybody's Golf(the actual name of the series) games have mipmapping, but they don't have any issues with it(or it has to be the Japan only online game). The games would improve with mipmapping though, as the high res textures don't look as good at a distance.

FlatOutPS2 avatar Sep 15 '16 12:09 FlatOutPS2

Yes lots of games (maybe nearly all) use mipmapping without any real bad impacts. Nocturne uses it too, for example, the ceiling light color is wrong of 1...

gregory38 avatar Sep 15 '16 12:09 gregory38

so you will implement mipmapping in hardware? this is real? : O

Dokman avatar Sep 15 '16 16:09 Dokman

I will add many games to this list after 2-3 days (when my tournament ends).

prafullpcsx2 avatar Sep 15 '16 17:09 prafullpcsx2

Hum, please say if it is major/minor issue.

Good luck ;)

gregory38 avatar Sep 15 '16 18:09 gregory38

all the people we want to play our ratchet and clank games and destroy all humans are crazy with the software render i think, because we cannot set a higher resolution and watch the correct textures in the game..

Dokman avatar Sep 15 '16 18:09 Dokman

Really.. Give that man some space. First priority is his family. After that he has to work for a living. After that he has to fulfill all desires and wishes he has. And exactly at the end after he took care about everything in his life he could take care of those who want to play R&C in higher than native or with weak hardware.

willkuer avatar Sep 15 '16 18:09 willkuer

I vaguely recall that one of the tomb raiders (legend? anniversary?) also had mipmap issues, though I don't recall if it's HW only.

avih avatar Sep 15 '16 18:09 avih

Before GITHUB goes down when rumour of mipmap work goes vrial on the internet. ^^

I have no plan to work on it yet. The purpose of this issue report is to concentrate all the mipmap issue into a single report instead of dozens of them. Less noise in the tracker + easier for tester.

On a side note, my current target is to finish Grandia 2 anniversary edition ;)

gregory38 avatar Sep 15 '16 19:09 gregory38

Are you porting all the Grandia 2 AE improvements to the PS2/PCSX2 version?! :P

FlatOutPS2 avatar Sep 15 '16 20:09 FlatOutPS2

Doesn't Tribes Aerial Assault use mipmaps?

MonJamp avatar Sep 16 '16 16:09 MonJamp

Doesn't Tribes Aerial Assault use mipmaps?

Yes, it does and it has several issues with it. I added it to the OP.

FlatOutPS2 avatar Sep 16 '16 16:09 FlatOutPS2

Added Tomb Raider: Anniversary. The game has additional problems. An overlay of broken shadow maps, it looks like.

ramapcsx2 avatar Sep 16 '16 17:09 ramapcsx2

I have a question: assuming that mipmapping doesn't work at all on GSdx: hardware, are these the only games that actually use Mipmapping on the PS2, or is there a certain way they're using mipmapping that's causing severe issues?

I've been trying to look up more on what the games are actually doing since it seems every time a PS2 article/video/anything is posted there's someone saying "does it run R&C yet" or "useless until it runs R&C in hardware," and I'd like to at least be able to rebut them to a degree with what the games are doing and why it's not emulated in hardware.

JMC47 avatar Sep 20 '16 21:09 JMC47

Lots of game use mipmapping but base layer contains real data. GS mem is more a cache than a standard vram. Mipmap layers are only pointer to memory area. You can do anything you want with the memory. The rule is there is no rule. Now for RC, I suspect that game only write texture data of the intermediate layers. The plan is to compute in cpu the max layer of the rendering and to upload this layer to the texure (with the help of texture view)

gregory38 avatar Sep 20 '16 21:09 gregory38

So, on GSdx hardware, it's pointing to where the actual texture is, rather than where the mipmap is right now? Causing it to load garbage instead of the actual texture? Or, rather, it has no place to actually load the texture since only the mipmap is in memory and nothing is in the base layer?

JMC47 avatar Sep 20 '16 21:09 JMC47

Jak and daxter series also has the mipmapping bug

TheJordanator avatar Sep 20 '16 22:09 TheJordanator

@TheJordanator That's already in the list

MrCK1 avatar Sep 20 '16 22:09 MrCK1

@JMC47 Hum, let's use an example On the game engine, you can compute the lod of the scene. Let's say you find 3. What you can do is

  • write Tex pointer to 0x1000
  • write Tex layer 1/2/3 to 0x1000,0x1000, 0x1100
  • Then do an EE texture write to the address 0x1100. 0x1000 is a random location, it could be anywhere. It could even be in the middle of the frame buffer or depth buffer or whatever. You don't care, as you know the game will only sample the layer 3.

Currently GSdx HW will read the memory located at 0x1000 to generate the texture. The correct behavior will be to upload the 0x1100 part.

Potential solution will be to upload all the layers and to sample the good layer. Perf will suck. So I think we could only upload the top layer that we know will be valid (if we compute the lod on the CPU). It might be enough for some games. However it can become easily complex. So far we reference texture with the layer0 address. Nothing forbid a game to change it but to keep the same layer. We can create new texture based on the layer address (we miss tri-linear filtering). It could to handle EE write in the middle of a layer. But it might create various texture upload based on the camera position (again bad for perf).

Every time, we want to upload a texture. We need to unsizzle it, convert it to 32 bits (or upload a palette). And then ask gl driver to upload which isn't fast. If the game only upload partial mipmap, it likely means that GS mem is too small for its => likely various texture collision/invalidation writes => more texture to upload.

Conclusion we need to do something and see what is the perf. But if it works, nobody will complain anymore ;)

gregory38 avatar Sep 21 '16 09:09 gregory38

Forget to say, first step is to do a current state of the game impacted, because I can tell you that all games are likely using different tricks.

And last but not least, extend the internal GS debugger to dump the texture layer. This way we can see what happen.

gregory38 avatar Sep 21 '16 10:09 gregory38

Sounds like a total pain in the ass. I do not envy whoever tries to tackle this issue. At least I have a reference to point people to now when I see them asking about it. Also, making it a perf vs accuracy issue with no great solution helps tell users "it's not that simple."

On Wed, Sep 21, 2016 at 6:05 AM, Gregory Hainaut [email protected] wrote:

Forget to say, first step is to do a current state of the game impacted, because I can tell you that all games are likely using different tricks.

And last but not least, extend the internal GS debugger to dump the texture layer. This way we can see what happen.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/PCSX2/pcsx2/issues/1561#issuecomment-248567332, or mute the thread https://github.com/notifications/unsubscribe-auth/AGSuQc50pjcp8JxVwqNIhTbDN5kW42NZks5qsQFagaJpZM4J6aJ4 .

JMC47 avatar Sep 21 '16 21:09 JMC47

Oh, you just found the initial name of the GS, PITA ;)

Here the SW implementation

            if(mipmap)
            {
                if(m_vt.m_lod.x > 0)
                    gd.sel.ltf = context->TEX1.MMIN >> 2;
                else
                    // TODO: isbilinear(mmag) != isbilinear(mmin) && m_vt.m_lod.x <= 0 && m_vt.m_lod.y > 0

                gd.sel.mmin = (context->TEX1.MMIN & 1) + 1; // 1: round, 2: tri
                gd.sel.lcm = context->TEX1.LCM;

                int mxl = std::min<int>((int)context->TEX1.MXL, 6) << 16;
                int k = context->TEX1.K << 12;

                if((int)m_vt.m_lod.x >= (int)context->TEX1.MXL)
                {
                    k = (int)m_vt.m_lod.x << 16; // set lod to max level

                    gd.sel.lcm = 1; // lod is constant
                    gd.sel.mmin = 1; // tri-linear is meaningless
                }

                if(gd.sel.mmin == 2)
                    mxl--; // don't sample beyond the last level (TODO: add a dummy level instead?)

                if(gd.sel.fst)
                    gd.sel.lcm = 1;

                if(gd.sel.lcm)
                {
                    int lod = std::max<int>(std::min<int>(k, mxl), 0);

                    if(gd.sel.mmin == 1)
                    {
                        lod = (lod + 0x8000) & 0xffff0000; // rounding
                    }

                    gd.lod.i = GSVector4i(lod >> 16);
                    gd.lod.f = GSVector4i(lod & 0xffff).xxxxl().xxzz();
                }
                else
                {
                    gd.mxl = GSVector4((float)mxl);
                    gd.l = GSVector4((float)(-0x10000 << context->TEX1.L));
                    gd.k = GSVector4((float)k);
                }

                GIFRegTEX0 MIP_TEX0 = TEX0;
                GIFRegCLAMP MIP_CLAMP = context->CLAMP;

                GSVector4 tmin = m_vt.m_min.t;
                GSVector4 tmax = m_vt.m_max.t;

                static int s_counter = 0;

                for(int i = 1, j = std::min<int>((int)context->TEX1.MXL, 6); i <= j; i++)
                {
                    switch(i)
                    {
                    case 1:
                        MIP_TEX0.TBP0 = context->MIPTBP1.TBP1;
                        MIP_TEX0.TBW = context->MIPTBP1.TBW1;
                        break;
                    case 2:
                        MIP_TEX0.TBP0 = context->MIPTBP1.TBP2;
                        MIP_TEX0.TBW = context->MIPTBP1.TBW2;
                        break;
                    case 3:
                        MIP_TEX0.TBP0 = context->MIPTBP1.TBP3;
                        MIP_TEX0.TBW = context->MIPTBP1.TBW3;
                        break;
                    case 4:
                        MIP_TEX0.TBP0 = context->MIPTBP2.TBP4;
                        MIP_TEX0.TBW = context->MIPTBP2.TBW4;
                        break;
                    case 5:
                        MIP_TEX0.TBP0 = context->MIPTBP2.TBP5;
                        MIP_TEX0.TBW = context->MIPTBP2.TBW5;
                        break;
                    case 6:
                        MIP_TEX0.TBP0 = context->MIPTBP2.TBP6;
                        MIP_TEX0.TBW = context->MIPTBP2.TBW6;
                        break;
                    default:
                        __assume(0);
                    }

                    if(MIP_TEX0.TW > 0) MIP_TEX0.TW--;
                    if(MIP_TEX0.TH > 0) MIP_TEX0.TH--;

                    MIP_CLAMP.MINU >>= 1;
                    MIP_CLAMP.MINV >>= 1;
                    MIP_CLAMP.MAXU >>= 1;
                    MIP_CLAMP.MAXV >>= 1;

                    m_vt.m_min.t *= 0.5f;
                    m_vt.m_max.t *= 0.5f;

                    GSTextureCacheSW::Texture* t = m_tc->Lookup(MIP_TEX0, env.TEXA, gd.sel.tw + 3);

                    if(t == NULL) {ASSERT(0); return false;}

                    GSVector4i r;

                    GetTextureMinMax(r, MIP_TEX0, MIP_CLAMP, gd.sel.ltf);

                    data->SetSource(t, r, i);
                }

                s_counter++;

                m_vt.m_min.t = tmin;
                m_vt.m_max.t = tmax;
}

Basically I want to do the same but with a single texture lookup loop (not 6 in worst case).

for(int i = 1, j = std::min<int>((int)context->TEX1.MXL, 6); i <= j; i++)

Hopefully it will be good enough to avoid most of the glitches. It won't be perfect, some game won't be supported but it would be a good start.

However I'm not sure how to handle texture size/clamp behavior etc... Hum, I need to check if mipmap is available with integer texture coordinate.

gregory38 avatar Sep 22 '16 10:09 gregory38