Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion shaders/src/overlay.frag
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ layout(set = 0, binding = 0) uniform sampler2D overlay;
layout(location = 0) in vec2 texCoord;
layout(location = 0) out vec4 color;

// Manually decode sRGB. The game texture is UNORM but its bytes are
// sRGB-encoded (typical for game backbuffers). Sampling a UNORM view returns
// the raw byte value which the hardware treats as linear. We convert here so
// the sRGB swapchain attachment re-encodes it correctly, giving a lossless
// round-trip through the compositor.
vec3 srgb_to_linear(vec3 c) {
bvec3 cutoff = lessThan(c, vec3(0.04045));
vec3 lo = c / vec3(12.92);
vec3 hi = pow((c + vec3(0.055)) / vec3(1.055), vec3(2.4));
return mix(hi, lo, cutoff);
}

void main() {
color = texture(overlay, texCoord);
vec4 sampled = texture(overlay, texCoord);
color = vec4(srgb_to_linear(sampled.rgb), sampled.a);
}
9 changes: 8 additions & 1 deletion src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,8 +891,15 @@ impl vr::IVRCompositor029_Interface for Compositor {
}

if *self.frame_state.lock().unwrap() == FrameState::Waited {
// discard frame
// Auto-flush pending overlay-only frame: begin it and immediately
// submit so overlay layers reach the compositor for games that
// never call Submit / PostPresentHandoff (e.g. menu-only frames).
// Normal games that submit each frame don't end up in Waited
// state here, so this is transparent to them.
self.maybe_begin_frame(&session_data);
if *self.frame_state.lock().unwrap() == FrameState::Begun {
self.PostPresentHandoff();
}
}
self.maybe_wait_frame(&session_data);

Expand Down
Loading
Loading