NVIDIAGameWorks / bridge-remix

This is the NVIDIA RTX Remix Runtime Bridge repository
MIT License
147 stars 26 forks source link

Midtown Madness crashes with RTX Remix #14

Open elishacloud opened 5 days ago

elishacloud commented 5 days ago

Microsoft's Midtown Madness uses Direct3D7 and I am using dxwrapper to convert it to Direct3D9. It works fine with dxwrapper and the latest build of DXVK, but when trying to use RTX Remix we are getting an error, as listed below.

Here is the files for the latest unreleased build: dxwrapper.zip

image

Here are the logs:

d3d9.log Open1560_d3d9.log

You can get a copy of Midtown Madness here.

Here are logs from the original game also:

d3d9.log midtown_d3d9.log

AlexDunn commented 2 days ago

Thanks @elishacloud - D3D7 support is awesome.

I dont see that on the latest builds. However, I do see the game (Open1560) flipping between 7280x2180 and 640x480 on my system. This flipping happens on the ::Present() call, and Im not really sure how to explain the behaviour.

elishacloud commented 2 days ago

@AlexDunn, thanks for looking into this. I don't have the means to test RTX Remix at the moment. Are you saying this is fixed with the latest released build or the latest dev build?

However, I do see the game (Open1560) flipping between 7280x2180 and 640x480 on my system.

That is weird. I have never seen that. I wonder if it is some type of DSR/SSAA scaling the game uses?

AlexDunn commented 2 days ago

It appears as though the game thinks its running at 640p. Do you have symbols for dxwrapper and a commit?

I havent fixed anything specifically for this, was just unable to repro using the latest builds.

AlexDunn commented 2 days ago

Actually, a little bit more digging and I did find an issue (although no error message).

When running the game in fullscreen it fails due to a missing implementation for D3D9SwapChainEx::GetRasterStatus.

The issue of flipping between 7280 and 640 is only visible when launching the game in windowed (-window)

AlexDunn commented 2 days ago

There is still no raytracing though. Presumably because of this line in the log: [RTX-Compatibility-Info] Skipped drawcall, using pre-transformed vertices which isn't currently supported.

Its common in these older GL/DX games to pretransform the geometry to screenspace before sending to the D3D API. Its possible to undo this projection, but it requires the game actually sends a projection matrix. Ideally both a projection and view matrix.

elishacloud commented 2 days ago

Do you have symbols for dxwrapper and a commit?

You should be able to get symbols for the latest release here: https://github.com/elishacloud/dxwrapper/actions/runs/10894375935

When running the game in fullscreen it fails due to a missing implementation for D3D9SwapChainEx::GetRasterStatus.

That is weird DX7 games don't use swap chains and dxwrapper does not use swap chains when converting the games to D3D9.

Its possible to undo this projection, but it requires the game actually sends a projection matrix. Ideally both a projection and view matrix.

I don't think there is much I can do here. I try to convert the DX7 functions call-by-call as directly as I can to D3D9. If the game doesn't call that I don't think there is anyway I can make the game do that.

AlexDunn commented 2 days ago

Thanks for sharing the symbols. The call stack which leads to GetRasterStatus is as follows: image

It looks like something internal to dxwrapper. The missing implementation on our side is definitely an issue here.

I don't think there is much I can do here. I try to convert the DX7 functions call-by-call as directly as I can to D3D9. If the game doesn't call that I don't think there is anyway I can make the game do that.

No there isnt much you can do without source code, that's just how this game was made.

elishacloud commented 2 days ago

The call stack which leads to GetRasterStatus is as follows:

Yes, I loop on GetRasterStatus waiting for the vertical blank, if I am unable to get that from D3DKMTWaitForVerticalBlankEvent. I guess RTX Remix takes the call and moves it over to the swap chain.

BTW: you can bypass that code by enabling ForceVsyncMode in the dxwrapper.ini file. Then as long as the game does not call WaitForVerticalBlank it should be good.