From 01a99f5d4d55e302a33d83b41d0ee3af5243d454 Mon Sep 17 00:00:00 2001 From: Sil Vilerino Date: Tue, 30 Jan 2024 12:52:41 -0500 Subject: [PATCH] d3d12: d3d12_video_encoder_negotiate_current_h264_slices_configuration to use correct mode when intra-refresh is on Part-of: --- .../drivers/d3d12/d3d12_video_enc_h264.cpp | 97 ++++++++++++------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp index 0f4a3b3e2b7..390524f2ff6 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp @@ -425,42 +425,67 @@ d3d12_video_encoder_negotiate_current_h264_slices_configuration(struct d3d12_vid pD3D12Enc->m_currentEncodeConfig.m_currentResolution.Width / D3D12_VIDEO_H264_MB_IN_PIXELS; bool bSliceAligned = ((picture->slices_descriptors[0].num_macroblocks % mbPerScanline) == 0); - if (bUniformSizeSlices && bSliceAligned && - d3d12_video_encoder_check_subregion_mode_support( - pD3D12Enc, - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION)) { + if (bUniformSizeSlices) { + if (picture->intra_refresh.mode != INTRA_REFRESH_MODE_NONE) { + /* + * When intra-refresh is active, we must use D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME + */ + if (d3d12_video_encoder_check_subregion_mode_support( + pD3D12Enc, + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME)) { + requestedSlicesMode = + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME; + requestedSlicesConfig.NumberOfSlicesPerFrame = picture->num_slice_descriptors; + debug_printf("[d3d12_video_encoder_h264] Intra-refresh is active and per DX12 spec it requires using multi slice encoding mode: " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME " + "with %d slices per frame.\n", + requestedSlicesConfig.NumberOfSlicesPerFrame); + } else { + debug_printf("[d3d12_video_encoder_h264] Intra-refresh is active which requires " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME " + "mode but there is HW support for such mode.\n"); + return false; + } + } else if (bSliceAligned && + d3d12_video_encoder_check_subregion_mode_support( + pD3D12Enc, + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION)) { - // Number of macroblocks per slice is aligned to a scanline width, in which case we can - // use D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION - requestedSlicesMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION; - requestedSlicesConfig.NumberOfRowsPerSlice = (picture->slices_descriptors[0].num_macroblocks / mbPerScanline); - debug_printf("[d3d12_video_encoder_h264] Using multi slice encoding mode: " - "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION with " - "%d macroblocks rows per slice.\n", - requestedSlicesConfig.NumberOfRowsPerSlice); - } else if (bUniformSizeSlices && - d3d12_video_encoder_check_subregion_mode_support( - pD3D12Enc, - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME)) { - requestedSlicesMode = - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME; - requestedSlicesConfig.NumberOfSlicesPerFrame = picture->num_slice_descriptors; + // Number of macroblocks per slice is aligned to a scanline width, in which case we can + // use D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION + requestedSlicesMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION; + requestedSlicesConfig.NumberOfRowsPerSlice = (picture->slices_descriptors[0].num_macroblocks / mbPerScanline); debug_printf("[d3d12_video_encoder_h264] Using multi slice encoding mode: " - "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME " - "with %d slices per frame.\n", - requestedSlicesConfig.NumberOfSlicesPerFrame); - } else if (bUniformSizeSlices && - d3d12_video_encoder_check_subregion_mode_support( - pD3D12Enc, - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED)) { - requestedSlicesMode = - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED; - requestedSlicesConfig.NumberOfCodingUnitsPerSlice = picture->slices_descriptors[0].num_macroblocks; - debug_printf("[d3d12_video_encoder_h264] Using multi slice encoding mode: " - "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED " - "with %d NumberOfCodingUnitsPerSlice per frame.\n", - requestedSlicesConfig.NumberOfCodingUnitsPerSlice); - + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION with " + "%d macroblocks rows per slice.\n", + requestedSlicesConfig.NumberOfRowsPerSlice); + } else if (d3d12_video_encoder_check_subregion_mode_support( + pD3D12Enc, + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME)) { + requestedSlicesMode = + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME; + requestedSlicesConfig.NumberOfSlicesPerFrame = picture->num_slice_descriptors; + debug_printf("[d3d12_video_encoder_h264] Using multi slice encoding mode: " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME " + "with %d slices per frame.\n", + requestedSlicesConfig.NumberOfSlicesPerFrame); + } else if (d3d12_video_encoder_check_subregion_mode_support( + pD3D12Enc, + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED)) { + requestedSlicesMode = + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED; + requestedSlicesConfig.NumberOfCodingUnitsPerSlice = picture->slices_descriptors[0].num_macroblocks; + debug_printf("[d3d12_video_encoder_h264] Using multi slice encoding mode: " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED " + "with %d NumberOfCodingUnitsPerSlice per frame.\n", + requestedSlicesConfig.NumberOfCodingUnitsPerSlice); + } else { + debug_printf("[d3d12_video_encoder_h264] Requested slice control mode is not supported by hardware: No HW support for " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION or" + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME or" + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED.\n"); + return false; + } } else { debug_printf("[d3d12_video_encoder_h264] Requested slice control mode is not supported: All slices must " "have the same number of macroblocks.\n"); @@ -479,8 +504,8 @@ d3d12_video_encoder_negotiate_current_h264_slices_configuration(struct d3d12_vid "with %d MaxBytesPerSlice per frame.\n", requestedSlicesConfig.MaxBytesPerSlice); } else { - debug_printf("[d3d12_video_encoder_h264] Requested slice control mode is not supported: All slices must " - "have the same number of macroblocks.\n"); + debug_printf("[d3d12_video_encoder_h264] Requested slice control mode is not supported: No HW support for " + "D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_BYTES_PER_SUBREGION.\n"); return false; } } else {