Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SteamVR is handing DriverDirectModeComponent textures it didn't allocate #1884

Open
DelusionalLogic opened this issue Feb 10, 2025 · 5 comments

Comments

@DelusionalLogic
Copy link

Hey,

I've implemented a driver that uses the DriverDirectModeComponent for linux. From what I can read of the documentation in the headers, I'm supposed to get the textures I allocate in CreateSwapTextureSet back in SubmitLayer, instead it looks like I'm getting textures that I didn't allocate.

During startup I create 2 texture sets (as a response to CreateSwapTextureSet calls). These seem to be used for the "void" before the steamtours application launches.

Texture 0 ref 0x40000002 imported 0x70000abb3
Texture 1 ref 0x40000006 imported 0x80000abb3
Texture 2 ref 0x4000000a imported 0x90000abb3

Texture 2 ref 0x4000000a imported 0x90000abb3
Texture 1 ref 0x40000016 imported 0xb0000abb3
Texture 2 ref 0x4000001a imported 0xc0000abb3

Once that launches, there's a brief fade, and steamtours allocates it's own texture sets and the vrserver starts submitting those to me

vrclient_steamtours Mon Feb 10 2025 20:10:01.611496 [Info] - Created remote Vulkan image 0xe00000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
vrclient_steamtours Mon Feb 10 2025 20:10:01.615655 [Info] - Created remote Vulkan image 0xe10000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
vrclient_steamtours Mon Feb 10 2025 20:10:01.620448 [Info] - Created remote Vulkan image 0xe30000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
vrclient_steamtours Mon Feb 10 2025 20:10:01.626633 [Info] - Created remote Vulkan image 0xe40000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
vrclient_steamtours Mon Feb 10 2025 20:10:01.630465 [Info] - Created remote Vulkan image 0xe50000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
vrclient_steamtours Mon Feb 10 2025 20:10:01.635761 [Info] - Created remote Vulkan image 0xe60000abb3, dimensions 3574 x 3823, format 43, memory size 55050240 and memory type 0.
Unknown our ref 0xe00000abb3 skip

Is this expected behavior? It doesn't seem to align with the documentation, but I know the Linux implementation is quite different from the Windows one, and it's possible the documentation isn't correct for Linux.

@Rectus
Copy link

Rectus commented Feb 11, 2025

That's a really curious behavior.

OpenVR applications create their own swapchain textures. This behvior could be an optimization to avoid double-allocating textures. I'm guessing this double-allocation is the main reason why a lot of users on Windows have worse performance with streaming headsets when using SteamVR with third-party drivers. It would sense for Valve to improve this.

I'm curious what happens if you run an OpenXR application. OpenXR shifts the responsibility to create textures to the runtime, so it might pass the call to CreateSwapTextureSet.

@DelusionalLogic
Copy link
Author

As an additional oddity, there's also this line in the log specifying a max texture size larger than the one it then asks to allocate.

vrclient_steamtours Thu Feb 13 2025 20:24:19.650558 [Info] - Setting max texture dimensions to 3304x3534 before requiring downsampling

This isn't really a problem that I care about, but it's odd.

@Rectus
Copy link

Rectus commented Feb 13, 2025

That message just logs what the minimum resolution is for the compositor to use the advanced supersampling filter (which downsamples the output with a box filter instead of regular bilinear). It has nothing to do with what resolution the application actually outputs.

@DelusionalLogic
Copy link
Author

DelusionalLogic commented Feb 15, 2025

It has to work somehow differently on windows. Looking into the drivers there, It looks like valve is doing an FNV hash (based on the constants) of the texture (maybe even the bounds, but that seems nonsensical to me) and producing an error ("SVLHMDDriverDirectX11::SubmitLayer() can\'t find texture %p\n") if it can't find the texture.

Since the driver works on Windows, this must be a behavioral difference between the two implementations. Unfortunately, there's no documentation anywhere for what to do about it.

@DelusionalLogic
Copy link
Author

DelusionalLogic commented Feb 16, 2025

I spent half the day looking into the problem in the bytecode of vrclient. It looks like this is a harcoded behavior in the Linux vrclient. The windows vrclient connects to the vrserver process and asks it for textures as evidenced by the following log taken from Windows. Note that we see the vrcompositor create a set first and the steamtours application then creates it's own afterwards. This sort of matches the architecture we see on Linux, except for how steamtours allocates its texture.

Sun Feb 16 2025 08:54:47.245 [Info] - vrlink: SVLHMDDriverD3D11::CreateSwapTextureSet() completed.
Sun Feb 16 2025 08:54:47.246 [Info] - Set thread 0000000000002C8C priority to: 15
Sun Feb 16 2025 08:54:47.246 [Info] - Processing message VRMsg_CreateSwapTextureSet from 16032: vrcompositor took 0.163 seconds
Sun Feb 16 2025 08:54:47.246 [Detail] - Processing Message of type VRMsg_CreateSwapTextureSet (10 bytes) from 16032: vrcompositor
Sun Feb 16 2025 08:54:47.246 [Info] - vrlink: CreateSwapTextureSet: 3096x3312(29) 1
Sun Feb 16 2025 08:54:47.246 [Info] - vrlink: SVLHMDDriverD3D11::CreateSwapTextureSet() completed.
[SNIP]
Sun Feb 16 2025 08:54:53.955 [Detail] - Processing Message of type VRMsg_CreateSwapTextureSet (10 bytes) from 14064: steamtours
Sun Feb 16 2025 08:54:53.955 [Info] - vrlink: CreateSwapTextureSet: 3574x3823(29) 1
Sun Feb 16 2025 08:54:53.956 [Info] - vrlink: SVLHMDDriverD3D11::CreateSwapTextureSet() completed.
Sun Feb 16 2025 08:54:53.958 [Detail] - Processing Message of type VRMsg_CreateSwapTextureSet (10 bytes) from 14064: steamtours
Sun Feb 16 2025 08:54:53.958 [Info] - vrlink: CreateSwapTextureSet: 3574x3823(29) 1
Sun Feb 16 2025 08:54:53.958 [Info] - vrlink: SVLHMDDriverD3D11::CreateSwapTextureSet() completed.

Looking into the why. Steamtours allocates textures through vrclient. At some point it calls CVRCompositorSharedTextures::UpdateTextureSet which notices that we don't have a texture set, allocates a CVRCompositorSharedTextures::CSharedTextureSetSHM and calls CreateSharedTextures on it. This method then just creates the textures through CVRCompositorSharedTextures::SharedTextureDataVulkan_t::Create which finally allocates the textures from the compositor.

It looks to just be an oversight in the structure of the code. To me (as an uninformed guy just looking at bytecode) it looks like the code below CVRCompositorSharedTextures::CSharedTextureSetSHM would need to be restructured but that everything else would probably continue to work as sit does now. It's just a matter of where you get the shared texture handles from.

This is unfortunately quite difficult for me to work around as I don't get any of the texture details, and there's no published interface to query for them. I might be able to find something in the code, but it's a hassle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants