freedreno: add helper to uncompress UBWC resource

We'll need this for a few edge cases, like image/sampler view that uses
a format that UBWC does not support with a resource originally created
in a format that UBWC does support.

NOTE we *could* in some cases do an in-place uncompress.  But that has
a couple potential sharp edges:

 1) the uncompressed buffer could have different layout, ie. a5xx
    with meta and pixel data of layers/levels interleaved.

 2) if it comes mid-batch, it would force flush, or somehow fixing
    up cmdstream for draws already emitted.  But with the resource
    shadowing approach we can rely on batch re-ordering to avoid
    splitting things.. older draws see the older compressed version,
    newer draws see the new uncompressed version of the rsc.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
This commit is contained in:
Rob Clark 2019-06-07 10:14:12 -07:00
parent 846b8a76bd
commit fe5c7b2b75
2 changed files with 37 additions and 0 deletions

View File

@ -50,6 +50,14 @@
/* XXX this should go away, needed for 'struct winsys_handle' */
#include "state_tracker/drm_driver.h"
/* A private modifier for now, so we have a way to request tiled but not
* compressed. It would perhaps be good to get real modifiers for the
* tiled formats, but would probably need to do some work to figure out
* the layout(s) of the tiled modes, and whether they are the same
* across generations.
*/
#define FD_FORMAT_MOD_QCOM_TILED fourcc_mod_code(QCOM, 0xffffffff)
/**
* Go through the entire state and see if the resource is bound
* anywhere. If it is, mark the relevant state as dirty. This is
@ -304,6 +312,34 @@ fd_try_shadow_resource(struct fd_context *ctx, struct fd_resource *rsc,
return true;
}
/**
* Uncompress an UBWC compressed buffer "in place". This works basically
* like resource shadowing, creating a new resource, and doing an uncompress
* blit, and swapping the state between shadow and original resource so it
* appears to the state tracker as if nothing changed.
*/
void
fd_resource_uncompress(struct fd_context *ctx, struct fd_resource *rsc)
{
bool success =
fd_try_shadow_resource(ctx, rsc, 0, NULL, FD_FORMAT_MOD_QCOM_TILED);
/* shadow should not fail in any cases where we need to uncompress: */
debug_assert(success);
/*
* TODO what if rsc is used in other contexts, we don't currently
* have a good way to rebind_resource() in other contexts. And an
* app that is reading one resource in multiple contexts, isn't
* going to expect that the resource is modified.
*
* Hopefully the edge cases where we need to uncompress are rare
* enough that they mostly only show up in deqp.
*/
rebind_resource(ctx, &rsc->base);
}
static struct fd_resource *
fd_alloc_staging(struct fd_context *ctx, struct fd_resource *rsc,
unsigned level, const struct pipe_box *box)

View File

@ -215,6 +215,7 @@ void fd_resource_context_init(struct pipe_context *pctx);
uint32_t fd_setup_slices(struct fd_resource *rsc);
void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz);
void fd_resource_uncompress(struct fd_context *ctx, struct fd_resource *rsc);
bool fd_render_condition_check(struct pipe_context *pctx);