From 803f7f5398fc73ed9c5229ff9f9758591739d1ad Mon Sep 17 00:00:00 2001 From: Sil Vilerino Date: Thu, 7 Mar 2024 08:01:54 -0500 Subject: [PATCH] d3d12: Video Encode - Add driver workaround for rate control reconfiguration Adds a driver workaround for IHVs actually supporting rate control reconfiguration but not reporting it in the DX12 driver support flags, and later having crashes/hangs in the driver when the rate control reconfiguration happens using the fallback method that includes re-creating the encoder state and encoder heap objects upon new rate control params Part-of: --- src/gallium/drivers/d3d12/d3d12_video_enc.cpp | 29 +++++++++++++++---- src/gallium/drivers/d3d12/d3d12_video_enc.h | 11 +++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index c61c8e29853..1cc40dd949f 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -511,12 +511,18 @@ d3d12_video_encoder_reconfigure_encoder_objects(struct d3d12_video_encoder *pD3D // If on-the-fly reconfiguration happened without object recreation, set // D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_*_CHANGED reconfiguration flags in EncodeFrame - if (rateControlChanged && - ((pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags & - D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_RECONFIGURATION_AVAILABLE) != - 0 /*checking if the flag it's actually set*/) && - (pD3D12Enc->m_fenceValue > 1) && (!reCreatedEncoder || !reCreatedEncoderHeap)) { - pD3D12Enc->m_currentEncodeConfig.m_seqFlags |= D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_RATE_CONTROL_CHANGE; + + // When driver workaround for rate control reconfig is active we cannot send to the driver the + // D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_RATE_CONTROL_CHANGE since it's not actually reporting + // support for setting it. + if ((pD3D12Enc->driver_workarounds & d3d12_video_encoder_driver_workaround_rate_control_reconfig) == 0) { + if (rateControlChanged && + ((pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags & + D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_RECONFIGURATION_AVAILABLE) != + 0 /*checking if the flag it's actually set*/) && + (pD3D12Enc->m_fenceValue > 1) && (!reCreatedEncoder || !reCreatedEncoderHeap)) { + pD3D12Enc->m_currentEncodeConfig.m_seqFlags |= D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_RATE_CONTROL_CHANGE; + } } if (slicesChanged && @@ -1376,6 +1382,17 @@ bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3 return false; } } + + // Workaround for drivers supporting rate control reconfiguration but not reporting it + // and having issues with encoder state/heap objects recreation + if (pD3D12Enc->m_pD3D12Screen->vendor_id == 0x8086 /* HW_VENDOR_INTEL */) { + // If IHV driver doesn't report reconfiguration, force doing the reconfiguration without object recreation + if ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_RECONFIGURATION_AVAILABLE) == 0) { + pD3D12Enc->driver_workarounds |= d3d12_video_encoder_driver_workaround_rate_control_reconfig; + capEncoderSupportData1.SupportFlags |= D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_RECONFIGURATION_AVAILABLE; + } + } + pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags = capEncoderSupportData1.SupportFlags; pD3D12Enc->m_currentEncodeCapabilities.m_ValidationFlags = capEncoderSupportData1.ValidationFlags; return true; diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index 2c1bb72ff56..64bbe062f2e 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -356,6 +356,15 @@ struct EncodedBitstreamResolvedMetadata struct d3d12_fence m_FenceData; }; +enum d3d12_video_encoder_driver_workarounds +{ + d3d12_video_encoder_driver_workaround_none = 0x0, + // Workaround for drivers supporting rate control reconfiguration but not reporting it + // and having issues with encoder state/heap objects recreation + d3d12_video_encoder_driver_workaround_rate_control_reconfig = 0x1, +}; +DEFINE_ENUM_FLAG_OPERATORS(d3d12_video_encoder_driver_workarounds); + struct d3d12_video_encoder { struct pipe_video_codec base = {}; @@ -363,6 +372,8 @@ struct d3d12_video_encoder struct d3d12_screen * m_pD3D12Screen = nullptr; UINT max_quality_levels = 1; + enum d3d12_video_encoder_driver_workarounds driver_workarounds = d3d12_video_encoder_driver_workaround_none; + /// /// D3D12 objects and context info ///