panfrost: Properly align stride
authorDaniel Stone <daniels@collabora.com>
Mon, 18 Mar 2019 16:07:00 +0000 (16:07 +0000)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Wed, 20 Mar 2019 04:20:42 +0000 (04:20 +0000)
Handle buffers whose width is not aligned to 16px by padding the stride
and storing it accordingly.

This does not reject imports for images whose stride is not sufficiently
aligned.

v2: make sure bo->stride is set on imported buffers, and add missing
variable definition. (Tomeu)

Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_drm.c
src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_resource.h
src/gallium/drivers/panfrost/pan_screen.h
src/gallium/drivers/panfrost/pan_sfbd.c

index 10eb6795bae9711195bb334a2966c77ae67aed1e..19cdb6c0444b198c8921e1189a9ee769c2ec79a8 100644 (file)
@@ -70,7 +70,7 @@ panfrost_enable_afbc(struct panfrost_context *ctx, struct panfrost_resource *rsr
         int tile_w = (rsrc->base.width0 + (MALI_TILE_LENGTH - 1)) >> MALI_TILE_SHIFT;
         int tile_h = (rsrc->base.height0 + (MALI_TILE_LENGTH - 1)) >> MALI_TILE_SHIFT;
         int bytes_per_pixel = util_format_get_blocksize(rsrc->base.format);
-        int stride = bytes_per_pixel * rsrc->base.width0; /* TODO: Alignment? */
+        int stride = bytes_per_pixel * ALIGN(rsrc->base.width0, 16);
 
         stride *= 2;  /* TODO: Should this be carried over? */
         int main_size = stride * rsrc->base.height0;
index 71e8c6ac1f9d7b7da07c194532f5aa6d341bad3f..bc2007e6cce5e1c15a3710e936af4f0cc7bc969a 100644 (file)
@@ -162,7 +162,7 @@ panfrost_drm_import_bo(struct panfrost_screen *screen, struct winsys_handle *wha
 }
 
 static int
-panfrost_drm_export_bo(struct panfrost_screen *screen, int gem_handle, struct winsys_handle *whandle)
+panfrost_drm_export_bo(struct panfrost_screen *screen, int gem_handle, unsigned int stride, struct winsys_handle *whandle)
 {
        struct panfrost_drm *drm = (struct panfrost_drm *)screen->driver;
         struct drm_prime_handle args = {
@@ -175,6 +175,7 @@ panfrost_drm_export_bo(struct panfrost_screen *screen, int gem_handle, struct wi
                 return FALSE;
 
         whandle->handle = args.fd;
+        whandle->stride = stride;
 
         return TRUE;
 }
index ac7f9ed665f0dd4eb5fca6aef747dce033441ccd..6a7cd596744eaec63f9583a4f98123f6307671e1 100644 (file)
@@ -81,9 +81,7 @@ panfrost_mfbd_set_cbuf(
                 bool flip_y)
 {
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
-
-        signed stride =
-                util_format_get_stride(surf->format, surf->texture->width0);
+        int stride = rsrc->bo->stride;
 
         rt->format = panfrost_mfbd_format(surf);
 
@@ -148,8 +146,7 @@ panfrost_mfbd_set_zsbuf(
                 fbx->flags |= MALI_EXTRA_PRESENT | MALI_EXTRA_ZS | 0x1;
 
                 fbx->ds_linear.depth = rsrc->bo->gpu[0];
-                fbx->ds_linear.depth_stride =
-                        util_format_get_stride(surf->format, surf->texture->width0);
+                fbx->ds_linear.depth_stride = rsrc->bo->stride;
         } else {
                 assert(0);
         }
@@ -273,12 +270,10 @@ panfrost_mfbd_fragment(struct panfrost_context *ctx, bool flip_y)
                 struct panfrost_resource *rsrc = (struct panfrost_resource *) ctx->pipe_framebuffer.cbufs[0]->texture;
 
                 if (rsrc->bo->has_checksum) {
-                        int stride = util_format_get_stride(rsrc->base.format, rsrc->base.width0);
-
                         fb.unk3 |= MALI_MFBD_EXTRA;
                         fbx.flags |= MALI_EXTRA_PRESENT;
                         fbx.checksum_stride = rsrc->bo->checksum_stride;
-                        fbx.checksum = rsrc->bo->gpu[0] + stride * rsrc->base.height0;
+                        fbx.checksum = rsrc->bo->gpu[0] + rsrc->bo->stride * rsrc->base.height0;
                 }
         }
 
index 9e83c9bcb513bd1a372c3ad1ea79f11e4fb679f2..6fe871594ea0cf3cc9dc26cb4154b602f7a03978 100644 (file)
@@ -68,6 +68,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
         prsc->screen = pscreen;
 
        rsc->bo = screen->driver->import_bo(screen, whandle);
+       rsc->bo->stride = whandle->stride;
 
        if (screen->ro) {
                rsc->scanout =
@@ -88,10 +89,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
         struct panfrost_screen *screen = pan_screen(pscreen);
         struct panfrost_resource *rsrc = (struct panfrost_resource *) pt;
         struct renderonly_scanout *scanout = rsrc->scanout;
-        int bytes_per_pixel = util_format_get_blocksize(rsrc->base.format);
-        int stride = bytes_per_pixel * rsrc->base.width0; /* TODO: Alignment? */
 
-        handle->stride = stride;
         handle->modifier = DRM_FORMAT_MOD_INVALID;
 
        if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
@@ -101,6 +99,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
                        return TRUE;
 
                handle->handle = rsrc->bo->gem_handle;
+               handle->stride = rsrc->bo->stride;
                return TRUE;
        } else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
                 if (scanout) {
@@ -113,11 +112,12 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
                         if (ret == -1)
                                 return FALSE;
 
+                        handle->stride = scanout->stride;
                         handle->handle = args.fd;
 
                         return TRUE;
                 } else
-                       return screen->driver->export_bo(screen, rsrc->bo->gem_handle, handle);
+                       return screen->driver->export_bo(screen, rsrc->bo->gem_handle, rsrc->bo->stride, handle);
        }
 
        return FALSE;
@@ -191,7 +191,7 @@ panfrost_create_bo(struct panfrost_screen *screen, const struct pipe_resource *t
         /* Calculate the size of the bo */
 
         int bytes_per_pixel = util_format_get_blocksize(template->format);
-        int stride = bytes_per_pixel * template->width0; /* TODO: Alignment? */
+        int stride = ALIGN(template->width0, 16) * bytes_per_pixel;
         size_t sz = stride;
 
         if (template->height0) sz *= template->height0;
@@ -252,6 +252,8 @@ panfrost_create_bo(struct panfrost_screen *screen, const struct pipe_resource *t
                 /* TODO: Mipmap */
         }
 
+        bo->stride = stride;
+
         return bo;
 }
 
@@ -287,8 +289,6 @@ panfrost_resource_create(struct pipe_screen *screen,
                 struct renderonly_scanout *scanout;
                 struct winsys_handle handle;
 
-                /* TODO: align width0 and height0? */
-
                 scanout = renderonly_scanout_for_resource(&scanout_templat,
                                                           pscreen->ro, &handle);
                 if (!scanout)
@@ -403,14 +403,14 @@ panfrost_transfer_map(struct pipe_context *pctx,
 {
         struct panfrost_context *ctx = pan_context(pctx);
         int bytes_per_pixel = util_format_get_blocksize(resource->format);
-        int stride = bytes_per_pixel * resource->width0; /* TODO: Alignment? */
+        struct panfrost_bo *bo = pan_resource(resource)->bo;
        uint8_t *cpu;
 
         struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
         transfer->level = level;
         transfer->usage = usage;
         transfer->box = *box;
-        transfer->stride = stride;
+        transfer->stride = bo->stride;
         assert(!transfer->box.z);
 
         pipe_resource_reference(&transfer->resource, resource);
@@ -431,7 +431,7 @@ panfrost_transfer_map(struct pipe_context *pctx,
        if (cpu == NULL)
                return NULL;
 
-        return cpu + transfer->box.x * bytes_per_pixel + transfer->box.y * stride;
+        return cpu + transfer->box.x * bytes_per_pixel + transfer->box.y * bo->stride;
 }
 
 static void
@@ -439,7 +439,6 @@ panfrost_tile_texture(struct panfrost_screen *screen, struct panfrost_resource *
 {
        struct panfrost_bo *bo = (struct panfrost_bo *)rsrc->bo;
         int bytes_per_pixel = util_format_get_blocksize(rsrc->base.format);
-        int stride = bytes_per_pixel * rsrc->base.width0; /* TODO: Alignment? */
 
         int width = rsrc->base.width0 >> level;
         int height = rsrc->base.height0 >> level;
@@ -469,7 +468,7 @@ panfrost_tile_texture(struct panfrost_screen *screen, struct panfrost_resource *
         /* Run actual texture swizzle, writing directly to the mapped
          * GPU chunk we allocated */
 
-        panfrost_texture_swizzle(width, height, bytes_per_pixel, stride, bo->cpu[level], swizzled);
+        panfrost_texture_swizzle(width, height, bytes_per_pixel, bo->stride, bo->cpu[level], swizzled);
 }
 
 static void
index 2e3d72babe6b1ddffae3bfc98b16d9ccfff45da1..4b5b9c49c07c816d287e9a85297e45fbc37d0593 100644 (file)
@@ -81,6 +81,7 @@ struct panfrost_bo {
         int checksum_stride;
 
         int gem_handle;
+        unsigned int stride;
 };
 
 struct panfrost_resource {
index 882611e93e3eee37545d171a441599e822b94339..cbadf8136751cb81002191019e06f1641b605ba3 100644 (file)
@@ -49,7 +49,7 @@ struct panfrost_screen;
 
 struct panfrost_driver {
        struct panfrost_bo * (*import_bo) (struct panfrost_screen *screen, struct winsys_handle *whandle);
-       int (*export_bo) (struct panfrost_screen *screen, int gem_handle, struct winsys_handle *whandle);
+       int (*export_bo) (struct panfrost_screen *screen, int gem_handle, unsigned int stride, struct winsys_handle *whandle);
 
        int (*submit_vs_fs_job) (struct panfrost_context *ctx, bool has_draws, bool is_scanout);
        void (*force_flush_fragment) (struct panfrost_context *ctx,
index 1c08f97fd1df5a992e7b211c781f27556caf5380..787fef2c16eb3041875bff38e7ef6d648bcb6682 100644 (file)
@@ -92,8 +92,7 @@ panfrost_sfbd_set_cbuf(
 {
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
 
-        signed stride =
-                util_format_get_stride(surf->format, surf->texture->width0);
+        signed stride = rsrc->bo->stride;
 
         fb->format = panfrost_sfbd_format(surf);