d3d12: Only check HEVC video caps if configuration changed between frames

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-18 10:51:01 -04:00
committed by Pohsiang (John) Hsu
parent e3ab866fea
commit 6f9c49f6f5
@@ -1372,15 +1372,70 @@ d3d12_video_encoder_update_current_encoder_config_state_hevc(struct d3d12_video_
return false;
}
if (!d3d12_video_encoder_negotiate_requested_features_and_d3d12_driver_caps(pD3D12Enc, capEncoderSupportData2)) {
debug_printf("[d3d12_video_encoder_hevc] After negotiating caps, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT2 "
"arguments are not supported - "
"ValidationFlags: 0x%x - SupportFlags: 0x%x\n",
capEncoderSupportData2.ValidationFlags,
capEncoderSupportData2.SupportFlags);
// Set motion estimation config BEFORE caps query
auto targetMotionLimit = d3d12_video_encoder_convert_hevc_motion_configuration(pD3D12Enc, hevcPic);
if (pD3D12Enc->m_currentEncodeConfig.m_encoderMotionPrecisionLimit != targetMotionLimit) {
pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags |=
d3d12_video_encoder_config_dirty_flag_motion_precision_limit;
}
pD3D12Enc->m_currentEncodeConfig.m_encoderMotionPrecisionLimit = targetMotionLimit;
// Set intra-refresh config BEFORE caps query
if(!d3d12_video_encoder_update_intra_refresh_hevc(pD3D12Enc, srcTextureDesc, hevcPic)) {
debug_printf("d3d12_video_encoder_update_intra_refresh_hevc failed!\n");
return false;
}
// Define flags that require re-querying driver capabilities
static const d3d12_video_encoder_config_dirty_flags caps_affecting_flags =
(d3d12_video_encoder_config_dirty_flags)(
d3d12_video_encoder_config_dirty_flag_codec |
d3d12_video_encoder_config_dirty_flag_profile |
d3d12_video_encoder_config_dirty_flag_level |
d3d12_video_encoder_config_dirty_flag_codec_config |
d3d12_video_encoder_config_dirty_flag_input_format |
d3d12_video_encoder_config_dirty_flag_resolution |
d3d12_video_encoder_config_dirty_flag_slices |
d3d12_video_encoder_config_dirty_flag_gop |
d3d12_video_encoder_config_dirty_flag_motion_precision_limit |
d3d12_video_encoder_config_dirty_flag_intra_refresh
);
// Calculate effective dirty flags including configuration changes not tracked by dirty flags
// as there are set in d3d12_video_enc.cpp later in the encoding process
d3d12_video_encoder_config_dirty_flags effective_dirty_flags = pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags;
if (!pD3D12Enc->m_prevFrameEncodeConfig.m_encoderRateControlDesc[pD3D12Enc->m_currentEncodeConfig.m_activeRateControlIndex]
.CompareEqual(pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[pD3D12Enc->m_currentEncodeConfig.m_activeRateControlIndex])) {
effective_dirty_flags |= d3d12_video_encoder_config_dirty_flag_rate_control;
}
if (memcmp(&pD3D12Enc->m_prevFrameEncodeConfig.m_DirtyRectsDesc,
&pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc,
sizeof(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc)) != 0) {
effective_dirty_flags |= d3d12_video_encoder_config_dirty_flag_dirty_regions;
}
// Only query driver caps if configuration parameters that affect capabilities have changed
if ((effective_dirty_flags & (caps_affecting_flags | d3d12_video_encoder_config_dirty_flag_rate_control | d3d12_video_encoder_config_dirty_flag_dirty_regions)) != 0) {
debug_printf("[d3d12_video_encoder_hevc] Configuration changed - performing CheckFeatureSupport driver capability query (fenceValue: %" PRIu64 ", effectiveDirtyFlags: 0x%x)\n",
pD3D12Enc->m_fenceValue,
effective_dirty_flags);
if (!d3d12_video_encoder_negotiate_requested_features_and_d3d12_driver_caps(pD3D12Enc, capEncoderSupportData2)) {
debug_printf("[d3d12_video_encoder_hevc] After negotiating caps, D3D12_FEATURE_VIDEO_ENCODER_SUPPORT2 "
"arguments are not supported - "
"ValidationFlags: 0x%x - SupportFlags: 0x%x\n",
capEncoderSupportData2.ValidationFlags,
capEncoderSupportData2.SupportFlags);
return false;
}
} else {
debug_printf("[d3d12_video_encoder_hevc] No configuration changes detected - skipping expensive driver query and reusing cached capabilities (fenceValue: %" PRIu64 ")\n", pD3D12Enc->m_fenceValue);
// Copy capabilities from previous frame to avoid expensive driver query
capEncoderSupportData2.SupportFlags = pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags;
capEncoderSupportData2.ValidationFlags = pD3D12Enc->m_currentEncodeCapabilities.m_ValidationFlags;
// Note: m_currentResolutionSupportCaps and other capability data remain valid from previous query
}
///
// Calculate current settings based on the returned values from the caps query
//
@@ -1392,23 +1447,9 @@ d3d12_video_encoder_update_current_encoder_config_state_hevc(struct d3d12_video_
pD3D12Enc->m_currentEncodeConfig.m_currentResolution,
pD3D12Enc->m_currentEncodeCapabilities.m_currentResolutionSupportCaps.SubregionBlockPixelsSize);
// Set intra-refresh config
if(!d3d12_video_encoder_update_intra_refresh_hevc(pD3D12Enc, srcTextureDesc, hevcPic)) {
debug_printf("d3d12_video_encoder_update_intra_refresh_hevc failed!\n");
return false;
}
// m_currentEncodeConfig.m_encoderPicParamsDesc pic params are set in d3d12_video_encoder_reconfigure_encoder_objects
// after re-allocating objects if needed
// Set motion estimation config
auto targetMotionLimit = d3d12_video_encoder_convert_hevc_motion_configuration(pD3D12Enc, hevcPic);
if (pD3D12Enc->m_currentEncodeConfig.m_encoderMotionPrecisionLimit != targetMotionLimit) {
pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags |=
d3d12_video_encoder_config_dirty_flag_motion_precision_limit;
}
pD3D12Enc->m_currentEncodeConfig.m_encoderMotionPrecisionLimit = targetMotionLimit;
//
// Validate caps support returned values against current settings
//