From 536bcaa68ffb2b6f939cda4477929f5c3ff55a8c Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 7 Mar 2019 03:52:20 +0000 Subject: [PATCH] panfrost: Combine has_afbc/tiled in layout enum AFBC, tiled, and linear BO layouts are mutually exclusive; they should be coupled via a single enum rather than ad hoc checks of booleans. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Tomeu Vizoso --- src/gallium/drivers/panfrost/pan_context.c | 34 ++++++++++++------- src/gallium/drivers/panfrost/pan_resource.c | 36 +++++++++++++++------ src/gallium/drivers/panfrost/pan_resource.h | 20 +++++++++--- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 095f9cf3606..4987d92d01c 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -107,8 +107,7 @@ panfrost_enable_afbc(struct panfrost_context *ctx, struct panfrost_resource *rsr (rsrc->bo->afbc_metadata_size + main_size + 4095) / 4096, true, 0, 0, 0); - rsrc->bo->has_afbc = true; - rsrc->bo->gem_handle = rsrc->bo->afbc_slab.gem_handle; + rsrc->bo->layout = PAN_AFBC; /* Compressed textured reads use a tagged pointer to the metadata */ @@ -142,7 +141,7 @@ panfrost_set_fragment_afbc(struct panfrost_context *ctx) struct panfrost_resource *rsrc = (struct panfrost_resource *) ctx->pipe_framebuffer.cbufs[cb]->texture; /* Non-AFBC is the default */ - if (!rsrc->bo->has_afbc) + if (rsrc->bo->layout != PAN_AFBC) continue; if (ctx->require_sfbd) { @@ -168,7 +167,7 @@ panfrost_set_fragment_afbc(struct panfrost_context *ctx) if (ctx->pipe_framebuffer.zsbuf) { struct panfrost_resource *rsrc = (struct panfrost_resource *) ctx->pipe_framebuffer.zsbuf->texture; - if (rsrc->bo->has_afbc) { + if (rsrc->bo->layout == PAN_AFBC) { if (ctx->require_sfbd) { DBG("Depth AFBC not supported on SFBD\n"); assert(0); @@ -2235,6 +2234,23 @@ panfrost_create_sampler_view( enum mali_format format = panfrost_find_format(desc); + unsigned usage2_layout = 0x10; + + switch (prsrc->bo->layout) { + case PAN_AFBC: + usage2_layout |= 0xc; + break; + case PAN_TILED: + usage2_layout |= 0x1; + break; + case PAN_LINEAR: + usage2_layout |= 0x2; + break; + default: + assert(0); + break; + } + struct mali_texture_descriptor texture_descriptor = { .width = MALI_POSITIVE(texture->width0), .height = MALI_POSITIVE(texture->height0), @@ -2248,11 +2264,7 @@ panfrost_create_sampler_view( .usage1 = 0x0, .is_not_cubemap = 1, - /* 0x11 - regular texture 2d, uncompressed tiled */ - /* 0x12 - regular texture 2d, uncompressed linear */ - /* 0x1c - AFBC compressed (internally tiled, probably) texture 2D */ - - .usage2 = prsrc->bo->has_afbc ? 0x1c : (prsrc->bo->tiled ? 0x11 : 0x12), + .usage2 = usage2_layout }, .swizzle = panfrost_translate_swizzle_4(user_swizzle) @@ -2344,7 +2356,7 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx, struct panfrost_resource *tex = ((struct panfrost_resource *) ctx->pipe_framebuffer.cbufs[i]->texture); bool is_scanout = panfrost_is_scanout(ctx); - if (!is_scanout && !tex->bo->has_afbc) { + if (!is_scanout && tex->bo->layout != PAN_AFBC) { /* The blob is aggressive about enabling AFBC. As such, * it's pretty much necessary to use it here, since we * have no traces of non-compressed FBO. */ @@ -2378,7 +2390,7 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx, struct panfrost_resource *tex = ((struct panfrost_resource *) ctx->pipe_framebuffer.zsbuf->texture); - if (!tex->bo->has_afbc && !panfrost_is_scanout(ctx)) + if (tex->bo->layout != PAN_AFBC && !panfrost_is_scanout(ctx)) panfrost_enable_afbc(ctx, tex, true); } } diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 8fe51bc8d2d..0b97d9c3461 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -197,10 +197,28 @@ panfrost_create_bo(struct panfrost_screen *screen, const struct pipe_resource *t if (template->height0) sz *= template->height0; if (template->depth0) sz *= template->depth0; - /* Tiling textures is almost always faster, unless we only use it once */ - bo->tiled = (template->usage != PIPE_USAGE_STREAM) && (template->bind & PIPE_BIND_SAMPLER_VIEW); + /* Based on the usage, figure out what storing will be used. There are + * various tradeoffs: + * + * Linear: the basic format, bad for memory bandwidth, bad for cache + * use. Zero-copy, though. Renderable. + * + * Tiled: Not compressed, but cache-optimized. Expensive to write into + * (due to software tiling), but cheap to sample from. Ideal for most + * textures. + * + * AFBC: Compressed and renderable (so always desirable for non-scanout + * rendertargets). Cheap to sample from. The format is black box, so we + * can't read/write from software. + */ - if (bo->tiled) { + /* Tiling textures is almost always faster, unless we only use it once */ + bool should_tile = (template->usage != PIPE_USAGE_STREAM) && (template->bind & PIPE_BIND_SAMPLER_VIEW); + + /* Set the layout appropriately */ + bo->layout = should_tile ? PAN_TILED : PAN_LINEAR; + + if (bo->layout == PAN_TILED) { /* For tiled, we don't map directly, so just malloc any old buffer */ for (int l = 0; l < (template->last_level + 1); ++l) { @@ -293,7 +311,7 @@ panfrost_destroy_bo(struct panfrost_screen *screen, struct panfrost_bo *pbo) } } - if (bo->tiled) { + if (bo->layout == PAN_TILED) { /* Tiled has a malloc'd CPU, so just plain ol' free needed */ for (int l = 0; l < MAX_MIP_LEVELS; ++l) { @@ -301,7 +319,7 @@ panfrost_destroy_bo(struct panfrost_screen *screen, struct panfrost_bo *pbo) } } - if (bo->has_afbc) { + if (bo->layout == PAN_AFBC) { /* TODO */ DBG("--leaking afbc (%d bytes)--\n", bo->afbc_metadata_size); } @@ -340,8 +358,8 @@ panfrost_map_bo(struct panfrost_context *ctx, struct pipe_transfer *transfer) /* If non-zero level, it's a mipmapped resource and needs to be treated as such */ bo->is_mipmap |= transfer->level; - if (transfer->usage & PIPE_TRANSFER_MAP_DIRECTLY && bo->tiled) { - /* We cannot directly map tiled textures */ + if (transfer->usage & PIPE_TRANSFER_MAP_DIRECTLY && bo->layout != PAN_LINEAR) { + /* We can only directly map linear resources */ return NULL; } @@ -446,9 +464,9 @@ panfrost_unmap_bo(struct panfrost_context *ctx, struct panfrost_resource *prsrc = (struct panfrost_resource *) transfer->resource; /* Gallium thinks writeback happens here; instead, this is our cue to tile */ - if (bo->has_afbc) { + if (bo->layout == PAN_AFBC) { DBG("Warning: writes to afbc surface can't possibly work out well for you...\n"); - } else if (bo->tiled) { + } else if (bo->layout == PAN_TILED) { struct pipe_context *gallium = (struct pipe_context *) ctx; struct panfrost_screen *screen = pan_screen(gallium->screen); panfrost_tile_texture(screen, prsrc, transfer->level); diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 633f185ab5b..6114fe75779 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -31,6 +31,14 @@ #include "pan_allocate.h" #include "drm-uapi/drm.h" +/* Describes the memory layout of a BO */ + +enum panfrost_memory_layout { + PAN_LINEAR, + PAN_TILED, + PAN_AFBC +}; + struct panfrost_bo { /* Address to the BO in question */ @@ -51,21 +59,23 @@ struct panfrost_bo { /* Number of bytes of the imported allocation */ size_t imported_size; - /* Set for tiled, clear for linear. */ - bool tiled; + /* Internal layout (tiled?) */ + enum panfrost_memory_layout layout; /* Is something other than level 0 ever written? */ bool is_mipmap; /* If AFBC is enabled for this resource, we lug around an AFBC * metadata buffer as well. The actual AFBC resource is also in - * afbc_slab (only defined for AFBC) at position afbc_main_offset */ + * afbc_slab (only defined for AFBC) at position afbc_main_offset + */ - bool has_afbc; struct panfrost_memory afbc_slab; int afbc_metadata_size; - /* Similarly for TE */ + /* If transaciton elimination is enabled, we have a dedicated + * buffer for that as well. */ + bool has_checksum; struct panfrost_memory checksum_slab; int checksum_stride;