elishacloud / dxwrapper

Fixes compatibility issues with older games running on Windows 10/11 by wrapping DirectX dlls. Also allows loading custom libraries with the file extension .asi into game processes.
zlib License
1.17k stars 83 forks source link

Investigate Far Cry water reflections #5

Closed mirh closed 6 years ago

mirh commented 6 years ago

thread

elishacloud commented 6 years ago

Interesting. I am not quite sure what could be causing this issue but I will check it out. Seems easy enough to reproduce.

CookiePLMonster commented 6 years ago

Any news on this? Might investigate it at some point soon, since I got the game just for this.

elishacloud commented 6 years ago

@CookiePLMonster, I have not had much time to look into this issue. I also purchased the game from GOG because of this. Initially I thought the issue was related to shaders, but so far I have not found any issues with the shaders. Though I will admit I have not ruled them out yet. If you get a chance to look into this let me know what you find out.

CookiePLMonster commented 6 years ago

My experience with FC has been terrible so far - not sure if it depends on particular detail settings but I have been facing constant crashes (we're talking 90 seconds of gameplay TOPS), frame drops (down to 8FPS, no joke)... other than that, Alt-Tab consistently leaves my game in a locked up state, mouse cursor leaves smudges in main menu...

I'll try playing around with this a bit more. I have never seen people complain about those specific issues so maybe detail settings are broken (game auto-defaults to minimum details for me, which makes me think they probably broke a VRAM check by making it signed, so my 8GB VRAM GPU shows as -2GB instead of 4GB for this 32-bit game). I haven't checked the 64-bit version yet either.

I also thought the water issue would be related to shaders, however - have you compared pix frames between XP and non-XP?

elishacloud commented 6 years ago

I have not had any problems with FC so far (other than the reflection issue). I am running at the highest setting for every graphic option. My graphics card only has 3GBs of VRAM. I am using a GeForce GTX 780.

I have not tried running PIX yet to compare frames. I have mainly focused on the PixelShaders using my d3d9 wrapper.

CookiePLMonster commented 6 years ago

Does vsync work for you? No matter what I do I can't get it to work.

elishacloud commented 6 years ago

When I enable vsync I get some stuttering and screen tearing.

elishacloud commented 6 years ago

Not sure if you have see this guide, but it has some interesting details on Far Cry, especially page 8.

r_Quality_Reflection [0,1] - 0=Off, 1=On. If turned on allows reflection of all surrounding objects in the water. This decreases FPS in areas with water but increases realism.

Also looking at the Shaders\Cache\CGVShaders folder tells me that this may be handled by a VertexShader not a PixelShader.

CookiePLMonster commented 6 years ago

Makes sense.

About vsync, it's weird since I am unable to get it to work, even though it's enabled in options... I wonder if it's my error or some other incompatibility.

mirh commented 6 years ago

Maybe first try to figure out why you are so special to crash every minute or so /s

CookiePLMonster commented 6 years ago

Since it's impossible to proceed with this, it's probably going to happen first, yeah.

Then again I stopped crashing after reseting settings (recommended ones being lowest possible...) so maybe I just need to give it another chance.

CookiePLMonster commented 6 years ago

This is worrying... I gave it another try today and none of the issues I had manifest themselves now... I should maybe check if Steam shader cache hides them.

mirh commented 6 years ago

Pretty extremely sure steam cache has nothing to do with older games. ... Maybe W10 did update something?

CookiePLMonster commented 6 years ago

I doubt it. Anyway, now I can take a look at this issue soon.

CookiePLMonster commented 6 years ago

So, so far... I have no idea what is going on. This has to be the weirdest issue I ever got to debug, since "wrong" PIX frames capturted on Windows 10... display correctly on Windows XP!

For example, water reflection on Win10 looks like this: ref102

But the same frame looks like this on XP: refxp2

Both have the same draws and both show correct mesh postVS and preVS, but on Win10 I don't even see those pixels in pixel history - not even as rejected by depth/alpha/stencil test.

It's weird. I thought maybe pixel shader is busted, but even that should output something (at least I should be able to see output in pixel history). Rocks on this screen are rendered with this PS:

    ps_1_1
    def c2, 0.5, 0.5, 0.5, 1
    tex t0
    tex t1
    tex t2
    mul r0.xyz, t0, v0.w
  + mov r0.w, v0.z
    mul_x2 r0.xyz, r0, c0
    lrp r1.xyz, r0.w, t1, c2
    mul_x2 r0.xyz, r0, r1
  + mov r0.w, v1.z
    lrp r1.xyz, r0.w, t2, c2
  + mul r0.w, t0, v0
    mul_x2 r0.xyz, r0, r1

// approximately 9 instruction slots used (3 texture, 6 arithmetic)

EDIT: I know those screens look so absurd so it looks like April Fools, but I can confirm that tomorrow ^^

CookiePLMonster commented 6 years ago

far cry screenshot 2018 04 01 - 15 50 52 55

mirh commented 6 years ago

And then GOG shouldn't throw money at you..

CookiePLMonster commented 6 years ago

OK, so as here https://github.com/CookiePLMonster/SilentPatchFarCry/commit/fb79e575e7cb9f9d07a8f35733be4b41caa69dca

I implemented a fix by saving clip planes and lazily setting active ones before each draw call. This fix is fully reliable (and generic), but it's definitely too broad...

Basing on hours of testing and trial and error by now it's not exactly "draw calls invalidate clip planes" like I thought (and like the fix suggests) - planes get corrupted/invalidated by something else, but I can't quite make out what.

I tried caching SetClipPlane values and letting them to D3D directly (as opposed to just caching and setting lazily) and re-submitting them from SetVertexShader and/or SetVertexShaderConstants - but that does not fix the issue fully. Most of the geometry is fine, but looks like the first batch of geometries drawn after enabling clip planes is still missing.

This is definitely a bug and it may not be as obvious as I initially thought - but thankfully current fix is reliable, albeit maybe too broad. However, 1 extra D3D call for each clipped draw call is really a non-issue.

EDIT: I'm not sure if @crosire would be interested in this issue, but it may also concern d3d8to9 (because now using d3d9 makes it "vulnerable" to the issue) and ReShade... plus maybe also some NVidia-fu =)

elishacloud commented 6 years ago

Nice! Works flawlessly for me. Would be interesting to figure out why clip planes are getting corrupted.

mirh commented 6 years ago

Mh.. Guess like that would require some hefty disassembly? @UCyborg @Marcinosoft maybe you are interested in this.

CookiePLMonster commented 6 years ago

For me, this looks like some optimization/precomputation being applied to those (maybe calculating clipping space?) which does not carry for subsequent draws - notice not all draws are busted (trees reflect fine), so it's not like planes are corrupted for all calls.

I re-retested last night again - if I remove lazy setting entirely and re-apply planes from those functions:

I get better results - geometry is mostly there, but with some holes which in my case appear/dissapear depending on camera angle and placement (different order of draws? different shaders used?).

I gave up trying to come up with a less "heavy" fix (though admitedly, 1 extra D3D call for each draw call per enabled clip plane is nothing, as most of the time clip planes are disabled anyway) for one important reason - even if I ended up fixing it by re-submitting planes from X functions, I can't say for sure it would be exhaustive - more calls may every well also be causing issues. Besides, current fix was tested with all three GPU vendors and confirmed working flawlessly.

elishacloud commented 6 years ago

I am not sure if they has anything to do with it, but I was looking up the Microsoft documentation and according to this site calling Clear() with NULL "will clear the entire viewport".

I notice that once in each frame immediately after the game calls SetViewport() it calls Clear(), removing the viewport that was just called. Why would the game set a viewport and then immediately clear it before the viewport was ever used?

Is it possible that Clear() works differently on Windows 8/10 than the game expects?

farcry_clear

CookiePLMonster commented 6 years ago

It could be... but I'm pretty sure they set viewport and then clear it so they clear the entire image - leaving viewport as smaller and then clearing would probably clear only a part of the image...

By the way, have you been able to get VSync to work? I can't get it on Win7 nor Win10.

CookiePLMonster commented 6 years ago

Interesting quirk: clip planes can be disabled via system.cfg by adding this: d3d9_ClipPlanes = "0"

elishacloud commented 6 years ago

@CookiePLMonster, no I have not been able to get VSync to work for me. I am also using Win10.

Also, disabling the clip planes solved the initial reflection issue but also caused a whole bunch of new "artifacts" in the water.

CookiePLMonster commented 6 years ago

Sure, it makes perfect sense - they use clip planes to cull underwater geometry so it doesn't end up rendered in a reflection map. Disabling clip planes makes them reflect.

About VSync, by now I'm pretty sure it's totally broken so I hooked up some custom code for that.

This issue can be closed now, I guess? Your fix is in place and mine is releasing tomorrow-ish.

elishacloud commented 6 years ago

About VSync, by now I'm pretty sure it's totally broken so I hooked up some custom code for that.

Nice! Great work!

mirh commented 6 years ago

This issue can be closed now, I guess?

I guess like it depends on whehter one simply wants "fixes" or even "documentation" of them.

elishacloud commented 6 years ago

I added a wiki for the Far Cry fix.

Note: I did not fix VSync yet, but can add an option for that later. @CookiePLMonster fix is better since he actually checks the status of the VSync option. I plan on just adding a VSync option to dxwrapper.

Closing the issue.

CookiePLMonster commented 6 years ago

Though on the flip side, I like your SetRenderState more - even though I can't imagine any cases where it would report failure (with valid parameters), it doesn't hurt accounting for it like you did in your fix!

On semi-unrelated note, do you think it's worth submitting identical PRs for d3d8to9 and ReShade? I would say it makes sense, especially since the fix is very cheap and I literally can't imagine any cases where it introduces regressions.

elishacloud commented 5 years ago

@CookiePLMonster, the vsync issue with Far Cry could be related to the issue here.

CookiePLMonster commented 5 years ago

Doubt it - if I recall correctly, FC never requested anything else but immediate interval. If it requested a default one though then you are probably right.

BTW. I am not 100% sure if it's an universal Win10 issue, since my current experiments with CRC Extreme showed that by default the game used a default presentation interval, yet I am 100% sure vsync worked.

elishacloud commented 5 years ago

Yep. You are right. It looks like the the Far Cry vsync fix changed it from 'immediate' to 'one'.

holybagpipes commented 4 years ago

@elishacloud Sorry for necro-ing this thread but I've tried the fix for the reflections and it tends to crash quite a bit. This is with the GOG release and the 64-bit addon since the wrapper doesn't seem to work with the 64-bit version.