mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 18:10:11 +01:00
d3d12: Video Encode - Do not flush on direct buffer maps
Reviewed-by: Pohsiang (John) Hsu <pohhsu@microsoft.com> Reviewed-by: Yubo Xie <yuboxie@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38578>
This commit is contained in:
parent
f7c306c654
commit
d9c2ccd543
1 changed files with 32 additions and 13 deletions
|
|
@ -3041,6 +3041,14 @@ d3d12_video_encoder_calculate_max_slices_count_in_output(
|
||||||
return maxSlices;
|
return maxSlices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
d3d12_buffer_maps_directly(pipe_resource *buffer)
|
||||||
|
{
|
||||||
|
return buffer->target == PIPE_BUFFER &&
|
||||||
|
buffer->usage != PIPE_USAGE_DEFAULT &&
|
||||||
|
buffer->usage != PIPE_USAGE_IMMUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
d3d12_video_encoder_get_slice_bitstream_data(struct pipe_video_codec *codec,
|
d3d12_video_encoder_get_slice_bitstream_data(struct pipe_video_codec *codec,
|
||||||
void *feedback,
|
void *feedback,
|
||||||
|
|
@ -3183,7 +3191,8 @@ d3d12_video_encoder_get_slice_bitstream_data(struct pipe_video_codec *codec,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we uploaded new slice headers, flush and wait for the context to upload them
|
// If we uploaded new slice headers, flush and wait for the context to upload them
|
||||||
if (pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pSliceHeaders[slice_idx].size() > 0)
|
if ((pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pSliceHeaders[slice_idx].size() > 0) &&
|
||||||
|
!d3d12_buffer_maps_directly(pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].comp_bit_destinations[slice_idx])) // If the buffer maps directly, the buffer_subdata is synchronous on unmap, no need to flush
|
||||||
{
|
{
|
||||||
struct pipe_fence_handle *pUploadGPUCompletionFence = NULL;
|
struct pipe_fence_handle *pUploadGPUCompletionFence = NULL;
|
||||||
pD3D12Enc->base.context->flush(pD3D12Enc->base.context,
|
pD3D12Enc->base.context->flush(pD3D12Enc->base.context,
|
||||||
|
|
@ -3437,12 +3446,19 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||||
static_cast<unsigned int>(pD3D12Enc->m_BitstreamHeadersBuffer.size()),
|
static_cast<unsigned int>(pD3D12Enc->m_BitstreamHeadersBuffer.size()),
|
||||||
pD3D12Enc->m_BitstreamHeadersBuffer.data());
|
pD3D12Enc->m_BitstreamHeadersBuffer.data());
|
||||||
|
|
||||||
|
if (!d3d12_buffer_maps_directly(&pD3D12Enc->m_pOutputBitstreamBuffers[0/*first slice buffer*/]->base.b)) // If the buffer maps directly, the buffer_subdata is synchronous on unmap, no need to flush
|
||||||
|
{
|
||||||
|
// If the destination buffer doesn't map directly (eg. DEFAULT usage), we need to flush
|
||||||
|
// and set a fence to ensure the upload is finished before EncodeFrame reads from it
|
||||||
|
|
||||||
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_encode_bitstream_impl - Flushing pD3D12Enc->m_BitstreamHeadersBuffer data upload.\n");
|
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_encode_bitstream_impl - Flushing pD3D12Enc->m_BitstreamHeadersBuffer data upload.\n");
|
||||||
pD3D12Enc->base.context->flush(
|
pD3D12Enc->base.context->flush(
|
||||||
pD3D12Enc->base.context,
|
pD3D12Enc->base.context,
|
||||||
&pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].headers_upload_completion_fence,
|
&pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].headers_upload_completion_fence,
|
||||||
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
|
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
|
||||||
|
|
||||||
assert(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].headers_upload_completion_fence);
|
assert(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].headers_upload_completion_fence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -4670,18 +4686,21 @@ d3d12_video_encoder_get_feedback(struct pipe_video_codec *codec,
|
||||||
//
|
//
|
||||||
// Flush copies in batch and wait on this CPU thread for GPU work completion
|
// Flush copies in batch and wait on this CPU thread for GPU work completion
|
||||||
//
|
//
|
||||||
struct pipe_fence_handle *pUploadGPUCompletionFence = NULL;
|
|
||||||
pD3D12Enc->base.context->flush(pD3D12Enc->base.context,
|
if (!d3d12_buffer_maps_directly(pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].comp_bit_destinations[0/*first slice*/])) { // If the buffer maps directly, the buffer_subdata is synchronous on unmap, no need to flush
|
||||||
&pUploadGPUCompletionFence,
|
struct pipe_fence_handle *pUploadGPUCompletionFence = NULL;
|
||||||
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
|
pD3D12Enc->base.context->flush(pD3D12Enc->base.context,
|
||||||
assert(pUploadGPUCompletionFence);
|
&pUploadGPUCompletionFence,
|
||||||
pD3D12Enc->m_pD3D12Screen->base.fence_finish(&pD3D12Enc->m_pD3D12Screen->base,
|
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
|
||||||
NULL,
|
assert(pUploadGPUCompletionFence);
|
||||||
pUploadGPUCompletionFence,
|
pD3D12Enc->m_pD3D12Screen->base.fence_finish(&pD3D12Enc->m_pD3D12Screen->base,
|
||||||
OS_TIMEOUT_INFINITE);
|
NULL,
|
||||||
pD3D12Enc->m_pD3D12Screen->base.fence_reference(&pD3D12Enc->m_pD3D12Screen->base,
|
pUploadGPUCompletionFence,
|
||||||
&pUploadGPUCompletionFence,
|
OS_TIMEOUT_INFINITE);
|
||||||
NULL);
|
pD3D12Enc->m_pD3D12Screen->base.fence_reference(&pD3D12Enc->m_pD3D12Screen->base,
|
||||||
|
&pUploadGPUCompletionFence,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue