diff --git a/src/gallium/frontends/mediafoundation/codecapi.cpp b/src/gallium/frontends/mediafoundation/codecapi.cpp index e3c4c379ef8..981969ad7d8 100644 --- a/src/gallium/frontends/mediafoundation/codecapi.cpp +++ b/src/gallium/frontends/mediafoundation/codecapi.cpp @@ -342,7 +342,7 @@ CDX12EncHMFT::IsSupported( const GUID *Api ) *Api == CODECAPI_AVEncVideoSelectLayer || *Api == CODECAPI_AVEncVideoEncodeFrameTypeQP || *Api == CODECAPI_AVEncSliceControlMode || *Api == CODECAPI_AVEncSliceControlSize || *Api == CODECAPI_AVEncVideoMaxNumRefFrame || *Api == CODECAPI_AVEncVideoMeanAbsoluteDifference || - *Api == CODECAPI_AVEncVideoMaxQP || *Api == CODECAPI_AVEncVideoGradualIntraRefresh || *Api == CODECAPI_AVScenarioInfo || + *Api == CODECAPI_AVEncVideoMaxQP || *Api == CODECAPI_AVScenarioInfo || *Api == CODECAPI_AVEncVideoROIEnabled || *Api == CODECAPI_AVEncVideoLTRBufferControl || *Api == CODECAPI_AVEncVideoMarkLTRFrame || *Api == CODECAPI_AVEncVideoUseLTRFrame ) { @@ -350,6 +350,15 @@ CDX12EncHMFT::IsSupported( const GUID *Api ) return hr; } + if( m_EncoderCapabilities.m_HWSupportsIntraRefreshModes != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE) + { + if( *Api == CODECAPI_AVEncVideoGradualIntraRefresh ) + { + hr = S_OK; + return hr; + } + } + if( m_EncoderCapabilities.m_HWSupportDirtyRects.bits.supports_info_type_dirty ) { if( *Api == CODECAPI_AVEncVideoDirtyRectEnabled ) @@ -650,13 +659,19 @@ CDX12EncHMFT::GetParameterValues( const GUID *Api, VARIANT **Values, ULONG *Valu } else if( *Api == CODECAPI_AVEncVideoGradualIntraRefresh ) { - // Our HMFT doesn't support HMFT_INTRA_REFRESH_MODE_PERIODIC - *ValuesCount = 2; - CHECKNULL_GOTO( *Values = (VARIANT *) CoTaskMemAlloc( ( *ValuesCount ) * sizeof( VARIANT ) ), E_OUTOFMEMORY, done ); - ( *Values )[0].vt = VT_UI4; - ( *Values )[0].ulVal = HMFT_INTRA_REFRESH_MODE_NONE; - ( *Values )[1].vt = VT_UI4; - ( *Values )[1].ulVal = HMFT_INTRA_REFRESH_MODE_CONTINUAL; + + *ValuesCount = 0; // Assume no support unless reported by driver's capabilities + + if( m_EncoderCapabilities.m_HWSupportsIntraRefreshModes != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE) + { + // Our HMFT doesn't support HMFT_INTRA_REFRESH_MODE_PERIODIC + *ValuesCount = 2; + CHECKNULL_GOTO( *Values = (VARIANT *) CoTaskMemAlloc( ( *ValuesCount ) * sizeof( VARIANT ) ), E_OUTOFMEMORY, done ); + ( *Values )[0].vt = VT_UI4; + ( *Values )[0].ulVal = HMFT_INTRA_REFRESH_MODE_NONE; + ( *Values )[1].vt = VT_UI4; + ( *Values )[1].ulVal = HMFT_INTRA_REFRESH_MODE_CONTINUAL; + } } else if( *Api == CODECAPI_AVEncVideoLTRBufferControl ) { @@ -1526,11 +1541,38 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value ) } else if( *Api == CODECAPI_AVEncVideoGradualIntraRefresh ) { - debug_printf( "[dx12 hmft 0x%p] SET CODECAPI_AVEncVideoGradualIntraRefresh - %u\n", this, Value->ulVal ); - if( Value->vt != VT_UI4 || ( ( Value->ulVal & 0xFFFF ) >= HMFT_INTRA_REFRESH_MODE_MAX ) ) + UINT uiIntraRefreshMode = Value->ulVal & 0xFFFF; + UINT uiIntraRefreshSize = Value->ulVal >> 16 & 0xFFFF; + + if ((uiIntraRefreshMode != 0) && (m_EncoderCapabilities.m_HWSupportsIntraRefreshModes == PIPE_VIDEO_ENC_INTRA_REFRESH_NONE)) { + debug_printf( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoGradualIntraRefresh with mode %u, but this " + "encoder does NOT support intra refresh.", + this, uiIntraRefreshMode ); CHECKHR_GOTO( E_INVALIDARG, done ); } + + if (uiIntraRefreshSize > m_EncoderCapabilities.m_uiMaxHWSupportedIntraRefreshSize) + { + debug_printf( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoGradualIntraRefresh with size %u, but this " + "exceeds the maximum supported by hardware %u.", + this, uiIntraRefreshSize, m_EncoderCapabilities.m_uiMaxHWSupportedIntraRefreshSize ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } + + debug_printf( "[dx12 hmft 0x%p] SET CODECAPI_AVEncVideoGradualIntraRefresh - %u\n", this, Value->ulVal ); + if( Value->vt != VT_UI4 ) + { + debug_printf( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoGradualIntraRefresh with invalid vt %u\n", this, Value->vt ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } + + if( uiIntraRefreshMode >= HMFT_INTRA_REFRESH_MODE_MAX ) + { + debug_printf( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoGradualIntraRefresh with invalid mode %u\n", this, uiIntraRefreshMode ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } + m_uiIntraRefreshMode = Value->ulVal & 0xFFFF; m_uiIntraRefreshSize = Value->ulVal >> 16 & 0xFFFF; } diff --git a/src/gallium/frontends/mediafoundation/encode_h264.cpp b/src/gallium/frontends/mediafoundation/encode_h264.cpp index 487b2d2f42b..ddd00a897ee 100644 --- a/src/gallium/frontends/mediafoundation/encode_h264.cpp +++ b/src/gallium/frontends/mediafoundation/encode_h264.cpp @@ -492,7 +492,7 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo { // Use current encoder slice config for when NOT doing an intra-refresh wave intra_refresh_slices_config non_ir_wave_slices_config = {}; - CHECKBOOL_GOTO( m_EncoderCapabilities.m_uiHWSupportsIntraRefreshModes, MF_E_UNEXPECTED, done ); + CHECKBOOL_GOTO( (m_EncoderCapabilities.m_HWSupportsIntraRefreshModes != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE), MF_E_UNEXPECTED, done ); non_ir_wave_slices_config.slice_mode = pPicInfo->slice_mode; non_ir_wave_slices_config.num_slice_descriptors = pPicInfo->num_slice_descriptors; memcpy( non_ir_wave_slices_config.slices_descriptors, diff --git a/src/gallium/frontends/mediafoundation/encode_hevc.cpp b/src/gallium/frontends/mediafoundation/encode_hevc.cpp index 5afcf3d5cac..46f53aef134 100644 --- a/src/gallium/frontends/mediafoundation/encode_hevc.cpp +++ b/src/gallium/frontends/mediafoundation/encode_hevc.cpp @@ -472,7 +472,7 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo { // Use current encoder slice config for when NOT doing an intra-refresh wave intra_refresh_slices_config non_ir_wave_slices_config = {}; - CHECKBOOL_GOTO( m_EncoderCapabilities.m_uiHWSupportsIntraRefreshModes, MF_E_UNEXPECTED, done ); + CHECKBOOL_GOTO( (m_EncoderCapabilities.m_HWSupportsIntraRefreshModes != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE), MF_E_UNEXPECTED, done ); non_ir_wave_slices_config.slice_mode = pPicInfo->slice_mode; non_ir_wave_slices_config.num_slice_descriptors = pPicInfo->num_slice_descriptors; memcpy( non_ir_wave_slices_config.slices_descriptors, diff --git a/src/gallium/frontends/mediafoundation/encoder_capabilities.cpp b/src/gallium/frontends/mediafoundation/encoder_capabilities.cpp index 90d346f8386..acd9dea2138 100644 --- a/src/gallium/frontends/mediafoundation/encoder_capabilities.cpp +++ b/src/gallium/frontends/mediafoundation/encoder_capabilities.cpp @@ -68,8 +68,11 @@ encoder_capabilities::initialize( pipe_screen *pScreen, pipe_video_profile video ( pScreen->get_video_param( pScreen, videoProfile, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_RATE_CONTROL_QVBR ) == 1 ); - m_uiHWSupportsIntraRefreshModes = - pScreen->get_video_param( pScreen, videoProfile, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_INTRA_REFRESH ); + m_HWSupportsIntraRefreshModes = + (enum pipe_video_enc_intra_refresh_mode) pScreen->get_video_param( pScreen, + videoProfile, + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_INTRA_REFRESH ); m_HWSupportedMetadataFlags = (enum pipe_video_feedback_metadata_type) pScreen->get_video_param( pScreen, @@ -83,7 +86,7 @@ encoder_capabilities::initialize( pipe_screen *pScreen, pipe_video_profile video PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_H264_DISABLE_DBK_FILTER_MODES_SUPPORTED ); - if( m_uiHWSupportsIntraRefreshModes ) + if( m_HWSupportsIntraRefreshModes ) { m_uiMaxHWSupportedIntraRefreshSize = pScreen->get_video_param( pScreen, videoProfile, diff --git a/src/gallium/frontends/mediafoundation/encoder_capabilities.h b/src/gallium/frontends/mediafoundation/encoder_capabilities.h index 9f33018cc4e..9c3fb65aaf4 100644 --- a/src/gallium/frontends/mediafoundation/encoder_capabilities.h +++ b/src/gallium/frontends/mediafoundation/encoder_capabilities.h @@ -75,7 +75,7 @@ class encoder_capabilities BOOL m_bHWSupportsQualityVBRRateControlMode = FALSE; // PIPE_VIDEO_CAP_ENC_INTRA_REFRESH - BOOL m_uiHWSupportsIntraRefreshModes = FALSE; + enum pipe_video_enc_intra_refresh_mode m_HWSupportsIntraRefreshModes = PIPE_VIDEO_ENC_INTRA_REFRESH_NONE; // PIPE_VIDEO_CAP_ENC_SUPPORTS_FEEDBACK_METADATA enum pipe_video_feedback_metadata_type m_HWSupportedMetadataFlags = PIPE_VIDEO_FEEDBACK_METADATA_TYPE_BITSTREAM_SIZE;