panfrost: Properly align stride

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>
This commit is contained in:
Daniel Stone 2019-03-18 16:07:00 +00:00 committed by Alyssa Rosenzweig
parent 2be60e0c73
commit d258b787fa
7 changed files with 20 additions and 25 deletions

View 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;

View 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;
}

View 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;
}
}

View 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

View file

@ -81,6 +81,7 @@ struct panfrost_bo {
int checksum_stride;
int gem_handle;
unsigned int stride;
};
struct panfrost_resource {

View 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,

View 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);