protonscr

Proton 10 breaks OpenVR for 32bit Windows binaries

protonclosed Regression
ValveSoftware/Proton#8749 · opened 2025-05-29 by twhitehead · updated 2025-06-06 · 9 comments · github
2 matching comments, n / p to jump
Ttwhitehead 2025-05-29 github

When VR_Init is called from a 32bit Windows binary on a 64bit Linux machine, it either crashes or returns a huge number for the error code and 0 for the API table.

Here is a simple program that just calls VR_Init. Here is the trace in 32bit mode (this one died)

2805317.001:0188:018c:trace:loaddll:build_module Loaded L"C:\\vrclient\\bin\\vrclient.dll" at 7A9D0000: builtin
2805317.001:0188:018c:trace:vrclient:DllMain (7A9D0000, 1, 00000000)
2805317.001:0188:018c:trace:vrclient:VRClientCoreFactory name: IVRClientCore_003, return_code: 0080FA8C
2805317.011:0188:018c:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\rpcrt4.dll" at 7A850000: builtin
2805317.011:0188:018c:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\setupapi.dll" at 7A8F0000: builtin
2805317.012:0188:018c:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\winevulkan.dll" at 7A980000: builtin
2805317.012:0188:018c:trace:vrclient:load_vrclient got openvr runtime path: /home/tyson/.local/share/Steam/steamapps/common/SteamVR/bin/vrclient.so
2805317.019:0188:018c:trace:vrclient:get_winevulkan_unixlib path /home/tyson/.local/share/Steam/steamapps/common/Proton 10.0/files/lib/wine/i386-unix/winevulkan.so.
2805317.019:0188:018c:trace:vrclient:create_win_interface trying to create IVRClientCore_003
2805317.019:0188:018c:trace:vrclient:create_winIVRClientCore_IVRClientCore_003 -> 0082BD68
2805317.019:0188:018c:warn:seh:dispatch_exception backtrace: --- Exception 0xc0000005.
2805317.019:0188:018c:trace:seh:dispatch_exception code=c0000005 (EXCEPTION_ACCESS_VIOLATION) flags=0 addr=7BB41900
2805317.019:0188:018c:trace:seh:dispatch_exception  info[0]=00000001
2805317.019:0188:018c:trace:seh:dispatch_exception  info[1]=0000000A
2805317.019:0188:018c:trace:seh:dispatch_exception eip=7bb41900 esp=0080fa00 ebp=0080fa90 eflags=00010287
2805317.019:0188:018c:trace:seh:dispatch_exception eax=00000001 ebx=0080fae0 ecx=0000000f edx=fffffffe
2805317.019:0188:018c:trace:seh:dispatch_exception esi=00000000 edi=00000010 cs=0023 ds=002b es=002b fs=0063 gs=006b ss=002b
2805317.019:0188:018c:trace:seh:call_seh_handlers calling handler at 7BF696B0 code=c0000005 flags=0
2805317.019:0188:018c:trace:seh:signal (11, 00000000)
wine: Unhandled page fault on write access to 0000000A at address 7BB41900 (thread 018c), starting debugger...

and here it is in 64bit mode (this one is fine)

2805459.898:020c:0210:trace:loaddll:build_module Loaded L"C:\\vrclient\\bin\\vrclient_x64.dll" at 00006FFFFD9D0000: builtin
2805459.899:020c:0210:trace:vrclient:DllMain (00006FFFFD9D0000, 1, 0000000000000000)
2805459.899:020c:0210:trace:vrclient:VRClientCoreFactory name: IVRClientCore_003, return_code: 000000000022FA50
2805459.903:020c:0210:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\rpcrt4.dll" at 00006FFFFF900000: builtin
2805459.903:020c:0210:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\setupapi.dll" at 00006FFFFF870000: builtin
2805459.903:020c:0210:trace:loaddll:build_module Loaded L"C:\\windows\\system32\\winevulkan.dll" at 00006FFFFDC00000: builtin
2805459.903:020c:0210:trace:vrclient:load_vrclient got openvr runtime path: /home/tyson/.local/share/Steam/steamapps/common/SteamVR/bin/linux64/vrclient.so
2805459.903:020c:0210:trace:vrclient:get_winevulkan_unixlib path /home/tyson/.local/share/Steam/steamapps/common/Proton 10.0/files/lib/wine/x86_64-unix/winevulkan.so.
2805459.903:020c:0210:trace:vrclient:create_win_interface trying to create IVRClientCore_003
2805459.903:020c:0210:trace:vrclient:create_winIVRClientCore_IVRClientCore_003 -> 00000000002A39B0
2805459.903:020c:0210:trace:vrclient:winIVRClientCore_IVRClientCore_003_Init 00000000002A39B0
2805462.319:020c:0210:trace:vrclient:winIVRClientCore_IVRClientCore_003_IsInterfaceVersionValid 00000000002A39B0
2805462.321:020c:0210:trace:vrclient:winIVRClientCore_IVRClientCore_003_GetGenericInterface 00000000002A39B0
2805462.321:020c:0210:trace:vrclient:ivrclientcore_get_generic_interface 0x7f0c343752a8 000000014000A01E
2805462.321:020c:0210:trace:vrclient:create_win_interface trying to create IVRSystem_022
2805462.321:020c:0210:trace:vrclient:create_winIVRSystem_IVRSystem_022 -> 00000000002A3A70
Ttwhitehead 2025-05-30 github

@rbernon I expect you are already aware that 32bit OpenVR is broken in Proton 10 (VR_Init crashes), but CC just in case.

Ttwhitehead 2025-06-01 github

I did a bisect and it broke somewhere between proton-10.0-1b and the commit immediately following proton-9.0-4d.

I have been, unfortunately, not able to track it down closer than that as none of the intermediate commits will build for me.

Ttwhitehead 2025-06-03 github

Figured out that while I could not test the entire intermediate versions as they would not build, I could test just the vrclient_x64 portions by checking them out into nearby complete versions that did build.

Bisecting this way identified the problem commit as 454533f7e3964a25e787ef8910a81244a686d0f0. This commit changed the calling convention of VRClientCoreFactory and HmdSystemFactory from CDECL to __stdcall.

Reverting this commit on the head of the Proton_10.0 branch makes calling VR_Init work in 32bit mode again. 64bit continues to work as well, and I also tried a full 32bit VR program, and that works too.

CCing @bylaws as the author of the commit.

Aalasky17 2025-06-03 github

@twhitehead Do you have an example game that uses this? Thank you for all the details and investigation so far :)

Ttwhitehead 2025-06-03 github

Condor 2 and 3 are both examples. I use them via Revive under Linux as they internally use the Oculus VR API.

You don't need anything fancy to see this bug though. Any 32bit OpenVR application should be broken. You can't even successfully call VR_Init as can be seen by compiling and running this bit of code

#include <stdio.h>
#include <openvr.h>

int main() {
  vr::EVRInitError error = vr::VRInitError_Init_NotInitialized;
  
  vr::IVRSystem* ptr = vr::VR_Init(&error, vr::VRApplication_Scene);
  printf("ovr_Initialize(...): returned error %d and object %p\n", error, ptr);

  vr::VR_Shutdown();
  
  return error;  // vr::VRInitError_None == 0
}  
Ttwhitehead 2025-06-04 github

Dug into this a bit. Here are the details. Patch is following shortly.

The VRClientCoreFactory function is declared in the OpenVR SDK without a calling convention. According to Microsoft cdecl is the default calling convention for C and C++ functions, so this means that the user side needs VRClientCoreFactory to be cdecl and not stdcall.

In more detail, if the system side is stdcall (callee cleans stack), it is going to pop the arguments off the stack before returning. Then the client side is then going to do the same as it thinks it is cdecl (caller cleans stack). Obviously this ends badly as exhibited by the simple program above that just calls VR_Init.

The reason this only affects x86 code is these calling conventions only exist for x86. For x64 code they are simply ignored. See here for cdecl

On ARM and x64 processors, __cdecl is accepted but typically ignored by the compiler

and here for stdcall)

On ARM and x64 processors, __stdcall is accepted and ignored by the compiler

There is also a vrclient_x64.spec file checked in on the original commit that is currently declaring both of these to be stdcall too. Changing this to cdecl gets rid of the the following linker warnings

ld: warning: resolving _HmdSystemFactory@8 by linking to _HmdSystemFactory
ld: warning: resolving _VRClientCoreFactory@8 by linking to _VRClientCoreFactory

Apart from these warning, it seems these misdeclarations were not causing any issues as HmdSystemFactory does not appear to be used at all and VRClientCoreFactory is only called by the OpenVR SDK which accesses it directly by manually opening the dll, looking up the symbol, and assigning it to a cdecl function pointer.

Aalasky17 2025-06-05 github

@twhitehead Thank you! A fix just got pushed to the experimental-bleeding-edge in addition to reverting the problematic change. There is already a build available if you select the bleeding-edge beta option in the Proton - Experimental tool properties. However - coincidentally there is another regression that was just introduced in dxvk yesterday which we found while testing the fix for this regression, so your milage may vary depending on which games you are trying to play until that gets fully resolved, hopefully in the next day or two :)

Thank you again for the report and for all the details and investigation!

Aalasky17 2025-06-06 github

@twhitehead The secondary regression has now been fixed in experimental-bleeding-edge. Please let me know if you are still seeing a regression with any 32-bit openvr titles :)

Ttwhitehead 2025-06-06 github

Comes up fine now. Thanks very much. I'll close the ticket. 👍

Proton versions

DLLs

Error codes