protonscr

[d3d9] Pico Park: Classic Edition (Steam id 461040) renders white screen only on some machines

dxvkclosed d3d9fixed function
doitsujin/dxvk#2926 · opened 2022-09-16 by gofman · updated 2022-09-30 · 5 comments · github
Ggofman 2022-09-16 github

That is not universally reproducible, e. g, I could reproduce it on Deck and my AMD desktop but not on Nvidia (while other people were seeing that on Nvidia too).

The issue is not there with wined3d (but running that with wined3d hits an unrelated bug which I have fixed only locally so far).
I didn't reproduce the issue on the same AMD desktop when running with DXVK on Windows, although recorded apitrace (from native Windows d3d9) reproduces the issue when replayed on Linux with dxvk (attaching the apitrace here just in case).

The game is using FFP only (at least at start) and in rather simple way (e. g., no lighting, vertex blending or else trickery). The issue seems to be in the world / projection matrix multiplication precision in ffp shader. I first proved that by hacking the thing in the following way:

  • provide identity matrices to ffp shader;
  • perform multiplication on the CPU in DrawPrimitiveUP (the only draw functions called at start are DrawPrimitiveUP with 2 triangles).
    This way it renders fine. The culprit seems to be in Z coordinate which ends up being exactly 0 when multiplying on the CPU (while that is achieved with non-orthogonal matrices and involves nonzero multiplication and addition to get that final zero). I think in the shader it gets slightly negative (or maybe even just -0.0f??) and hits clipping.

That is clipping, not depth or other test which is failing (all those tests may be hack-disabled with the same result).

I am attaching a proof of concept hack which lets it render (the hack does depth clamping insted of clipping).

pico_park.zip

poc.txt

Ddoitsujin maintainer 2022-09-16 github

Did some testing and it seems that depth clip is unconditionally enabled on native D3D9, so DXVK behaves correctly there and I guess the only solution is to actually do the mutliplication on the CPU side using a very specific instruction sequence? How exactly did you do the multiplication?

It's rather absurd that games are relying on this.

Ddoitsujin maintainer 2022-09-17 github

Fixed in above commit.

Aalasky17 2022-09-30 github

@doitsujin @K0bin Is this one that we could get in the 1.10.x branch so that it can be fixed in Proton-stable?

KK0bin maintainer 2022-09-30 github

Already done.
#2934

Aalasky17 2022-09-30 github

@K0bin Sweet!!! Thank you so much :)

Nothing extracted yet.