From 53e07e78c7cbc0c12e3773eb29ac053713e61e83 Mon Sep 17 00:00:00 2001 From: Silvio Vilerino Date: Sat, 18 Oct 2025 10:01:31 -0400 Subject: [PATCH] d3d12: Cache ID3D12VideoEncodeCommandList4 instance if supported Reviewed-by: Pohsiang (John) Hsu Part-of: --- src/gallium/drivers/d3d12/d3d12_video_enc.cpp | 59 ++++++++++--------- src/gallium/drivers/d3d12/d3d12_video_enc.h | 2 + .../drivers/d3d12/d3d12_video_enc_hevc.cpp | 8 +-- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index f35f0116fdf..513c56c32a6 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -2441,6 +2441,9 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } + // Cache ID3D12VideoEncodeCommandList4 interface for EncodeFrame1 optimization + pD3D12Enc->m_spEncodeCommandList->QueryInterface(IID_PPV_ARGS(pD3D12Enc->m_spEncodeCommandList4.GetAddressOf())); + hr = spD3D12Device4->CreateCommandList1(0, D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, D3D12_COMMAND_LIST_FLAG_NONE, @@ -2453,6 +2456,9 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } + // Cache ID3D12VideoEncodeCommandList4 interface for ResolveEncoderOutputMetadata1 optimization + pD3D12Enc->m_spResolveCommandList->QueryInterface(IID_PPV_ARGS(pD3D12Enc->m_spResolveCommandList4.GetAddressOf())); + return true; } @@ -3592,12 +3598,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, } #endif - ComPtr spEncodeCommandList4; - ComPtr spResolveCommandList4; - if ((SUCCEEDED(pD3D12Enc->m_spEncodeCommandList->QueryInterface( - IID_PPV_ARGS(spEncodeCommandList4.GetAddressOf())))) && - (SUCCEEDED(pD3D12Enc->m_spResolveCommandList->QueryInterface( - IID_PPV_ARGS(spResolveCommandList4.GetAddressOf()))))) { + // Use cached ID3D12VideoEncodeCommandList4 interfaces if available + if (pD3D12Enc->m_spEncodeCommandList4 && pD3D12Enc->m_spResolveCommandList4) { // Update current frame pic params state after reconfiguring above. D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA1 currentPicParams = @@ -3645,7 +3647,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, } // see below std::warp for reversal to common after ResolveInputParamLayout is done - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); D3D12_VIDEO_ENCODER_INPUT_MAP_DATA ResolveInputData = {}; ResolveInputData.MapType = D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE_DIRTY_REGIONS; @@ -3663,11 +3665,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, dirtyRegions.pOpaqueLayoutBuffer, }; - spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); + pD3D12Enc->m_spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); for (auto &BarrierDesc : pResolveInputDataBarriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); } } @@ -3690,7 +3692,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ)); // see below std::warp for reversal to common after ResolveInputParamLayout is done - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); D3D12_VIDEO_ENCODER_INPUT_MAP_DATA ResolveInputData = {}; ResolveInputData.MapType = D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE_QUANTIZATION_MATRIX; @@ -3705,11 +3707,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, QuantizationTextureMap.pOpaqueQuantizationMap, }; - spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); + pD3D12Enc->m_spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); for (auto &BarrierDesc : pResolveInputDataBarriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); } @@ -3741,7 +3743,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, } // see below std::swap for reversal to common after ResolveInputParamLayout is done - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); D3D12_VIDEO_ENCODER_INPUT_MAP_DATA ResolveInputData = {}; ResolveInputData.MapType = D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE_MOTION_VECTORS; @@ -3764,11 +3766,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, motionRegions.pOpaqueLayoutBuffer, }; - spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); + pD3D12Enc->m_spEncodeCommandList4->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput); for (auto &BarrierDesc : pResolveInputDataBarriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pResolveInputDataBarriers.size()), pResolveInputDataBarriers.data()); } } @@ -3904,7 +3906,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, }; } - spEncodeCommandList4->ResourceBarrier(static_cast(pTwoPassExtraBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pTwoPassExtraBarriers.size()), pTwoPassExtraBarriers.data()); } @@ -4089,7 +4091,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].ppSubregionFenceValues.data() }; - spEncodeCommandList4->ResourceBarrier(static_cast(pSlicedEncodingExtraBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pSlicedEncodingExtraBarriers.size()), pSlicedEncodingExtraBarriers.data()); } @@ -4128,8 +4130,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, // Record EncodeFrame - use cached ID3D12VideoEncoderHeap1 interface - // If spEncodeCommandList4 QI succeeded, ID3D12VideoEncoderHeap1 should be available - spEncodeCommandList4->EncodeFrame1(pD3D12Enc->m_spVideoEncoder.Get(), + // If cached CommandList4 interfaces are available, ID3D12VideoEncoderHeap1 should be available + pD3D12Enc->m_spEncodeCommandList4->EncodeFrame1(pD3D12Enc->m_spVideoEncoder.Get(), pD3D12Enc->m_spVideoEncoderHeap1.Get(), &inputStreamArguments, &outputStreamArguments); @@ -4154,7 +4156,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_COMMON)); } - spResolveCommandList4->ResourceBarrier(static_cast(rgResolveMetadataStateTransitions.size()), + pD3D12Enc->m_spResolveCommandList4->ResourceBarrier(static_cast(rgResolveMetadataStateTransitions.size()), rgResolveMetadataStateTransitions.data()); std::vector output_stats_barriers; @@ -4182,7 +4184,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE)); } - spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), + pD3D12Enc->m_spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), output_stats_barriers.data()); const D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS1 inputMetadataCmd = { pD3D12Enc->m_currentEncodeConfig.m_encoderCodecDesc, @@ -4217,7 +4219,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, {}, }; - spResolveCommandList4->ResolveEncoderOutputMetadata1(&inputMetadataCmd, &outputMetadataCmd); + pD3D12Enc->m_spResolveCommandList4->ResolveEncoderOutputMetadata1(&inputMetadataCmd, &outputMetadataCmd); debug_printf("[d3d12_video_encoder_encode_bitstream] EncodeFrame slot %" PRIu64 " encoder %p encoderheap %p input tex %p output bitstream %p raw metadata buf %p resolved metadata buf %p Command allocator %p\n", static_cast(d3d12_video_encoder_pool_current_index(pD3D12Enc)), @@ -4237,7 +4239,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, } if (rgReferenceTransitions.size() > 0) { - spEncodeCommandList4->ResourceBarrier(static_cast(rgReferenceTransitions.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(rgReferenceTransitions.size()), rgReferenceTransitions.data()); } } @@ -4251,26 +4253,25 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_COMMON), }; - spResolveCommandList4->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), + pD3D12Enc->m_spResolveCommandList4->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), rgRevertResolveMetadataStateTransitions); // Revert output_stats_barriers for (auto &BarrierDesc : output_stats_barriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), - output_stats_barriers.data()); - + pD3D12Enc->m_spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), + output_stats_barriers.data()); for (auto &BarrierDesc : pSlicedEncodingExtraBarriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(pSlicedEncodingExtraBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pSlicedEncodingExtraBarriers.size()), pSlicedEncodingExtraBarriers.data()); for (auto &BarrierDesc : pTwoPassExtraBarriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(pTwoPassExtraBarriers.size()), + pD3D12Enc->m_spEncodeCommandList4->ResourceBarrier(static_cast(pTwoPassExtraBarriers.size()), pTwoPassExtraBarriers.data()); } else diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index 9e8957e874e..e78efd630c4 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -595,6 +595,8 @@ struct d3d12_video_encoder ComPtr m_spResolveCommandQueue; ComPtr m_spEncodeCommandList; ComPtr m_spResolveCommandList; + ComPtr m_spEncodeCommandList4; + ComPtr m_spResolveCommandList4; std::vector m_transitionsBeforeCloseCmdList; std::unique_ptr m_upDPBManager; diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp index 6a1b283377f..ae4723c400e 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp @@ -554,9 +554,7 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video // differently on the newer interfaces that support it // Otherwise fallback to the legacy behavior using List0ReferenceFramesCount // equal to num_ref_idx_l0_active_minus1 + 1 - ComPtr spEncodeCommandList4; - if (SUCCEEDED(pD3D12Enc->m_spEncodeCommandList->QueryInterface( - IID_PPV_ARGS(spEncodeCommandList4.GetAddressOf())))) + if (pD3D12Enc->m_spEncodeCommandList4) { pHEVCPicData->num_ref_idx_l0_active_minus1 = hevcPic->num_ref_idx_l0_active_minus1; pHEVCPicData->List0ReferenceFramesCount = ref_list0_count; @@ -571,9 +569,7 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video // differently on the newer interfaces that support it // Otherwise fallback to the legacy behavior using List1ReferenceFramesCount // equal to num_ref_idx_l1_active_minus1 + 1 - ComPtr spEncodeCommandList4; - if (SUCCEEDED(pD3D12Enc->m_spEncodeCommandList->QueryInterface( - IID_PPV_ARGS(spEncodeCommandList4.GetAddressOf())))) + if (pD3D12Enc->m_spEncodeCommandList4) { pHEVCPicData->num_ref_idx_l1_active_minus1 = hevcPic->num_ref_idx_l1_active_minus1; pHEVCPicData->List1ReferenceFramesCount = ref_list1_count;