X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Flima%2Flima_resource.c;h=6c207f19d9186f58de1c33e61cd034231fa50974;hb=c64994433c0da03d1dabf7cf561f1f1474d6554f;hp=2f9081c3d1151ba961435e1610695b82f1f45bec;hpb=4ed569eed771a1b70b485430c8b595d817232b1c;p=mesa.git diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c index 2f9081c3d11..6c207f19d91 100644 --- a/src/gallium/drivers/lima/lima_resource.c +++ b/src/gallium/drivers/lima/lima_resource.c @@ -24,7 +24,7 @@ #include "util/u_memory.h" #include "util/u_blitter.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_debug.h" @@ -116,6 +116,7 @@ setup_miptree(struct lima_resource *res, res->levels[level].width = aligned_width; res->levels[level].stride = stride; 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 @@ -177,9 +178,13 @@ _lima_resource_create_with_modifiers(struct pipe_screen *pscreen, int count) { struct lima_screen *screen = lima_screen(pscreen); - bool should_tile = false; + bool should_tile = lima_debug & LIMA_DEBUG_NO_TILING ? false : true; unsigned width, height; bool should_align_dimensions; + bool has_user_modifiers = true; + + if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) + has_user_modifiers = false; /* VBOs/PBOs are untiled (and 1 height). */ if (templat->target == PIPE_BUFFER) @@ -188,9 +193,17 @@ _lima_resource_create_with_modifiers(struct pipe_screen *pscreen, if (templat->bind & (PIPE_BIND_LINEAR | PIPE_BIND_SCANOUT)) should_tile = false; - /* if linear buffer is not allowed, alloc fail */ - if (!should_tile && !drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count)) - return NULL; + /* 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 (drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count)) + should_tile = false; + + if (has_user_modifiers && + !drm_find_modifier(DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, + modifiers, count)) + should_tile = false; if (should_tile || (templat->bind & PIPE_BIND_RENDER_TARGET) || (templat->bind & PIPE_BIND_DEPTH_STENCIL)) { @@ -227,10 +240,9 @@ static struct pipe_resource * lima_resource_create(struct pipe_screen *pscreen, const struct pipe_resource *templat) { - static const uint64_t modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - }; - return _lima_resource_create_with_modifiers(pscreen, templat, modifiers, ARRAY_SIZE(modifiers)); + const uint64_t mod = DRM_FORMAT_MOD_INVALID; + + return _lima_resource_create_with_modifiers(pscreen, templat, &mod, 1); } static struct pipe_resource * @@ -259,7 +271,7 @@ lima_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *pres) struct lima_resource *res = lima_resource(pres); if (res->bo) - lima_bo_free(res->bo); + lima_bo_unreference(res->bo); if (res->scanout) renderonly_scanout_destroy(res->scanout, screen->ro); @@ -314,8 +326,24 @@ lima_resource_from_handle(struct pipe_screen *pscreen, else res->levels[0].width = pres->width0; - handle->modifier = DRM_FORMAT_MOD_LINEAR; - res->tiled = false; + switch (handle->modifier) { + case DRM_FORMAT_MOD_LINEAR: + res->tiled = false; + break; + 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; @@ -333,7 +361,10 @@ lima_resource_get_handle(struct pipe_screen *pscreen, struct lima_screen *screen = lima_screen(pscreen); struct lima_resource *res = lima_resource(pres); - handle->modifier = DRM_FORMAT_MOD_LINEAR; + if (res->tiled) + handle->modifier = DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; + else + handle->modifier = DRM_FORMAT_MOD_LINEAR; if (handle->type == WINSYS_HANDLE_TYPE_KMS && screen->ro && renderonly_get_handle(res->scanout, handle)) @@ -346,6 +377,36 @@ lima_resource_get_handle(struct pipe_screen *pscreen, return true; } +static void +get_scissor_from_box(struct pipe_scissor_state *s, + const struct pipe_box *b, int h) +{ + int y = h - (b->y + b->height); + /* region in tile unit */ + s->minx = b->x >> 4; + s->miny = y >> 4; + s->maxx = (b->x + b->width + 0xf) >> 4; + s->maxy = (y + b->height + 0xf) >> 4; +} + +static void +get_damage_bound_box(struct pipe_resource *pres, + const struct pipe_box *rects, + unsigned int nrects, + struct pipe_scissor_state *bound) +{ + struct pipe_box b = rects[0]; + + for (int i = 1; i < nrects; i++) + u_box_union_2d(&b, &b, rects + i); + + int ret = u_box_clip_2d(&b, &b, pres->width0, pres->height0); + if (ret < 0) + memset(bound, 0, sizeof(*bound)); + else + get_scissor_from_box(bound, &b, pres->height0); +} + static void lima_resource_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres, @@ -379,19 +440,16 @@ lima_resource_set_damage_region(struct pipe_screen *pscreen, return; } + struct pipe_scissor_state *bound = &damage->bound; + get_damage_bound_box(pres, rects, nrects, bound); + damage->region = CALLOC(nrects, sizeof(*damage->region)); if (!damage->region) return; - for (i = 0; i < nrects; i++) { - struct pipe_scissor_state *r = damage->region + i; - int y = pres->height0 - (rects[i].y + rects[i].height); - /* region in tile unit */ - r->minx = rects[i].x >> 4; - r->miny = y >> 4; - r->maxx = (rects[i].x + rects[i].width + 0xf) >> 4; - r->maxy = (y + rects[i].height + 0xf) >> 4; - } + for (i = 0; i < nrects; i++) + get_scissor_from_box(damage->region + i, rects + i, + pres->height0); /* is region aligned to tiles? */ damage->aligned = true; @@ -501,7 +559,7 @@ lima_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf) struct lima_ctx_plb_pp_stream *s = entry->data; if (--s->refcnt == 0) { if (s->bo) - lima_bo_free(s->bo); + lima_bo_unreference(s->bo); _mesa_hash_table_remove(ctx->plb_pp_stream, entry); ralloc_free(s); } @@ -536,8 +594,7 @@ lima_transfer_map(struct pipe_context *pctx, * 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_submit_accessing_bo(ctx, bo, usage & PIPE_TRANSFER_WRITE); unsigned op = usage & PIPE_TRANSFER_WRITE ? LIMA_GEM_WAIT_WRITE : LIMA_GEM_WAIT_READ; @@ -568,20 +625,26 @@ lima_transfer_map(struct pipe_context *pctx, trans->staging = malloc(ptrans->stride * ptrans->box.height * ptrans->box.depth); - if (usage & PIPE_TRANSFER_READ) - panfrost_load_tiled_image(trans->staging, bo->map + res->levels[level].offset, - &ptrans->box, - ptrans->stride, - res->levels[level].stride, - util_format_get_blocksize(pres->format)); + if (usage & PIPE_TRANSFER_READ) { + unsigned i; + for (i = 0; i < ptrans->box.depth; i++) + 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.x, ptrans->box.y, + ptrans->box.width, ptrans->box.height, + ptrans->stride, + res->levels[level].stride, + pres->format); + } return trans->staging; } else { ptrans->stride = res->levels[level].stride; - ptrans->layer_stride = ptrans->stride * box->height; + ptrans->layer_stride = res->levels[level].layer_stride; return bo->map + res->levels[level].offset + - box->z * ptrans->layer_stride + + box->z * res->levels[level].layer_stride + box->y / util_format_get_blockheight(pres->format) * ptrans->stride + box->x / util_format_get_blockwidth(pres->format) * util_format_get_blocksize(pres->format); @@ -608,12 +671,18 @@ lima_transfer_unmap(struct pipe_context *pctx, if (trans->staging) { pres = &res->base; - if (ptrans->usage & PIPE_TRANSFER_WRITE) - panfrost_store_tiled_image(bo->map + res->levels[ptrans->level].offset, trans->staging, - &ptrans->box, - res->levels[ptrans->level].stride, - ptrans->stride, - util_format_get_blocksize(pres->format)); + if (ptrans->usage & PIPE_TRANSFER_WRITE) { + unsigned i; + for (i = 0; i < ptrans->box.depth; i++) + 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.x, ptrans->box.y, + ptrans->box.width, ptrans->box.height, + res->levels[ptrans->level].stride, + ptrans->stride, + pres->format); + } free(trans->staging); }