i915: Vertical align video encode buffers to macroblock size

This is the reland of crrev.com/c/4615698. It is reverted because it
causes the camera regression (b/289983468). The camera IPU hardware
cannot handle a frame whose Y plane and UV planes are not contiguous.
Aligning the height by 16 makes the space between the planes.
This CL aligns the height by 8. This will not cause the camera
problem today because all the heights of camera stack exposed as
supported are aligned by 8.

BUG=b:274756117, b:289983468
TEST=PSNR 31.946 => 34.012 in video.EncodeAccelPerf.av1_180p_desktop2 on rex

Change-Id: I96907ea372bae6740559a67f71856a89811c7cc8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4739135
Reviewed-by: Chia-I Wu <olv@google.com>
Tested-by: Hirokazu Honda <hiroh@chromium.org>
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
This commit is contained in:
Hirokazu Honda 2023-08-02 13:05:01 +09:00 committed by Chromeos LUCI
parent 30c22dada9
commit 555b38476a

9
i915.c
View file

@ -349,7 +349,12 @@ 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 +366,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 = 8;
} else if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
vertical_alignment = 1;
} else {
vertical_alignment = 4;