summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/freedreno/freedreno_batch.c35
-rw-r--r--src/gallium/drivers/freedreno/freedreno_batch.h7
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.c11
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.c31
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.h3
7 files changed, 51 insertions, 42 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c
index c202ff0e942..51a61d96e02 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.c
+++ b/src/gallium/drivers/freedreno/freedreno_batch.c
@@ -24,10 +24,12 @@
* Rob Clark <[email protected]>
*/
+#include "util/list.h"
#include "util/u_string.h"
#include "freedreno_batch.h"
#include "freedreno_context.h"
+#include "freedreno_resource.h"
struct fd_batch *
fd_batch_create(struct fd_context *ctx)
@@ -54,6 +56,8 @@ fd_batch_create(struct fd_context *ctx)
fd_ringbuffer_set_parent(batch->draw, batch->gmem);
fd_ringbuffer_set_parent(batch->binning, batch->gmem);
+ list_inithead(&batch->used_resources);
+
return batch;
}
@@ -76,7 +80,38 @@ __fd_batch_describe(char* buf, const struct fd_batch *batch)
void
fd_batch_flush(struct fd_batch *batch)
{
+ struct fd_resource *rsc, *rsc_tmp;
+
fd_gmem_render_tiles(batch->ctx);
+
+ /* go through all the used resources and clear their reading flag */
+ LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &batch->used_resources, list) {
+ debug_assert(rsc->pending_batch == batch);
+ debug_assert(rsc->status != 0);
+ rsc->status = 0;
+ fd_batch_reference(&rsc->pending_batch, NULL);
+ list_delinit(&rsc->list);
+ }
+
+ assert(LIST_IS_EMPTY(&batch->used_resources));
+}
+
+void
+fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc,
+ enum fd_resource_status status)
+{
+ rsc->status |= status;
+
+ if (rsc->stencil)
+ rsc->stencil->status |= status;
+
+ /* TODO resources can actually be shared across contexts,
+ * so I'm not sure a single list-head will do the trick?
+ */
+ debug_assert((rsc->pending_batch == batch) || !rsc->pending_batch);
+ list_delinit(&rsc->list);
+ list_addtail(&rsc->list, &batch->used_resources);
+ fd_batch_reference(&rsc->pending_batch, batch);
}
void
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h
index 2134624f833..69779d8c8f4 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.h
+++ b/src/gallium/drivers/freedreno/freedreno_batch.h
@@ -32,6 +32,8 @@
#include "freedreno_util.h"
struct fd_context;
+struct fd_resource;
+enum fd_resource_status;
/* A batch tracks everything about a cmdstream batch/submit, including the
* ringbuffers used for binning, draw, and gmem cmds, list of associated
@@ -48,11 +50,16 @@ struct fd_batch {
struct fd_ringbuffer *binning;
/** tiling/gmem (IB0) cmdstream: */
struct fd_ringbuffer *gmem;
+
+ /** list of resources used by currently-unsubmitted batch */
+ struct list_head used_resources;
};
struct fd_batch * fd_batch_create(struct fd_context *ctx);
void fd_batch_flush(struct fd_batch *batch);
+void fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc,
+ enum fd_resource_status status);
void fd_batch_check_size(struct fd_batch *batch);
/* not called directly: */
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index d3a631e3a00..3614370bf33 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -45,7 +45,6 @@ void
fd_context_render(struct pipe_context *pctx)
{
struct fd_context *ctx = fd_context(pctx);
- struct fd_resource *rsc, *rsc_tmp;
DBG("needs_flush: %d", ctx->needs_flush);
@@ -61,16 +60,6 @@ fd_context_render(struct pipe_context *pctx)
ctx->cleared = ctx->partial_cleared = ctx->restore = ctx->resolve = 0;
ctx->gmem_reason = 0;
ctx->num_draws = 0;
-
- /* go through all the used resources and clear their reading flag */
- LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list) {
- debug_assert(rsc->status != 0);
- rsc->status = 0;
- rsc->pending_ctx = NULL;
- list_delinit(&rsc->list);
- }
-
- assert(LIST_IS_EMPTY(&ctx->used_resources));
}
static void
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index cdf40146881..88e103ea6c3 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -185,9 +185,6 @@ struct fd_context {
struct fd_bo *query_bo;
uint32_t query_tile_stride;
- /* list of resources used by currently-unsubmitted renders */
- struct list_head used_resources;
-
/* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to
* DI_PT_x value to use for draw initiator. There are some
* slight differences between generation:
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 26164f2109e..2c76333cf12 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -40,38 +40,19 @@
#include "freedreno_util.h"
static void
-resource_used(struct fd_context *ctx, struct pipe_resource *prsc,
- enum fd_resource_status status)
+resource_read(struct fd_context *ctx, struct pipe_resource *prsc)
{
- struct fd_resource *rsc;
-
if (!prsc)
return;
-
- rsc = fd_resource(prsc);
- rsc->status |= status;
- if (rsc->stencil)
- rsc->stencil->status |= status;
-
- /* TODO resources can actually be shared across contexts,
- * so I'm not sure a single list-head will do the trick?
- */
- debug_assert((rsc->pending_ctx == ctx) || !rsc->pending_ctx);
- list_delinit(&rsc->list);
- list_addtail(&rsc->list, &ctx->used_resources);
- rsc->pending_ctx = ctx;
-}
-
-static void
-resource_read(struct fd_context *ctx, struct pipe_resource *prsc)
-{
- resource_used(ctx, prsc, FD_PENDING_READ);
+ fd_batch_resource_used(ctx->batch, fd_resource(prsc), FD_PENDING_READ);
}
static void
resource_written(struct fd_context *ctx, struct pipe_resource *prsc)
{
- resource_used(ctx, prsc, FD_PENDING_WRITE);
+ if (!prsc)
+ return;
+ fd_batch_resource_used(ctx->batch, fd_resource(prsc), FD_PENDING_WRITE);
}
static void
@@ -300,8 +281,6 @@ fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
void
fd_draw_init(struct pipe_context *pctx)
{
- list_inithead(&fd_context(pctx)->used_resources);
-
pctx->draw_vbo = fd_draw_vbo;
pctx->clear = fd_clear;
pctx->clear_render_target = fd_clear_render_target;
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 41f46a69c3e..eea53c60696 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -109,7 +109,7 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
rsc->bo = fd_bo_new(screen->dev, size, flags);
rsc->timestamp = 0;
rsc->status = 0;
- rsc->pending_ctx = NULL;
+ fd_batch_reference(&rsc->pending_batch, NULL);
list_delinit(&rsc->list);
util_range_set_empty(&rsc->valid_buffer_range);
}
@@ -453,6 +453,7 @@ fd_resource_destroy(struct pipe_screen *pscreen,
struct fd_resource *rsc = fd_resource(prsc);
if (rsc->bo)
fd_bo_del(rsc->bo);
+ fd_batch_reference(&rsc->pending_batch, NULL);
list_delinit(&rsc->list);
util_range_destroy(&rsc->valid_buffer_range);
FREE(rsc);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 9a9b0d08244..f8131c774ec 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -33,6 +33,7 @@
#include "util/u_range.h"
#include "util/u_transfer.h"
+#include "freedreno_batch.h"
#include "freedreno_util.h"
/* Texture Layout on a3xx:
@@ -91,7 +92,7 @@ struct fd_resource {
* in the used_resources list.
*/
struct list_head list;
- struct fd_context *pending_ctx;
+ struct fd_batch *pending_batch;
};
static inline struct fd_resource *