summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.c10
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.c38
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c6
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.h3
5 files changed, 59 insertions, 1 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index bb1b52797a8..5fca57c5a3a 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -95,6 +95,7 @@ fd_context_render(struct pipe_context *pctx)
{
struct fd_context *ctx = fd_context(pctx);
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+ struct fd_resource *rsc, *rsc_tmp;
int i;
DBG("needs_flush: %d", ctx->needs_flush);
@@ -122,6 +123,15 @@ fd_context_render(struct pipe_context *pctx)
fd_resource(pfb->cbufs[i]->texture)->dirty = false;
if (pfb->zsbuf)
fd_resource(pfb->zsbuf->texture)->dirty = false;
+
+ /* go through all the used resources and clear their reading flag */
+ LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list) {
+ assert(rsc->reading);
+ rsc->reading = false;
+ 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 7b0424e65da..a648689cefd 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -165,6 +165,9 @@ 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 423ae23769c..fed3e64f202 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -39,6 +39,19 @@
#include "freedreno_query_hw.h"
#include "freedreno_util.h"
+static void
+resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
+{
+ struct fd_resource *rsc;
+
+ if (!prsc)
+ return;
+
+ rsc = fd_resource(prsc);
+ rsc->reading = true;
+ list_delinit(&rsc->list);
+ list_addtail(&rsc->list, &ctx->used_resources);
+}
static void
fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
@@ -101,6 +114,29 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
ctx->gmem_reason |= FD_GMEM_BLEND_ENABLED;
}
+ /* Skip over buffer 0, that is sent along with the command stream */
+ for (i = 1; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ resource_reading(ctx, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
+ resource_reading(ctx, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
+ }
+
+ /* Mark VBOs as being read */
+ for (i = 0; i < ctx->vtx.vertexbuf.count; i++) {
+ assert(!ctx->vtx.vertexbuf.vb[i].user_buffer);
+ resource_reading(ctx, ctx->vtx.vertexbuf.vb[i].buffer);
+ }
+
+ /* Mark index buffer as being read */
+ resource_reading(ctx, ctx->indexbuf.buffer);
+
+ /* Mark textures as being read */
+ for (i = 0; i < ctx->verttex.num_textures; i++)
+ if (ctx->verttex.textures[i])
+ resource_reading(ctx, ctx->verttex.textures[i]->texture);
+ for (i = 0; i < ctx->fragtex.num_textures; i++)
+ if (ctx->fragtex.textures[i])
+ resource_reading(ctx, ctx->fragtex.textures[i]->texture);
+
ctx->num_draws++;
ctx->stats.draw_calls++;
@@ -223,6 +259,8 @@ 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 6e7958d42dd..000d1c210af 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -57,7 +57,8 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
rsc->bo = fd_bo_new(screen->dev, size, flags);
rsc->timestamp = 0;
- rsc->dirty = false;
+ rsc->dirty = rsc->reading = false;
+ list_delinit(&rsc->list);
}
static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
@@ -170,6 +171,7 @@ fd_resource_destroy(struct pipe_screen *pscreen,
struct fd_resource *rsc = fd_resource(prsc);
if (rsc->bo)
fd_bo_del(rsc->bo);
+ list_delinit(&rsc->list);
FREE(rsc);
}
@@ -277,6 +279,7 @@ fd_resource_create(struct pipe_screen *pscreen,
*prsc = *tmpl;
pipe_reference_init(&prsc->reference, 1);
+ list_inithead(&rsc->list);
prsc->screen = pscreen;
rsc->base.vtbl = &fd_resource_vtbl;
@@ -340,6 +343,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
*prsc = *tmpl;
pipe_reference_init(&prsc->reference, 1);
+ list_inithead(&rsc->list);
prsc->screen = pscreen;
rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 1f246328969..1539fc9ad1a 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -29,6 +29,7 @@
#ifndef FREEDRENO_RESOURCE_H_
#define FREEDRENO_RESOURCE_H_
+#include "util/u_double_list.h"
#include "util/u_transfer.h"
#include "freedreno_util.h"
@@ -67,6 +68,8 @@ struct fd_resource {
struct fd_resource_slice slices[MAX_MIP_LEVELS];
uint32_t timestamp;
bool dirty, reading;
+
+ struct list_head list;
};
static INLINE struct fd_resource *