aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-04-03 02:15:17 -0400
committerRob Clark <[email protected]>2015-04-05 16:36:35 -0400
commitbde2045fa247b4d1de98a3bc7585d1b60f9b58b7 (patch)
treec8f238125517f281751fd6b0dfbb95074099778a /src/gallium/drivers
parentdacf22e0a34d4dc2595f3cb0dbee52318dc9d0d7 (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c24
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.h3
2 files changed, 27 insertions, 0 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 000d1c210af..6dc4a563565 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 1539fc9ad1a..a2a540ce506 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -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;
};