doitsujin / dxvk

Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine
zlib License
12.41k stars 795 forks source link

[D3D9] The Void needs bits of IDirect3DShaderValidator9 implementation. #2045

Open gofman opened 3 years ago

gofman commented 3 years ago

I've debugged 'The Void' Steam game some time ago (which was crashing at certain locations both with dxvk and Wine's d3d9) and figured that is the first known game which requires some bits of real IDirect3DShaderValidator9 implementation to work (I've put some details and PoC Wine implementation which adds the necessary bits to https://bugs.winehq.org/show_bug.cgi?id=47229).

The game disassembles and assembles back some shaders (I have no idea why). Some shaders fail to assemble back due to: 'dcl_texcoord10_pp v10' (only 10 inputs are supported in ps_3_0 and this is the eleventh) which result in the crash as the game doesn't consider D3DXAssembleShader() failures. With (partially) working shader validator the problematic shaders get rejected at the earlier stage (IIRC shader compilation from HLSL) and the game handles that fine.

The PoC patch for Wine's d3d9 attached to the Wine bug is enough to make game work.

For testing with the game, here is a save file and reproduction instructions: https://github.com/ValveSoftware/Proton/issues/4527. Also, here is the cheat sheet which explains how to open dev console and get to any location at once: https://forum.ice-pick.com/viewtopic.php?f=28&t=9044. Without that I would probably never get to a problematic spot.

Also, WRT game testing, it creates the compiled shader cache and once you have passed the problematic place successfully the next run won't trigger problematic behaviour (e. g., if you first run on Windows without dxvk and then with dxvk you won't reproduce it until the cache is cleared). So it is better to delete users/Public/Documents/My\ Games/Void/Cache/* before each run.

Joshua-Ashton commented 3 years ago

Thanks for putting this here, I have a branch for this that I forgot about :frog:

mz1193 commented 2 years ago

Just curious, has there been any progress with this?

robohappy commented 1 year ago

Progress update on this issue?

MisterManji commented 1 year ago

It'd be great if there was a proton version with that patch that's supposed to make the game work past the problematic area pre-applied. It's way complicated for me to patch it myself.

simifor commented 12 months ago

Issue still happens with dxvk 2.2. @Joshua-Ashton could you share the name of the branch you had for this?

Blisto91 commented 12 months ago

https://github.com/doitsujin/dxvk/tree/d3d9-shader-val2 But it needs more work even when the compiler error is fixed.

simifor commented 11 months ago

There are a few errors that are easy to work around with:

Added "#include " to: ./src/dxvk/dxvk_buffer.h ./src/dxgi/dxgi_swapchain.cpp ./src/dxgi/dxgi_factory.cpp ./src/dxgi/dxgi_output.cpp ./src/dxgi/dxgi_main.cpp ./src/d3d10/d3d10_multithread.cpp

Added "#include " to: ./src/d3d10/d3d10_reflection.h

But then there's more complicated stuff like:

../../../src/d3d9/d3d9_shader_validator.h:118:37: error: cannot bind non-const lvalue reference of type ‘dxvk::DxsoCodeIter&’ to an rvalue of type ‘dxvk::DxsoCodeIter’

118 |       if (!m_ctx->decodeInstruction(DxsoCodeIter{ reinterpret_cast<const uint32_t*>(pdwInst) }))

So I changed:

      DxsoReader reader = { reinterpret_cast<const char*>(pdwInst) };

      if (m_state == D3D9ShaderValidatorState::ValidatingHeader)
        return ValidateHeader(pFile, Line, pdwInst, cdw);

      if (!m_ctx->decodeInstruction(DxsoCodeIter{ reinterpret_cast<const uint32_t*>(pdwInst) }))

into (which might not be correct):

      DxsoReader reader = { reinterpret_cast<const char*>(pdwInst) };
      DxsoCodeIter iter(reinterpret_cast<const uint32_t*>(pdwInst));

      if (m_state == D3D9ShaderValidatorState::ValidatingHeader)
        return ValidateHeader(pFile, Line, pdwInst, cdw);

      if (!m_ctx->decodeInstruction(iter))

Which allowed me to build dxvk, unfortunately, the game still dies with this.