mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 09:10:32 +01:00
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:
parent
2be60e0c73
commit
d258b787fa
7 changed files with 20 additions and 25 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ struct panfrost_bo {
|
|||
int checksum_stride;
|
||||
|
||||
int gem_handle;
|
||||
unsigned int stride;
|
||||
};
|
||||
|
||||
struct panfrost_resource {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue