i915: Vertical align video encode buffers to macroblock size

Verically align buffers used in video encoding to the size of a
macroblock. This prevents uninitialized data from entering the encoding
pipeline, which causes quality degradations.

BUG=b:274756117 b:277690367
TEST=Tested by running "./video_encode_accelerator_perf_tests
--codec=av1 --bitrate=84120 180p_perf.yuv 180p_perf.json
--gtest_filter=VideoEncoderTest.MeasureProducedBitstreamQuality" on a
Rex. The average PSNR goes from 34.4939dB to 38.6649dB.

Change-Id: I6783f1986869e11b1dd19e949d25c4450229c4c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4615698
Tested-by: Justin Green <greenjustin@google.com>
Commit-Queue: Justin Green <greenjustin@google.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Dominik Behr <dbehr@chromium.org>
This commit is contained in:
Justin Green 2023-06-15 17:18:51 -04:00 committed by Chromeos LUCI
parent b23bfa5a70
commit 670301f61a

10
i915.c
View file

@ -349,7 +349,11 @@ static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling
#else
horizontal_alignment = 64;
#endif
/*
/* For hardware video encoding buffers, we want to align to the size of a
* macroblock, because otherwise we will end up encoding uninitialized data.
* This can result in substantial quality degradations, especially on lower
* resolution videos, because this uninitialized data may be high entropy.
*
* For R8 and height=1, we assume the surface will be used as a linear buffer blob
* (such as VkBuffer). The hardware allows vertical_alignment=1 only for non-tiled
* 1D surfaces, which covers the VkBuffer case. However, if the app uses the surface
@ -361,7 +365,9 @@ static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling
* constraints with GPU_DATA_BUFFER usage when the guest has migrated to use
* virtgpu_cross_domain backend which passes that flag through.
*/
if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
if (bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) {
vertical_alignment = 16;
} else if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
vertical_alignment = 1;
} else {
vertical_alignment = 4;