mediafoundation: add mechanism to disable async and h.264 unwrapped POC (commented out for now) according to gpu/version

Reviewed-by: Yubo Xie <yuboxie@microsoft.com>
Reviewed-by: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35219>
This commit is contained in:
Pohsiang (John) Hsu 2025-05-21 17:01:20 -07:00 committed by Marge Bot
parent 061085708a
commit 0107d94632
8 changed files with 70 additions and 20 deletions

View file

@ -924,10 +924,9 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value )
}
else if( *Api == CODECAPI_AVLowLatencyMode )
{
// TODO: remove this code path when we clarify whether this is supported on AMD.
if( m_deviceVendor == "AMD" )
if( m_gpuFeatureFlags.m_bDisableAsync )
{
debug_printf( "[dx12 hmft 0x%p] Device vendor is AMD, ignore LowLatency Settings\n", this );
debug_printf( "[dx12 hmft 0x%p] Async is disabled due to lack of GPU support \n", this );
m_bLowLatency = TRUE;
}
else

View file

@ -1174,7 +1174,8 @@ CDX12EncHMFT::CreateGOPTracker( uint32_t textureWidth, uint32_t textureHeight )
MaxHWL0Ref,
MaxHWL1Ref,
m_pPipeVideoCodec->max_references,
m_uiMaxLongTermReferences );
m_uiMaxLongTermReferences,
m_gpuFeatureFlags.m_bH264SendUnwrappedPOC );
CHECKNULL_GOTO( m_pGOPTracker, MF_E_INVALIDMEDIATYPE, done );

View file

@ -93,10 +93,10 @@ CMFD3DManager::Shutdown( bool bReleaseDeviceManager )
{
m_pVlScreen->destroy( this->m_pVlScreen );
m_pVlScreen = nullptr;
m_deviceVendor = {};
m_deviceVendorId = {};
m_deviceDeviceId = {};
m_deviceDriverVersion = {};
m_gpuFeatureFlags = {};
}
if( m_pWinsys )
@ -207,13 +207,12 @@ CMFD3DManager::GetDeviceInfo()
m_deviceVendorId = desc.VendorId;
m_deviceDeviceId = desc.DeviceId;
m_deviceVendor = VendorIDToString( m_deviceVendorId );
m_deviceDriverVersion.part1 = ExtractDriverVersionComponent( 3, driverVersion );
m_deviceDriverVersion.part2 = ExtractDriverVersionComponent( 2, driverVersion );
m_deviceDriverVersion.part3 = ExtractDriverVersionComponent( 1, driverVersion );
m_deviceDriverVersion.part4 = ExtractDriverVersionComponent( 0, driverVersion );
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: device vendor = %s\n", m_logId, m_deviceVendor.c_str() );
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: device vendor = %s\n", m_logId, VendorIDToString( m_deviceVendorId ) );
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: device vendor id = %x\n", m_logId, m_deviceVendorId );
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: device device id = %x\n", m_logId, m_deviceDeviceId );
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: %S", m_logId, desc.Description );
@ -227,6 +226,28 @@ done:
return hr;
}
void
CMFD3DManager::UpdateGPUFeatureFlags()
{
if( m_deviceVendorId == MFT_HW_VENDOR_AMD )
{
m_gpuFeatureFlags.m_bDisableAsync = true;
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: GPUFeature m_bDisableAsync is set to true\n", m_logId );
}
/*
if( m_deviceVendorId == MFT_HW_VENDOR_NVIDIA )
{
if( m_deviceDriverVersion.part1 >= 32 && m_deviceDriverVersion.part2 >= 0 && m_deviceDriverVersion.part3 >= 15 &&
m_deviceDriverVersion.part4 >= 9002 )
{
m_gpuFeatureFlags.m_bH264SendUnwrappedPOC = true;
MFE_INFO( "[dx12 hmft 0x%p] D3DManager: GPUFeature m_bH264SendUnwrappedPOC is set to true\n", m_logId );
}
}
*/
}
HRESULT
CMFD3DManager::xOnSetD3DManager( ULONG_PTR ulParam )
{
@ -256,6 +277,8 @@ CMFD3DManager::xOnSetD3DManager( ULONG_PTR ulParam )
CHECKHR_GOTO( GetDeviceInfo(), done );
UpdateGPUFeatureFlags();
done:
if( FAILED( hr ) )
{

View file

@ -80,6 +80,7 @@ class CMFD3DManager
protected:
HRESULT xReopenDeviceManager( bool bNewDevice );
HRESULT GetDeviceInfo();
void UpdateGPUFeatureFlags();
ComPtr<IMFDXGIDeviceManager> m_spDeviceManager;
ComPtr<ID3D11Device5> m_spDevice11;
@ -93,11 +94,19 @@ class CMFD3DManager
struct sw_winsys *m_pWinsys = nullptr;
struct pipe_context *m_pPipeContext = nullptr;
std::string m_deviceVendor {};
uint32_t m_deviceVendorId {};
uint32_t m_deviceDeviceId {};
MFAdapterDriverVersion m_deviceDriverVersion {};
// MFT features that are dependent on GPU / version (ensure these are named to be false by default so we can easily reset this
// struct)
struct GPUFeatureFlags
{
bool m_bDisableAsync = false;
bool m_bH264SendUnwrappedPOC = false;
};
GPUFeatureFlags m_gpuFeatureFlags;
private:
D3D12_VIDEO_ENCODER_CODEC m_codec;
const void *m_logId = {};

View file

@ -543,10 +543,9 @@ CDX12EncHMFT::OnOutputTypeChanged()
}
CHECKHR_GOTO( InitializeEncoder( m_outputPipeProfile, m_uiOutputWidth, m_uiOutputHeight ), done );
// TODO: remove this code path when we clarify whether this is supported on AMD.
if( m_deviceVendor == "AMD" )
if( m_gpuFeatureFlags.m_bDisableAsync )
{
MFE_INFO( "[dx12 hmft 0x%p] Device vendor is AMD, turn off async mode until issue is worked out", this );
MFE_INFO( "[dx12 hmft 0x%p] Async is disabled due to lack of GPU support.", this );
m_bLowLatency = TRUE;
}
else

View file

@ -43,12 +43,14 @@ reference_frames_tracker_h264::reference_frames_tracker_h264( struct pipe_video_
uint32_t MaxL0References,
uint32_t MaxL1References,
uint32_t MaxDPBCapacity,
uint32_t MaxLongTermReferences )
uint32_t MaxLongTermReferences,
bool bSendUnwrappedPOC )
: m_codec( codec ),
m_MaxL0References( MaxL0References ),
m_MaxL1References( MaxL1References ),
m_MaxDPBCapacity( MaxDPBCapacity ),
m_MaxLongTermReferences( MaxLongTermReferences ),
m_bSendUnwrappedPOC( bSendUnwrappedPOC ),
m_ALL_LTR_VALID_MASK( ( 1 << m_MaxLongTermReferences ) - 1 ),
m_DPBManager(
m_codec,
@ -595,14 +597,28 @@ reference_frames_tracker_h264::GOPStateBeginFrame( bool forceKey )
{
m_gop_state.reference_type = frame_descriptor_reference_type_short_term;
m_gop_state.temporal_id = 0;
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num ) % ( 2 * m_max_frame_num );
if( m_bSendUnwrappedPOC )
{
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num_no_wrap );
}
else
{
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num ) % ( 2 * m_max_frame_num );
}
m_gop_state.current_reference_frame_count++;
}
else
{
m_gop_state.reference_type = frame_descriptor_reference_type_none;
m_gop_state.temporal_id = 1;
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num - 1 ) % ( 2 * m_max_frame_num );
if( m_bSendUnwrappedPOC )
{
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num_no_wrap - 1 );
}
else
{
m_gop_state.picture_order_count = ( 2 * m_gop_state.frame_num - 1 ) % ( 2 * m_max_frame_num );
}
}
}
}

View file

@ -37,8 +37,8 @@ typedef struct frame_descriptor_h264
uint32_t ip_period;
pipe_h2645_enc_picture_type frame_type;
uint32_t frame_num; // H264: frame_num % max_frame_num, reset on IDR
uint64_t frame_num_no_wrap;
uint64_t current_reference_frame_count;
uint32_t frame_num_no_wrap;
uint32_t current_reference_frame_count;
uint32_t picture_order_count;
frame_descriptor_reference_type reference_type;
uint32_t ltr_index;
@ -68,7 +68,7 @@ class reference_frames_tracker_h264 : public reference_frames_tracker
{
uint32_t picture_order_count;
uint32_t frame_num;
uint64_t frame_num_no_wrap;
uint32_t frame_num_no_wrap;
bool is_ltr;
uint32_t ltr_index;
uint8_t temporal_id;
@ -81,7 +81,7 @@ class reference_frames_tracker_h264 : public reference_frames_tracker
{
uint8_t pos; // index into location in the PrevFrameInfo array
// below are from PrevFrameInfo
uint64_t frame_num_no_wrap;
uint32_t frame_num_no_wrap;
bool is_ltr;
uint32_t ltr_index;
uint8_t temporal_id;
@ -114,7 +114,8 @@ class reference_frames_tracker_h264 : public reference_frames_tracker
uint32_t MaxL0References,
uint32_t MaxL1References,
uint32_t MaxDPBCapacity,
uint32_t MaxLongTermReferences );
uint32_t MaxLongTermReferences,
bool bSendUnwrappedPOC );
private:
uint32_t PrepareFrameRefLists( bool useLTR, uint32_t useLTRBitmap );
@ -136,6 +137,8 @@ class reference_frames_tracker_h264 : public reference_frames_tracker
uint32_t m_MaxDPBCapacity = 0;
uint32_t m_MaxLongTermReferences = 0;
bool m_bSendUnwrappedPOC = false;
bool m_bSendMaxLongTermReferences = false;
uint32_t m_ActiveLTRBitmap = 0;

View file

@ -154,7 +154,7 @@ reference_frames_tracker_hevc::begin_frame( reference_frames_tracker_dpb_async_t
}
}
m_ActiveLTRBitmap = useLTRBitmap & 0xFFFF; // synchronize active LTR bitmap with useLTRBitmap
m_ActiveLTRBitmap = useLTRBitmap & 0xFFFF; // synchronize active LTR bitmap with useLTRBitmap
}
ltrUsedBitMask = PrepareFrameRefLists();