rsc->halign = halign;
pipe_reference_init(&rsc->base.reference, 1);
+ util_range_init(&rsc->valid_buffer_range);
size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale);
if (rsc->scanout)
renderonly_scanout_destroy(rsc->scanout, etna_screen(pscreen)->ro);
+ util_range_destroy(&rsc->valid_buffer_range);
+
pipe_resource_reference(&rsc->texture, NULL);
pipe_resource_reference(&rsc->render, NULL);
*prsc = *tmpl;
pipe_reference_init(&prsc->reference, 1);
+ util_range_init(&rsc->valid_buffer_range);
prsc->screen = pscreen;
rsc->bo = etna_screen_bo_from_handle(pscreen, handle, &level->stride);
#include "util/list.h"
#include "util/set.h"
#include "util/u_helpers.h"
+#include "util/u_range.h"
struct etna_context;
struct pipe_screen;
struct etna_resource_level levels[ETNA_NUM_LOD];
+ /* buffer range that has been initialized */
+ struct util_range valid_buffer_range;
+
/* for when TE doesn't support the base layout */
struct pipe_resource *texture;
/* for when PE doesn't support the base layout */
if (!trans->rsc && !(ptrans->usage & PIPE_TRANSFER_UNSYNCHRONIZED))
etna_bo_cpu_fini(rsc->bo);
+ if ((ptrans->resource->target == PIPE_BUFFER) &&
+ (ptrans->usage & PIPE_TRANSFER_WRITE)) {
+ util_range_add(&rsc->base,
+ &rsc->valid_buffer_range,
+ ptrans->box.x,
+ ptrans->box.x + ptrans->box.width);
+ }
+
pipe_resource_reference(&trans->rsc, NULL);
pipe_resource_reference(&ptrans->resource, NULL);
slab_free(&ctx->transfer_pool, trans);
/* slab_alloc() doesn't zero */
memset(trans, 0, sizeof(*trans));
+ /*
+ * Upgrade to UNSYNCHRONIZED if target is PIPE_BUFFER and range is uninitialized.
+ */
+ if ((usage & PIPE_TRANSFER_WRITE) &&
+ (prsc->target == PIPE_BUFFER) &&
+ !util_ranges_intersect(&rsc->valid_buffer_range,
+ box->x,
+ box->x + box->width)) {
+ usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
+ }
+
/* Upgrade DISCARD_RANGE to WHOLE_RESOURCE if the whole resource is
* being mapped. If we add buffer reallocation to avoid CPU/GPU sync this
* check needs to be extended to coherent mappings and shared resources.
static void
etna_transfer_flush_region(struct pipe_context *pctx,
- struct pipe_transfer *transfer,
+ struct pipe_transfer *ptrans,
const struct pipe_box *box)
{
- /* NOOP for now */
+ struct etna_resource *rsc = etna_resource(ptrans->resource);
+
+ if (ptrans->resource->target == PIPE_BUFFER)
+ util_range_add(&rsc->base,
+ &rsc->valid_buffer_range,
+ ptrans->box.x + box->x,
+ ptrans->box.x + box->x + box->width);
}
void