narzoul / DDrawCompat

DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11
BSD Zero Clause License
893 stars 67 forks source link

Extreme G-2 rendering is bugged #159

Closed BEENNath58 closed 8 months ago

BEENNath58 commented 1 year ago

I am trying to run a game named Extreme G-2. The issue is that the game doesn't load textures. I am running the disc version.

Since the game crashes for me, first I had to edit the executable: changing hex instance of FF 15 E4 56 B1 01 with 90 90 90 90 90 90.

I tested the game on Windows 11, with an Nvidia GTX 1050Ti and the latest DDrawCompat. You can see below how the game looks with textures not getting loaded. xg2notextures

Thank you.

BEENNath58 commented 1 year ago

Is there anything that can help?

narzoul commented 1 year ago

The game is trying to create mipmaps with invalid and nonsensical parameters: non-pow2 dimensions which aren't supported even by DX7, and only 1 mip level. I wonder why it worked when it was released. Maybe old DX runtimes had less strict validations.

Anyway, here's a quick fix, I'll add it to the next release: ddraw.zip (diff.txt compared to v0.4.0)

BEENNath58 commented 1 year ago

The game is trying to create mipmaps with invalid and nonsensical parameters: non-pow2 dimensions which aren't supported even by DX7, and only 1 mip level. I wonder why it worked when it was released. Maybe old DX runtimes had less strict validations.

I think DX6.1 also didn't support non-pow2 textures, but was used in games like Midtown Madness, so yes if that's the case they had less strict rules.

Anyway, here's a quick fix, I'll add it to the next release: ddraw.zip ([diff.txt] (https://github.com/narzoul/DDrawCompat/files/9903178/diff.txt) compared to v0.4.0)

It is quite fixed, except for the start credit/intro type screen:

startupxg2

(btw, did ddc start supporting palettized textures and mipmapped textures all in version 0.4.0? I have a friend whose WDDM1.1 GPU using Windows 7 crashes, so he has to use older versions, but neither of us know which version supports the aforementioned features and if there's any setting for it)

narzoul commented 1 year ago

I think DX6.1 also didn't support non-pow2 textures, but was used in games like Midtown Madness, so yes if that's the case they had less strict rules.

Non-pow2 textures are fine, only mipmaps are not supported. Based on my testing, the DX7 runtime simply doesn't allow creating such mipmaps, even if the GPU would support it.

It is quite fixed, except for the start credit/intro type screen:

Hmm, this must be another NVIDIA specific driver issue I haven't encountered before. It renders correctly on AMD, and with ForceD3D9On12 it also works fine on NVIDIA, but that setting introduces other issues. I'll look into it sometime.

(btw, did ddc start supporting palettized textures and mipmapped textures all in version 0.4.0? I have a friend whose WDDM1.1 GPU using Windows 7 crashes, so he has to use older versions, but neither of us know which version supports the aforementioned features and if there's any setting for it)

Mipmapped textures are supported natively by ddraw, so it's also supported in all versions of DDrawCompat.

Palettized texture support was added in v0.4.0 (see PalettizedTextures setting in the wiki), but in theory you could use palettized textures in previous versions too if your GPU supports it natively (I'm not aware of any that do nowadays).

Palettized mipmaps are not currently supported by the emulation in DDrawCompat, but I'm only aware of one case where it causes problems (Conquest: Frontier Wars crashes with PalettizedTextures=on if I remember correctly).

For Windows 7, use the version here: https://github.com/narzoul/DDrawCompat/issues/149#issuecomment-1271986474 It fixes some Win7-specific crashes introduced by v0.4.0.

BEENNath58 commented 1 year ago

with ForceD3D9On12 it also works fine on NVIDIA,

Do you mean the D3D9On12Enabler shim with the -On parameter? That didn't help me...

Mipmapped textures are supported natively by ddraw, so it's also supported in all versions of DDrawCompat.

Interesting, I thought Mipmapping has been depreciated in modern drivers and DDraw.

narzoul commented 1 year ago

I meant the ForceD3D9On12 setting.

BEENNath58 commented 1 year ago

I keep forgetting to reply....

Yes I tested it then with ForceD3D9On12 setting and it worked fine. There were the problems as you earlier explained.

For now, dgVoodoo2 has the game completely sorted out.

Default DDC and DxWnd both have fixed the textures except the initial screen.

narzoul commented 1 year ago

Reopening so I don't forget to check the intro screen issues. NVIDIA also has some strange rendering issues in Midtown Madness 2 which I wanted to look into for a while, maybe I'll still have time for it this year...

narzoul commented 1 year ago

Ok, so I think I fixed the intro text, hopefully without breaking anything else: ddraw.zip (diff.txt compared to v0.4.0)

The game sets black color key on the font textures, seemingly completely unnecessarily, since the same result is achieved without any color keys. Additionally, it uses linear filtering, which has driver-dependent interworking with color keys, and is itself handled differently by NVIDIA. On my AMD GPU (or with D3D9On12), it looks as if texture color keying is completely ignored when alpha blending is enabled. So I just applied this as a fixup in the DDI for now.

I also found some old discussion of this issue on Vogons: https://www.vogons.org/viewtopic.php?f=8&t=41642 https://www.vogons.org/viewtopic.php?p=427054#p427054

So this issue also came up before in dgVoodoo, but it was solved differently, by changing the way bilinear filtering works with texture color keys. This still remains driver-dependent with DDrawCompat, but it seems to be quite difficult to fix at this level, so I leave it be for now, until some game actually requires it.

narzoul commented 1 year ago

Midtown Madness 2 NVIDIA texture bugs: the game creates all textures as render target textures (RTTs) for no good reason, since it doesn't actually try to render anything to them. The problem is that the A4R4G4B4 format is not supported as a render target on NVIDIA GPUs (at least on mine), so it fails to create all such textures.

For now, this simple patch just removes the render target flag from all textures: ddraw.zip (diff.txt compared to v0.4.0)

But I couldn't add this to the main release without some config option, and I'd rather not add one for this hack. Proper solution would be to emulate all RGB formats as RTTs when needed, which is quite a bit more effort, but might help some other game that actually needs such unsupported RTT formats. I might do this later.

BEENNath58 commented 11 months ago

I am reopening the issue yet again. Looking at the text quality, I see differences. I basically compared 4 setups: Complex mipmapping off (top left) vs non-power 2 fix vs ReactOS vs dgVoodoo2.

Visually, comparing to a Voodoo2 DX6 output, the ReactOS output was the most visually correct, dgVoodoo2 was little off in the text edges. Complex mipmap off and non-power 2 fix alone have a different quality altogether. Screenshot 2023-08-09 131354

Any idea on this?

I also forced point-sampled filtering through DxWnd and it manages to come close to that of ReactOS and dgVoodoo2, but the blockiness exsts, so it definitely isn't point-sampled.

narzoul commented 11 months ago

The top two look like NVIDIA-style texture color keying with bilinear filtering, and the bottom two look like AMD-style texture color keying with bilinear filtering. I don't know what causes the further shift between the bottom two, obviously I'm not familiar with their implementation differences.

Yes, with point filtering it looks closer to the bottom ones, but without the black fringes created by the colorkey color (black) bleeding into the edges.

BEENNath58 commented 11 months ago

Okay that's what I was expecting for the first 2: NVIDIA method. For the next two, I should ask what Dege changed himself.

Anyways, I see you have a Midtown Madness 2 fix put here too. Can you tell what it is for? Specifically, I don't remember seeing a problem with my Nvidia GPU on this game, so I am curious where I can emulate the problem as you did

narzoul commented 11 months ago

Just restore default graphics settings and go into a quick race. It looks like this for me, even without any wrappers: midtown2

BEENNath58 commented 11 months ago

Curious I don't have this.

I used the game + the XP patch + the 1.1 patch settings mm2hal

If my memory serves well, I have seen this issue, when the MM2Heap patcher was applied (that fixed nothing actually).

BEENNath58 commented 11 months ago

Ok I guess this is the correct one: 1.0 + noCD mm2bad

Maybe the XP patch was made for this specific purpose only?

The problem is that the A4R4G4B4 format is not supported as a render target on NVIDIA GPUs (at least on mine), so it fails to create all such textures.

I should check what Voodoo2 says, is there a way to check?

narzoul commented 11 months ago

I should check what Voodoo2 says, is there a way to check?

I assume you mean the 3dfx Voodoo2 video card and not dgVoodoo2.

I think the DX API doesn't expose any information about what kind of surfaces are supported as render targets. There are enumerations for texture and z-buffer formats only. Probably the only way to know for sure is to try to create the render target surface and see if it's successful.

That said, I'd assume the Voodoo2 doesn't have WDDM drivers, so the format checks are likely very different than what I'm used to. With WDDM, if the driver doesn't mark the specific surface format as supporting render targets, then the runtime doesn't even attempt to call the driver's surface creation function. But with XPDM drivers it might be different, I don't know if those can expose such information at all.

Anyway, it seems NVIDIA supports rendering in A4R4G4B4 format too, it just doesn't expose the needed caps for some reason. I tried simply removing the DDSCAPS_3DDEVICE flag from all textures, which fixed a lot of the glitches, but some textures were still black. If instead I just fix the format caps in the driver, it has no issue creating RTTs in A4R4G4B4 format, and the black textures are also fixed. So I guess the game does render to some such textures, after all.

I don't know what kind of system you have the Voodoo2 in. If it supports Rohitab API Monitor, you could try capturing the DirectDraw interfaces with that, and then see what kind of surfaces are created. Though the game creates hundreds of surfaces, so it would be quite a chore to go through all of them.

There's also a ddtest utility in the DX7 SDK that allows you to experiment with creating various surfaces, but interestingly, it doesn't prevent you from creating the same RTT format that fails to be created by the game. I checked debug logs and there are only 2 main differences: the game (or perhaps the D3D runtime) adds some undocumented DDSCAPS2 flag (with value 0x100000), but it doesn't seem to matter if I remove that from the game. The other difference is that ddutil uses the old IDirectDraw interface, but the game uses IDirectDraw7. I guess this one is more relevant. IDirectDraw passes the surface creation on to the driver, even though it's not supposed to support it. The driver doesn't fail the request, so it ends up being successful.

BEENNath58 commented 11 months ago

The 3Dfx Voodoo2 uses VxD drivers, and on Windows 98 :)

I doubt API Monitor works in such an old environment. What I can test is installing Win2000 there and trying whatever drivers they have (probably Win2K doesn't have VxD drivers anymore) on WDM, utilising XPDDM. I can try that only tomorrow.

About the IDirectDraw difference: I assume you meant to say the glitch is because ddutil doesn't use IDD7 and thus passes on the driver which successfully creates the texture, which IDD7 can't do. Can it be that XP fixes that, i.e. use a different texture format or uses IDD3/IDD1?

Recall that Shadows of the Empire v1.0 used the IDirect3D method for fogging and the v1.1 patch changed it to IDirect3D3, which removed the requirement to use the D3DDI hooking in DxWnd.

narzoul commented 11 months ago

About the IDirectDraw difference: I assume you meant to say the glitch is because ddutil doesn't use IDD7 and thus passes on the driver which successfully creates the texture, which IDD7 can't do.

Yes, it seems the old IDirectDraw interface misses some checks for this and just blindly asks the driver to create something it doesn't support. IDirectDraw7 doesn't even bother calling the driver.

Can it be that XP fixes that, i.e. use a different texture format or uses IDD3/IDD1?

You mean the XP patch? I have no idea what it does. Curiously the trial version of the game doesn't have this issue either. It seems that it doesn't use render target textures, or at least not with that specific format.

BEENNath58 commented 11 months ago

Okay I guess it's better for users to utilise the XP patch. Who knows, maybe XP DirectDraw removed this mode (and only dgVoodoo2 restores it properly).

I would want to see this feature developed in future for DDC too, but I never saw any other game with this problem, so your current fix should be enough and satisfactory for most users (and that you have many more other problems to fix as well other than this).

narzoul commented 8 months ago

The mentioned fixes have been added to v0.5.0. You can also use the new ColorKeyMethod setting to emulate AMD-style texture color keying with the alphatest(1) value (for fixing the text in the startup screen of Extreme G-2).