From b83a931cb17567e878b1fb135f8f12736b37ca13 Mon Sep 17 00:00:00 2001 From: Silvio Vilerino Date: Tue, 31 Mar 2026 15:35:31 -0400 Subject: [PATCH] d3d12: Video sliced encode: Use same ID3D12Fence/different per slice values as optimization Reviewed-by: Pohsiang (John) Hsu Part-of: --- src/gallium/drivers/d3d12/d3d12_video_enc.cpp | 14 ++++++++++---- src/gallium/drivers/d3d12/d3d12_video_enc.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index eb208685bc4..da32fc36541 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -4102,7 +4102,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionOffsets.resize(num_slice_objects, {}); pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences.resize(num_slice_objects, NULL); pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pSubregionPipeFences.resize(num_slice_objects); - pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFenceValues.resize(num_slice_objects, pD3D12Enc->m_fenceValue); + pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFenceValues.resize(num_slice_objects); + // m_SliceFenceValue is incremented per slice object and shared across all slices of the frame so the app can + // wait on a single fence but individual per frame, slice values + for (uint32_t i = 0; i < num_slice_objects; i++) + pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFenceValues[i] = pD3D12Enc->m_SliceFenceValue++; pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionSizes.resize(num_slice_objects, NULL); pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionOffsets.resize(num_slice_objects, NULL); @@ -4144,9 +4148,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionSizes[i] = pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionSizes[i].Get(); - if (pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[i] == nullptr) - hr = pD3D12Enc->m_pD3D12Screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[i])); - pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFences[i] = pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[i].Get(); + // Share a single ID3D12Fence object across all slices of this frame (per metadata slot) + if (pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[0] == nullptr) + hr = pD3D12Enc->m_pD3D12Screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[0])); + pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[i] = pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[0]; + pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFences[i] = pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[0].Get(); pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pSubregionPipeFences[i].reset( d3d12_create_fence_raw(pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].pspSubregionFences[i].Get(), diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index 4ff338e6b73..80bb097450d 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -588,6 +588,7 @@ struct d3d12_video_encoder ComPtr m_spLastSliceFence; uint64_t m_fenceValue = 1u; uint64_t m_LastSliceFenceValue = 1u; + uint64_t m_SliceFenceValue = 1u; uint64_t m_ResidencyFenceValue = 0u; bool m_bPendingWorkNotFlushed = false;