Hello @CruCo, we're tracking issues with game mods with the game that's being modified. Also, we're using one issue report per unofficially supported game title, so I've gone ahead and transferred this issue report to https://github.com/ValveSoftware/Proton/issues/291#issuecomment-6235815259.
Summary
wineopenxrcorrupts composition layers inxrEndFramewhen the first layer and later layers have different struct sizes. A typical case is oneXrCompositionLayerProjectionfollowed by two or moreXrCompositionLayerQuad. The runtime receives garbage poses, and SteamVR rejects every such frame withXR_ERROR_POSE_INVALID.Cause
In
wineopenxr/openxr_thunks.c(generated bymake_openxr, checked at experimental_11.07a94df49e4695fc101fd47d614166e69c43d9669),convert_XrCompositionLayerBaseHeader_pointer_array_win64_to_hostchooses a single element size for all layers fromin[0]->type:conversion_context_allocis a bump allocator (openxr_private.h). With a projection first, each quad (112 bytes on x64) is written into a 48-byte slot. The next layer's allocation starts inside the previous quad, so converting quad n+1 overwrites thepose/sizeof quad n. With a single trailing quad the overflow lands in unused buffer space, which is why simple apps work. Thewin32variant and the generator code that emitspolymorphic_elem_size(...)for these arrays have the same pattern.Expected
Each layer is allocated with the size of its own type. For example, compute the size per element inside the loop from
in[i]->type, or use the largest layer struct size.Reproduction
[projection, quad, quad]in onexrEndFrame.XR_ERROR_POSE_INVALID. Logged layer data beforexrEndFrameis valid (unit quaternions, sane sizes and rects).layers[0]is a quad) makes all frames succeed and the quads render correctly. That confirms the conversion as the cause.Mod-side report with logs: https://github.com/dubrovskiy-yevhen-stakelogic/vice-city-vr/issues/22