From 9e6ab9b94d5bec8b379fe5a0e01a0f0ef3abd406 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Fri, 17 Jul 2026 19:52:44 +0200 Subject: [PATCH] fix(qsv): enable D3D11 multithread protection before SetHandle (on-glass -16 on Arc) Co-Authored-By: Claude Fable 5 --- crates/pf-encode/src/enc/windows/qsv.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/crates/pf-encode/src/enc/windows/qsv.rs b/crates/pf-encode/src/enc/windows/qsv.rs index cdb26225..7fb8f020 100644 --- a/crates/pf-encode/src/enc/windows/qsv.rs +++ b/crates/pf-encode/src/enc/windows/qsv.rs @@ -68,6 +68,8 @@ fn sts_name(s: vpl::mfxStatus) -> &'static str { vpl::MFX_ERR_MEMORY_ALLOC => "MFX_ERR_MEMORY_ALLOC", vpl::MFX_ERR_INCOMPATIBLE_VIDEO_PARAM => "MFX_ERR_INCOMPATIBLE_VIDEO_PARAM", vpl::MFX_ERR_INVALID_VIDEO_PARAM => "MFX_ERR_INVALID_VIDEO_PARAM", + vpl::MFX_ERR_UNDEFINED_BEHAVIOR => "MFX_ERR_UNDEFINED_BEHAVIOR", + vpl::MFX_ERR_NOT_INITIALIZED => "MFX_ERR_NOT_INITIALIZED", vpl::MFX_WRN_DEVICE_BUSY => "MFX_WRN_DEVICE_BUSY", vpl::MFX_WRN_IN_EXECUTION => "MFX_WRN_IN_EXECUTION", vpl::MFX_WRN_INCOMPATIBLE_VIDEO_PARAM => "MFX_WRN_INCOMPATIBLE_VIDEO_PARAM", @@ -874,6 +876,15 @@ impl QsvEncoder { // synchronous SetHandle (the runtime AddRefs what it keeps). The multithread-protect QI // is standard COM on the owned immediate context. let dctx = unsafe { + let dctx = device + .GetImmediateContext() + .context("ID3D11Device immediate context")?; + // The runtime touches the device from its own threads — multithread protection + // must be ON **before** SetHandle or the runtime rejects the device with + // MFX_ERR_UNDEFINED_BEHAVIOR (-16, seen on-glass on Arc). + if let Ok(mt) = dctx.cast::() { + let _ = mt.SetMultithreadProtected(true); + } vpl_ok( vpl::MFXVideoCORE_SetHandle( session.0, @@ -882,14 +893,6 @@ impl QsvEncoder { ), "MFXVideoCORE_SetHandle(D3D11)", )?; - let dctx = device - .GetImmediateContext() - .context("ID3D11Device immediate context")?; - // The runtime touches the device from its own threads — D3D11 requires the - // multithread protection the VPL examples set. - if let Ok(mt) = dctx.cast::() { - let _ = mt.SetMultithreadProtected(true); - } dctx }; let (ltr_active, ir_active, bs_bytes) = self.init_encode(session.0)?;