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 ///