p_video_codec::encode_bitstream_sliced: Add last_slice_completion_fence for PIPE_VIDEO_SLICE_MODE_AUTO

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Reviewed-by: Pohsiang (John) Hsu <pohhsu@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37936>
This commit is contained in:
Silvio Vilerino
2025-10-17 08:32:54 -04:00
committed by Marge Bot
parent 84dc9af3d4
commit a5af8866df
6 changed files with 34 additions and 3 deletions
@@ -3095,6 +3095,7 @@ d3d12_video_encoder_encode_bitstream_sliced(struct pipe_video_codec *codec,
unsigned num_slice_objects,
struct pipe_resource **slice_destinations,
struct pipe_fence_handle **slice_fences,
struct pipe_fence_handle **last_slice_completion_fence,
void **feedback)
{
struct d3d12_video_encoder *pD3D12Enc = (struct d3d12_video_encoder *) codec;
@@ -3109,6 +3110,7 @@ d3d12_video_encoder_encode_bitstream_sliced(struct pipe_video_codec *codec,
num_slice_objects,
slice_destinations,
slice_fences,
last_slice_completion_fence,
feedback);
}
@@ -3119,11 +3121,13 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
void ** feedback)
{
struct pipe_fence_handle *slice_fences = NULL;
struct pipe_fence_handle *last_slice_completion_fence = NULL;
d3d12_video_encoder_encode_bitstream_impl(codec,
source,
1 /*num_slice_objects*/,
&destination /*slice_destinations*/,
&slice_fences,
&last_slice_completion_fence,
feedback);
}
@@ -3133,6 +3137,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
unsigned num_slice_objects,
struct pipe_resource **slice_destinations,
struct pipe_fence_handle **slice_fences,
[[maybe_unused]] struct pipe_fence_handle **last_slice_completion_fence,
void **feedback)
{
struct d3d12_video_encoder *pD3D12Enc = (struct d3d12_video_encoder *) codec;
@@ -120,6 +120,7 @@ d3d12_video_encoder_encode_bitstream_sliced(struct pipe_video_codec *codec,
unsigned num_slice_objects,
struct pipe_resource **slice_destinations,
struct pipe_fence_handle **slice_fences,
struct pipe_fence_handle **last_slice_completion_fence,
void **feedback);
void
@@ -128,6 +129,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
unsigned num_slice_objects,
struct pipe_resource **slice_destinations,
struct pipe_fence_handle **slice_fences,
struct pipe_fence_handle **last_slice_completion_fence,
void **feedback);
void
@@ -38,6 +38,7 @@ typedef class DX12EncodeContext
struct pipe_fence_handle *pAsyncFence = NULL;
std::vector<struct pipe_resource *> pOutputBitRes;
std::vector<struct pipe_fence_handle *> pSliceFences;
struct pipe_fence_handle * pLastSliceFence;
D3D12_VIDEO_ENCODER_COMPRESSED_BITSTREAM_NOTIFICATION_MODE sliceNotificationMode =
D3D12_VIDEO_ENCODER_COMPRESSED_BITSTREAM_NOTIFICATION_MODE_FULL_FRAME;
pipe_resource *pPipeResourceQPMapStats = nullptr;
@@ -574,6 +574,7 @@ CDX12EncHMFT::PrepareForEncode( IMFSample *pSample, LPDX12EncodeContext *ppDX12E
pDX12EncodeContext->pOutputBitRes.resize( num_output_buffers, NULL );
pDX12EncodeContext->pSliceFences.resize( num_output_buffers, NULL );
pDX12EncodeContext->pLastSliceFence = NULL;
for( uint32_t slice_idx = 0; slice_idx < num_output_buffers; slice_idx++ )
{
if( ( slice_idx > 0 ) && !m_EncoderCapabilities.m_HWSupportSlicedFences.bits.multiple_buffers_required )
@@ -1211,7 +1211,6 @@ CDX12EncHMFT::xThreadProc( void *pCtx )
pDX12EncodeContext->pSliceFences[slice_idx],
OS_TIMEOUT_INFINITE ) != 0;
assert( fenceWaitResult );
pThis->m_pPipeVideoCodec->destroy_fence( pThis->m_pPipeVideoCodec, pDX12EncodeContext->pSliceFences[slice_idx] );
if( fenceWaitResult )
{
unsigned codec_unit_metadata_count = 0u;
@@ -1261,6 +1260,18 @@ CDX12EncHMFT::xThreadProc( void *pCtx )
}
}
// Cleanup fences
for (unsigned slice_idx = 0; slice_idx < pDX12EncodeContext->pSliceFences.size(); slice_idx++)
{
if (pDX12EncodeContext->pSliceFences[slice_idx])
pThis->m_pPipeVideoCodec->destroy_fence( pThis->m_pPipeVideoCodec, pDX12EncodeContext->pSliceFences[slice_idx] );
}
if (pDX12EncodeContext->pLastSliceFence)
{
pThis->m_pPipeVideoCodec->destroy_fence( pThis->m_pPipeVideoCodec, pDX12EncodeContext->pLastSliceFence );
pDX12EncodeContext->pLastSliceFence = nullptr;
}
memset( pDX12EncodeContext->pSliceFences.data(),
0,
pDX12EncodeContext->pSliceFences.size() * sizeof( pipe_fence_handle * ) );
@@ -2203,6 +2214,7 @@ CDX12EncHMFT::ProcessInput( DWORD dwInputStreamIndex, IMFSample *pSample, DWORD
static_cast<unsigned>( pDX12EncodeContext->pOutputBitRes.size() ),
pDX12EncodeContext->pOutputBitRes.data(),
pDX12EncodeContext->pSliceFences.data(), // driver outputs the fences
&pDX12EncodeContext->pLastSliceFence, // driver outputs the last slice fence
&pDX12EncodeContext->pAsyncCookie );
}
else
+12 -2
View File
@@ -105,13 +105,22 @@ struct pipe_video_codec
*
* num_slice_objects indicates the number of elements in the input
* array slice_destinations and indicates the number of outputs expected
* in slice_fences
* in slice_fences. For PIPE_VIDEO_SLICE_MODE_AUTO where slice count is
* unknown, num_slice_objects must be PIPE_VIDEO_CAP_ENC_MAX_SLICES_PER_FRAME
*
* The frame NALs are attached to the first slice buffer
* Any packed slice header (e.g SVC NAL prefix) is attached to each slice buffer
*
* get_feedback information/stats is still only available after full frame
* completion is signaled (e.g pipe_picture_desc::fence)
* completion is signaled (e.g pipe_picture_desc::out_fence)
*
* last_slice_completion_fence signals when all slices complete, which may happen
* before pipe_picture_desc::out_fence signals, given that includes all GPU work
* submitted for the frame including get_feedback information/stats processing.
* For PIPE_VIDEO_SLICE_MODE_AUTO where num_slice_objects is equal to the
* PIPE_VIDEO_CAP_ENC_MAX_SLICES_PER_FRAME, this fence tells the frontend
* when to stop waiting for slice_fences[] without needing to wait for
* full frame completion.
*
* Driver reports support for this function used with different codecs/profiles
* in PIPE_VIDEO_CAP_ENC_SLICED_NOTIFICATIONS, frontend must check before using it.
@@ -121,6 +130,7 @@ struct pipe_video_codec
unsigned num_slice_objects,
struct pipe_resource **slice_destinations,
struct pipe_fence_handle **slice_fences,
struct pipe_fence_handle **last_slice_completion_fence,
void **feedback);