mediafoundation: Only use sliced mode when CODECAPI_AVEncSliceGenerationMode is set, disregarding num slices configured

Reviewed-by: Pohsiang (John) Hsu <pohhsu@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37982>
This commit is contained in:
Silvio Vilerino 2025-10-20 09:32:54 -04:00 committed by Pohsiang (John) Hsu
parent 71aecf4a93
commit b454c35318
3 changed files with 22 additions and 6 deletions

View file

@ -1824,6 +1824,14 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value )
{
CHECKHR_GOTO(E_INVALIDARG, done);
}
if ((Value->ulVal > 0) && (!m_EncoderCapabilities.m_HWSupportSlicedFences.bits.supported))
{
MFE_ERROR("[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncSliceGenerationMode: %d, but this encoder does NOT support sliced fence generation.",
this, Value->ulVal);
CHECKHR_GOTO(E_INVALIDARG, done);
}
debug_printf("[dx12 hmft 0x%p] SET CODECAPI_AVEncSliceGenerationMode - %u\n", this, Value->ulVal);
m_uiSliceGenerationMode = Value->ulVal;
m_bSliceGenerationModeSet = TRUE;

View file

@ -554,7 +554,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
#endif
pDX12EncodeContext->sliceNotificationMode = D3D12_VIDEO_ENCODER_COMPRESSED_BITSTREAM_NOTIFICATION_MODE_FULL_FRAME;
if( m_EncoderCapabilities.m_HWSupportSlicedFences.bits.supported && ( num_output_buffers > 1 ) )
if( m_bSliceGenerationModeSet && (m_uiSliceGenerationMode > 0) && ( num_output_buffers > 1 ) /* IHV driver requires > 1 slices */ )
{
pDX12EncodeContext->sliceNotificationMode = D3D12_VIDEO_ENCODER_COMPRESSED_BITSTREAM_NOTIFICATION_MODE_SUBREGIONS;
if( m_EncoderCapabilities.m_HWSupportSlicedFences.bits.multiple_buffers_required )

View file

@ -1443,11 +1443,19 @@ CDX12EncHMFT::xThreadProc( void *pCtx )
return result;
};
// If slice generation mode is explicitly set to 1 (1 slice per output sample) and auto mode is off
// emit multiple output samples, one per slice
if (pThis->m_bSliceGenerationModeSet &&
(pThis->m_uiSliceGenerationMode == 1) &&
(!pDX12EncodeContext->IsSliceAutoModeEnabled())) // We cannot know if the last slice is actually the last one on time to set the last MFSample properties
//
// We can assume pLastSliceFence is signaled after the last pSliceFences[slice_idx] is signaled
// but there may still be a race condition there in between these last two signals
//
// If we are using PIPE_SLICE_AUTO_MODE, we need to wait on pLastSliceFence to know when all actual slices are done
// and what pSliceFences[] after that point are unused and must not be waited on.
//
// When emitting the MFSamples asynchronously for each slice, we need to mark MFSample_LastSlice
// on the last actual slice. In auto mode, we only know which one is the last actual slice after pLastSliceFence is signaled
// and by that time, it is too late to mark MFSample_LastSlice on the last slice only (as it may have been already emitted),
// so in PIPE_SLICE_AUTO_MODE, we gather all completed slices here and emit them together after pLastSliceFence is signaled.
//
if (!pDX12EncodeContext->IsSliceAutoModeEnabled())
{
std::vector<struct codec_unit_location_t> codec_unit_metadata;
codec_unit_metadata.reserve( 16 );