mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 08:30:10 +01:00
freedreno: keep track of buffer valid ranges
Copies nouveau_buffer and radeon_buffer. This allows a write to proceed to an uninitialized part of a buffer even when the GPU is using the previously-initialized portions. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
dacf22e0a3
commit
bde2045fa2
2 changed files with 27 additions and 0 deletions
|
|
@ -59,12 +59,19 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
|
|||
rsc->timestamp = 0;
|
||||
rsc->dirty = rsc->reading = false;
|
||||
list_delinit(&rsc->list);
|
||||
util_range_set_empty(&rsc->valid_buffer_range);
|
||||
}
|
||||
|
||||
static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
|
||||
struct pipe_transfer *ptrans,
|
||||
const struct pipe_box *box)
|
||||
{
|
||||
struct fd_resource *rsc = fd_resource(ptrans->resource);
|
||||
|
||||
if (ptrans->resource->target == PIPE_BUFFER)
|
||||
util_range_add(&rsc->valid_buffer_range,
|
||||
ptrans->box.x + box->x,
|
||||
ptrans->box.x + box->x + box->width);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -75,6 +82,11 @@ fd_resource_transfer_unmap(struct pipe_context *pctx,
|
|||
struct fd_resource *rsc = fd_resource(ptrans->resource);
|
||||
if (!(ptrans->usage & PIPE_TRANSFER_UNSYNCHRONIZED))
|
||||
fd_bo_cpu_fini(rsc->bo);
|
||||
|
||||
util_range_add(&rsc->valid_buffer_range,
|
||||
ptrans->box.x,
|
||||
ptrans->box.x + ptrans->box.width);
|
||||
|
||||
pipe_resource_reference(&ptrans->resource, NULL);
|
||||
util_slab_free(&ctx->transfer_pool, ptrans);
|
||||
}
|
||||
|
|
@ -120,6 +132,13 @@ fd_resource_transfer_map(struct pipe_context *pctx,
|
|||
|
||||
if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
|
||||
realloc_bo(rsc, fd_bo_size(rsc->bo));
|
||||
} else if ((usage & PIPE_TRANSFER_WRITE) &&
|
||||
prsc->target == PIPE_BUFFER &&
|
||||
!util_ranges_intersect(&rsc->valid_buffer_range,
|
||||
box->x, box->x + box->width)) {
|
||||
/* We are trying to write to a previously uninitialized range. No need
|
||||
* to wait.
|
||||
*/
|
||||
} else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
|
||||
/* If the GPU is writing to the resource, or if it is reading from the
|
||||
* resource and we're trying to write to it, flush the renders.
|
||||
|
|
@ -172,6 +191,7 @@ fd_resource_destroy(struct pipe_screen *pscreen,
|
|||
if (rsc->bo)
|
||||
fd_bo_del(rsc->bo);
|
||||
list_delinit(&rsc->list);
|
||||
util_range_destroy(&rsc->valid_buffer_range);
|
||||
FREE(rsc);
|
||||
}
|
||||
|
||||
|
|
@ -282,6 +302,8 @@ fd_resource_create(struct pipe_screen *pscreen,
|
|||
list_inithead(&rsc->list);
|
||||
prsc->screen = pscreen;
|
||||
|
||||
util_range_init(&rsc->valid_buffer_range);
|
||||
|
||||
rsc->base.vtbl = &fd_resource_vtbl;
|
||||
rsc->cpp = util_format_get_blocksize(tmpl->format);
|
||||
|
||||
|
|
@ -346,6 +368,8 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
|
|||
list_inithead(&rsc->list);
|
||||
prsc->screen = pscreen;
|
||||
|
||||
util_range_init(&rsc->valid_buffer_range);
|
||||
|
||||
rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch);
|
||||
if (!rsc->bo)
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#define FREEDRENO_RESOURCE_H_
|
||||
|
||||
#include "util/u_double_list.h"
|
||||
#include "util/u_range.h"
|
||||
#include "util/u_transfer.h"
|
||||
|
||||
#include "freedreno_util.h"
|
||||
|
|
@ -68,6 +69,8 @@ struct fd_resource {
|
|||
struct fd_resource_slice slices[MAX_MIP_LEVELS];
|
||||
uint32_t timestamp;
|
||||
bool dirty, reading;
|
||||
/* buffer range that has been initialized */
|
||||
struct util_range valid_buffer_range;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue