#include "util/u_transfer.h"
#include "util/u_surface.h"
#include "util/hash_table.h"
+#include "util/ralloc.h"
#include "util/u_drm.h"
#include "renderonly/renderonly.h"
#include "lima_resource.h"
#include "lima_bo.h"
#include "lima_util.h"
+
+#include "pan_minmax_cache.h"
#include "pan_tiling.h"
static struct pipe_resource *
res->levels[level].offset = size;
res->levels[level].layer_stride = util_format_get_stride(pres->format, align(width, 16)) * align(height, 16);
- /* The start address of each level <= 10 must be 64-aligned
- * in order to be able to pass the addresses
- * to the hardware.
- * The start addresses of level 11 and level 12 are passed
- * implicitely: they start at an offset of respectively
- * 0x0400 and 0x0800 from the start address of level 10 */
- if (level < 10)
+ if (util_format_is_compressed(pres->format))
+ res->levels[level].layer_stride /= 4;
+
+ /* The start address of each level except the last level
+ * must be 64-aligned in order to be able to pass the
+ * addresses to the hardware. */
+ if (level != pres->last_level)
size += align(actual_level_size, 64);
- else if (level != pres->last_level)
- size += 0x0400;
else
size += actual_level_size; /* Save some memory */
int count)
{
struct lima_screen *screen = lima_screen(pscreen);
- bool should_tile = true;
+ bool should_tile = lima_debug & LIMA_DEBUG_NO_TILING ? false : true;
unsigned width, height;
bool should_align_dimensions;
bool has_user_modifiers = true;
if (templat->bind & (PIPE_BIND_LINEAR | PIPE_BIND_SCANOUT))
should_tile = false;
- if (drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count))
+ /* If there's no user modifiers and buffer is shared we use linear */
+ if (!has_user_modifiers && (templat->bind & PIPE_BIND_SHARED))
should_tile = false;
if (has_user_modifiers &&
struct lima_resource *res = lima_resource(pres);
res->tiled = should_tile;
+ if (templat->bind & PIPE_BIND_INDEX_BUFFER)
+ res->index_cache = CALLOC_STRUCT(panfrost_minmax_cache);
+
debug_printf("%s: pres=%p width=%u height=%u depth=%u target=%d "
"bind=%x usage=%d tile=%d last_level=%d\n", __func__,
pres, pres->width0, pres->height0, pres->depth0,
if (res->damage.region)
FREE(res->damage.region);
+ if (res->index_cache)
+ FREE(res->index_cache);
+
FREE(res);
}
case DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED:
res->tiled = true;
break;
+ case DRM_FORMAT_MOD_INVALID:
+ /* Modifier wasn't specified and it's shared buffer. We create these
+ * as linear, so disable tiling.
+ */
+ res->tiled = false;
+ break;
default:
fprintf(stderr, "Attempted to import unsupported modifier 0x%llx\n",
(long long)handle->modifier);
+ goto err_out;
}
return pres;
surf->reload = true;
- struct lima_context *ctx = lima_context(pctx);
- if (ctx->plb_pp_stream) {
- struct lima_ctx_plb_pp_stream_key key = {
- .tiled_w = surf->tiled_w,
- .tiled_h = surf->tiled_h,
- };
-
- for (int i = 0; i < lima_ctx_num_plb; i++) {
- key.plb_index = i;
-
- struct hash_entry *entry =
- _mesa_hash_table_search(ctx->plb_pp_stream, &key);
- if (entry) {
- struct lima_ctx_plb_pp_stream *s = entry->data;
- s->refcnt++;
- }
- else {
- struct lima_ctx_plb_pp_stream *s =
- ralloc(ctx->plb_pp_stream, struct lima_ctx_plb_pp_stream);
- s->key.plb_index = i;
- s->key.tiled_w = surf->tiled_w;
- s->key.tiled_h = surf->tiled_h;
- s->refcnt = 1;
- s->bo = NULL;
- _mesa_hash_table_insert(ctx->plb_pp_stream, &s->key, s);
- }
- }
- }
-
return &surf->base;
}
lima_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf)
{
struct lima_surface *surf = lima_surface(psurf);
- /* psurf->context may be not equal with pctx (i.e. glxinfo) */
- struct lima_context *ctx = lima_context(psurf->context);
-
- if (ctx->plb_pp_stream) {
- struct lima_ctx_plb_pp_stream_key key = {
- .tiled_w = surf->tiled_w,
- .tiled_h = surf->tiled_h,
- };
-
- for (int i = 0; i < lima_ctx_num_plb; i++) {
- key.plb_index = i;
-
- struct hash_entry *entry =
- _mesa_hash_table_search(ctx->plb_pp_stream, &key);
- struct lima_ctx_plb_pp_stream *s = entry->data;
- if (--s->refcnt == 0) {
- if (s->bo)
- lima_bo_unreference(s->bo);
- _mesa_hash_table_remove(ctx->plb_pp_stream, entry);
- ralloc_free(s);
- }
- }
- }
pipe_resource_reference(&psurf->texture, NULL);
FREE(surf);
* range, so no need to sync */
if (pres->usage != PIPE_USAGE_STREAM) {
if (usage & PIPE_TRANSFER_READ_WRITE) {
- if (lima_need_flush(ctx, bo, usage & PIPE_TRANSFER_WRITE))
- lima_flush(ctx);
+ lima_flush_job_accessing_bo(ctx, bo, usage & PIPE_TRANSFER_WRITE);
unsigned op = usage & PIPE_TRANSFER_WRITE ?
LIMA_GEM_WAIT_WRITE : LIMA_GEM_WAIT_READ;
panfrost_load_tiled_image(
trans->staging + i * ptrans->stride * ptrans->box.height,
bo->map + res->levels[level].offset + (i + box->z) * res->levels[level].layer_stride,
- &ptrans->box,
+ ptrans->box.x, ptrans->box.y,
+ ptrans->box.width, ptrans->box.height,
ptrans->stride,
res->levels[level].stride,
- util_format_get_blocksize(pres->format));
+ pres->format);
}
return trans->staging;
} else {
+ unsigned dpw = PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_PERSISTENT;
+ if ((usage & dpw) == dpw && res->index_cache)
+ return NULL;
+
ptrans->stride = res->levels[level].stride;
ptrans->layer_stride = res->levels[level].layer_stride;
+ if ((usage & PIPE_TRANSFER_WRITE) && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
+ panfrost_minmax_cache_invalidate(res->index_cache, ptrans);
+
return bo->map + res->levels[level].offset +
box->z * res->levels[level].layer_stride +
box->y / util_format_get_blockheight(pres->format) * ptrans->stride +
panfrost_store_tiled_image(
bo->map + res->levels[ptrans->level].offset + (i + ptrans->box.z) * res->levels[ptrans->level].layer_stride,
trans->staging + i * ptrans->stride * ptrans->box.height,
- &ptrans->box,
+ ptrans->box.x, ptrans->box.y,
+ ptrans->box.width, ptrans->box.height,
res->levels[ptrans->level].stride,
ptrans->stride,
- util_format_get_blocksize(pres->format));
+ pres->format);
}
free(trans->staging);
}
+ panfrost_minmax_cache_invalidate(res->index_cache, ptrans);
+
pipe_resource_reference(&ptrans->resource, NULL);
slab_free(&ctx->transfer_pool, trans);
}