OSDN Git Service

minigbm: i915: Add necessary padding to Android YV12 buffers
authorTomasz Figa <tfiga@chromium.org>
Sat, 29 Jul 2017 06:47:54 +0000 (15:47 +0900)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 3 Aug 2017 08:11:02 +0000 (01:11 -0700)
All the regular formats are already aligned by current code, except
Android YV12, which requires height of planes to be unchanged. However
Mesa requires each plane to have at least certain required padding
between planes. Work around this by calculating total BO size with
aligned height to allow padding space to overlap with further planes
and making sure that padding of last plane fits in the buffer. This is
okay, since Mesa requirement seems to indicate that data of the padding
area should not be affected and padding is only needed to satisfy GPU
cache requests.

Fixes following CTS tests on Intel platforms:
android.media.cts.VideoEncoderTest#testGoogH264FlexArbitraryH
android.media.cts.VideoEncoderTest#testGoogH264FlexNearMaxMin
android.media.cts.VideoEncoderTest#testGoogH264SurfArbitraryH
android.media.cts.VideoEncoderTest#testGoogH264SurfNearMaxMin

BUG=b:63957026
TEST=./cts-tradefed run cts -m CtsMediaTestCases -t
 android.media.cts.VideoEncoderTest

Change-Id: I46d44178ba983c0038b630b13b9b281251393f8f
Reviewed-on: https://chromium-review.googlesource.com/592990
Commit-Ready: Tomasz Figa <tfiga@chromium.org>
Tested-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
helpers.c
i915.c

index c6e3527..238563d 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -147,7 +147,7 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height,
         *  - the chroma stride is 16 bytes aligned, i.e., the luma's strides
         *    is 32 bytes aligned.
         */
-       if (bo->format == DRM_FORMAT_YVU420_ANDROID) {
+       if (format == DRM_FORMAT_YVU420_ANDROID) {
                assert(aligned_height == bo->height);
                assert(stride == ALIGN(stride, 32));
        }
diff --git a/i915.c b/i915.c
index 83bd738..f100767 100644 (file)
--- a/i915.c
+++ b/i915.c
@@ -311,12 +311,32 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32
                return ret;
 
        /*
-        * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned.
+        * HAL_PIXEL_FORMAT_YV12 requires the buffer height not be aligned, but we need to keep
+        * total size as with aligned height to ensure enough padding space after each plane to
+        * satisfy GPU alignment requirements.
+        *
+        * We do it by first calling drv_bo_from_format() with aligned height and
+        * DRM_FORMAT_YVU420, which allows height alignment, saving the total size it calculates
+        * and then calling it again with requested parameters.
+        *
+        * This relies on the fact that i965 driver uses separate surfaces for each plane and
+        * contents of padding bytes is not affected, as it is only used to satisfy GPU cache
+        * requests.
+        *
+        * This is enforced by Mesa in src/intel/isl/isl_gen8.c, inside
+        * isl_gen8_choose_image_alignment_el(), which is used for GEN9 and GEN8.
         */
-       if (format == DRM_FORMAT_YVU420_ANDROID)
-               height = bo->height;
-
-       drv_bo_from_format(bo, stride, height, format);
+       if (format == DRM_FORMAT_YVU420_ANDROID) {
+               uint32_t unaligned_height = bo->height;
+               size_t total_size;
+
+               drv_bo_from_format(bo, stride, height, DRM_FORMAT_YVU420);
+               total_size = bo->total_size;
+               drv_bo_from_format(bo, stride, unaligned_height, format);
+               bo->total_size = total_size;
+       } else {
+               drv_bo_from_format(bo, stride, height, format);
+       }
 
        /*
         * Quoting Mesa ISL library: