(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 */
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) {
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);
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),
.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)
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. */
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);
}
}
if (template->height0) sz *= template->height0;
if (template->depth0) sz *= template->depth0;
+ /* 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.
+ */
+
/* 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);
+ 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->tiled) {
+ 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) {
}
}
- 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) {
}
}
- if (bo->has_afbc) {
+ if (bo->layout == PAN_AFBC) {
/* TODO */
DBG("--leaking afbc (%d bytes)--\n", bo->afbc_metadata_size);
}
/* 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;
}
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);
#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 */
/* 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;