i915: avoid vertical alignment for FORMAT_BLOB
HAL_PIXEL_FORMAT_BLOB gets resolved into DRM_FORMAT_R8 with height of 1.
Avoid doing any vertical alignment for this case. Ideally we want a new
DRM_FORMAT_BLOB format.
BUG=b:255226937
TEST=atest CtsNNAPITestCases:GpuNnapiTest
Change-Id: Iea86481392b40c6c827f84323cb50450ddec03a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4035255
Auto-Submit: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Chad Versace <chadversary@chromium.org>
Tested-by: Yiwei Zhang <zzyiwei@chromium.org>
Commit-Queue: Yiwei Zhang <zzyiwei@chromium.org>
diff --git a/i915.c b/i915.c
index a40f88f..29b1c69 100644
--- a/i915.c
+++ b/i915.c
@@ -316,7 +316,7 @@
return 0;
}
-static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
+static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling, uint32_t *stride,
uint32_t *aligned_height)
{
struct i915_device *i915 = bo->drv->priv;
@@ -342,7 +342,24 @@
#else
horizontal_alignment = 64;
#endif
- vertical_alignment = 4;
+ /*
+ * 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
+ * as a 2D image with height=1, then this code is buggy. For 2D images, the hardware
+ * requires a vertical_alignment >= 4, and underallocating with vertical_alignment=1
+ * will cause the GPU to read out-of-bounds.
+ *
+ * TODO: add a new DRM_FORMAT_BLOB format for this case, or further tighten up the
+ * 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) {
+ vertical_alignment = 1;
+ } else {
+ vertical_alignment = 4;
+ }
+
break;
case I915_TILING_X:
@@ -473,7 +490,7 @@
if (bo->meta.tiling != I915_TILING_NONE)
assert(IS_ALIGNED(offset, pagesize));
- ret = i915_align_dimensions(bo, bo->meta.tiling, &stride, &plane_height);
+ ret = i915_align_dimensions(bo, format, bo->meta.tiling, &stride, &plane_height);
if (ret)
return ret;