minigbm: msm: Add platform specific alignment for NV12 linear format
Venus driver requires extra padding for NV12 buffers.
BUG=b:120118851
TEST=plane_test -f NV12
TEST=plane_test -f NV12 -z 640x480
Change-Id: If86c548350278cc8d87159b58e56802b2598d448
Signed-off-by: Tanmay Shah <tanmay@codeaurora.org>
Reviewed-on: https://chromium-review.googlesource.com/1362202
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
diff --git a/msm.c b/msm.c
index 8060cea..6bb70b6 100644
--- a/msm.c
+++ b/msm.c
@@ -18,6 +18,11 @@
#include "util.h"
#define DEFAULT_ALIGNMENT 64
+#define BUFFER_SIZE_ALIGN 4096
+
+#define VENUS_STRIDE_ALIGN 128
+#define VENUS_SCANLINE_ALIGN 16
+#define NV12_LINEAR_PADDING (12 * 1024)
static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
@@ -26,6 +31,51 @@
static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8,
DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
+static void msm_calculate_linear_layout(struct bo *bo)
+{
+ uint32_t width, height;
+
+ width = bo->width;
+ height = bo->height;
+
+ /* NV12 format requires extra padding with platform
+ * specific alignments for venus driver
+ */
+ if (bo->format == DRM_FORMAT_NV12) {
+ uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size;
+ y_stride = ALIGN(width, VENUS_STRIDE_ALIGN);
+ uv_stride = ALIGN(width, VENUS_STRIDE_ALIGN);
+ y_scanline = ALIGN(height, VENUS_SCANLINE_ALIGN * 2);
+ uv_scanline = ALIGN(DIV_ROUND_UP(height, 2), VENUS_SCANLINE_ALIGN);
+ y_plane = y_stride * y_scanline;
+ uv_plane = uv_stride * uv_scanline;
+
+ bo->strides[0] = y_stride;
+ bo->sizes[0] = y_plane;
+ bo->offsets[1] = y_plane;
+ bo->strides[1] = uv_stride;
+ size = y_plane + uv_plane + NV12_LINEAR_PADDING;
+ bo->total_size = ALIGN(size, BUFFER_SIZE_ALIGN);
+ bo->sizes[1] = bo->total_size - bo->sizes[0];
+ } else {
+ uint32_t stride, alignw, alignh;
+
+ alignw = ALIGN(width, DEFAULT_ALIGNMENT);
+
+ /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */
+ if (bo->format == DRM_FORMAT_YVU420_ANDROID) {
+ alignh = height;
+ } else {
+ alignh = ALIGN(height, DEFAULT_ALIGNMENT);
+ }
+
+ stride = drv_stride_from_format(bo->format, alignw, 0);
+
+ /* Calculate size and assign stride, size, offset to each plane based on format */
+ drv_bo_from_format(bo, stride, alignh, bo->format);
+ }
+}
+
static int msm_init(struct driver *drv)
{
drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
@@ -45,30 +95,10 @@
uint64_t flags)
{
struct drm_msm_gem_new req;
- uint32_t stride, alignw, alignh;
int ret;
size_t i;
- /* will get alignment from libadreno eventually */
- alignw = ALIGN(width, DEFAULT_ALIGNMENT);
- alignh = ALIGN(height, DEFAULT_ALIGNMENT);
-
- /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */
- if (bo->format == DRM_FORMAT_YVU420_ANDROID)
- alignh = bo->height;
-
- /*
- * The extra 12KB at the end are a requirement of the Venus codec driver.
- * Since |height| will be multiplied by 3/2 in drv_dumb_bo_create,
- * we multiply this padding by 2/3 here.
- */
- if (bo->format == DRM_FORMAT_NV12)
- alignh += 2 * DIV_ROUND_UP(0x3000, 3 * alignw);
-
- stride = drv_stride_from_format(format, alignw, 0);
-
- /* Calculate size and assign stride, size, offset to each plane based on format */
- drv_bo_from_format(bo, stride, alignh, format);
+ msm_calculate_linear_layout(bo);
memset(&req, 0, sizeof(req));
req.flags = MSM_BO_WC | MSM_BO_SCANOUT;