Skip to content

Commit 8d63952

Browse files
committed
feat(pipeline): symmetric RGB-direct logging + rgb_direct_encode override
1 parent f174cc4 commit 8d63952

3 files changed

Lines changed: 54 additions & 4 deletions

File tree

src/config.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,27 @@ pub struct VideoStreamConfig {
251251
/// the messages can be very noisy.
252252
#[serde(default = "default_false")]
253253
pub log_frame_spikes: bool,
254+
255+
/// Controls use of `VK_VALVE_video_encode_rgb_conversion`, which lets the
256+
/// video encoder do RGB→YUV conversion inline (skipping the compute-shader
257+
/// convert path). Currently only RADV (AMD on Linux) advertises the
258+
/// extension; other drivers fall through to the compute-shader path.
259+
///
260+
/// - `auto` (default): use it when the device advertises support.
261+
/// - `off`: always use the compute-shader path, even when supported.
262+
/// Useful as an escape hatch if a driver regresses or for A/B testing.
263+
/// - `force`: require it; encoder creation fails loudly if not supported.
264+
#[serde(default)]
265+
pub rgb_direct_encode: RgbDirectMode,
266+
}
267+
268+
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
269+
#[serde(rename_all = "lowercase")]
270+
pub enum RgbDirectMode {
271+
#[default]
272+
Auto,
273+
Off,
274+
Force,
254275
}
255276

256277
impl Default for VideoStreamConfig {
@@ -260,6 +281,7 @@ impl Default for VideoStreamConfig {
260281
fec_percentage: 20,
261282
encrypt: false,
262283
log_frame_spikes: false,
284+
rgb_direct_encode: RgbDirectMode::default(),
263285
}
264286
}
265287
}

src/session/stream/video/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ impl VideoStreamInner {
253253
stop_session_manager.clone(),
254254
hdr_metadata_tx,
255255
self.config.stream.video.log_frame_spikes,
256+
self.config.stream.video.rgb_direct_encode,
256257
)?;
257258

258259
self.pipeline = Some(pipeline);

src/session/stream/video/pipeline/mod.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use ash::vk;
1414
use async_shutdown::ShutdownManager;
1515
use tokio::sync::{broadcast, mpsc, watch};
1616

17+
use crate::config::RgbDirectMode;
1718
use crate::session::compositor::frame::{ExportedFrame, FrameColorSpace, HdrModeState};
1819
use crate::session::manager::SessionShutdownReason;
1920

@@ -142,6 +143,7 @@ impl VideoPipeline {
142143
stop_session_manager: ShutdownManager<SessionShutdownReason>,
143144
hdr_metadata_tx: watch::Sender<HdrModeState>,
144145
log_frame_spikes: bool,
146+
rgb_direct_mode: RgbDirectMode,
145147
) -> Result<Self, ()> {
146148
tracing::debug!("Initializing video pipeline.");
147149

@@ -159,6 +161,7 @@ impl VideoPipeline {
159161
max_reference_frames,
160162
encryption_key,
161163
log_frame_spikes,
164+
rgb_direct_mode,
162165
};
163166

164167
std::thread::Builder::new()
@@ -192,6 +195,8 @@ struct VideoPipelineInner {
192195
max_reference_frames: u32,
193196
encryption_key: Option<Vec<u8>>,
194197
log_frame_spikes: bool,
198+
/// Controls VK_VALVE_video_encode_rgb_conversion usage at encoder creation.
199+
rgb_direct_mode: RgbDirectMode,
195200
}
196201

197202
impl VideoPipelineInner {
@@ -251,10 +256,32 @@ impl VideoPipelineInner {
251256

252257
// RGB-direct encode skips the compute-shader RGB→YUV pass and lets
253258
// the video encoder hardware do the conversion inline. Enabled
254-
// whenever the device advertises VK_VALVE_video_encode_rgb_conversion.
255-
let use_rgb_input = context.supports_rgb_direct_encode();
256-
if use_rgb_input {
257-
tracing::info!("RGB-direct encode path active (VK_VALVE_video_encode_rgb_conversion)");
259+
// whenever the device advertises VK_VALVE_video_encode_rgb_conversion,
260+
// unless overridden via [stream.video] rgb_direct_encode in config.
261+
let device_supports_rgb_direct = context.supports_rgb_direct_encode();
262+
let use_rgb_input = match self.rgb_direct_mode {
263+
RgbDirectMode::Auto => device_supports_rgb_direct,
264+
RgbDirectMode::Off => false,
265+
RgbDirectMode::Force => {
266+
if !device_supports_rgb_direct {
267+
return Err(
268+
"rgb_direct_encode = \"force\" but VK_VALVE_video_encode_rgb_conversion \
269+
is not advertised by this device"
270+
.to_string(),
271+
);
272+
}
273+
true
274+
},
275+
};
276+
match (self.rgb_direct_mode, device_supports_rgb_direct, use_rgb_input) {
277+
(_, _, true) => tracing::info!("RGB-direct encode path active (VK_VALVE_video_encode_rgb_conversion)"),
278+
(RgbDirectMode::Off, true, _) => tracing::info!(
279+
"Compute-shader RGB→YUV path active (rgb_direct_encode = \"off\" overrides device support)"
280+
),
281+
(_, false, _) => tracing::info!(
282+
"Compute-shader RGB→YUV path active (VK_VALVE_video_encode_rgb_conversion not supported by this device)"
283+
),
284+
_ => {},
258285
}
259286

260287
// Convert pixel format.

0 commit comments

Comments
 (0)