OSDN Git Service

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 10eb679..19cdb6c 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 71e8c6a..bc2007e 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 ac7f9ed..6a7cd59 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 9e83c9b..6fe8715 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 2e3d72b..4b5b9c4 100644 (file)
@@ -81,6 +81,7 @@ struct panfrost_bo {
         int checksum_stride;
 
         int gem_handle;
+        unsigned int stride;
 };
 
 struct panfrost_resource {
index 882611e..cbadf81 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 1c08f97..787fef2 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);