summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_context.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2016-09-08 12:56:11 -0700
committerEric Anholt <[email protected]>2016-09-14 06:25:41 +0100
commitf597ac3966405934e13a9aaa18c73211b5a40c7c (patch)
treef7f09bead790e4cdd210e1ed0ca4c4b150dbe35e /src/gallium/drivers/vc4/vc4_context.c
parentf473348468ae1c68e7ef8eaf29f2cc51d17fbec7 (diff)
vc4: Implement job shuffling
Track rendering to each FBO independently and flush rendering only when necessary. This lets us avoid the overhead of storing and loading the frame when an application momentarily switches to rendering to some other texture in order to continue rendering the main scene. Improves glmark -b desktop:effect=shadow:windows=4 by 27% Improves glmark -b desktop:blur-radius=5:effect=blur:passes=1:separable=true:windows=4 by 17% While I haven't tested other apps, this should help X rendering a lot, and I've heard GLBenchmark needed it too.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_context.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_context.c101
1 files changed, 15 insertions, 86 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index 37b002d5cba..3863e4432a9 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -41,38 +41,12 @@ void
vc4_flush(struct pipe_context *pctx)
{
struct vc4_context *vc4 = vc4_context(pctx);
- struct pipe_surface *cbuf = vc4->framebuffer.cbufs[0];
- struct pipe_surface *zsbuf = vc4->framebuffer.zsbuf;
- struct vc4_job *job = vc4->job;
-
- if (cbuf && (job->resolve & PIPE_CLEAR_COLOR0)) {
- if (cbuf->texture->nr_samples > 1) {
- pipe_surface_reference(&job->msaa_color_write, cbuf);
- } else {
- pipe_surface_reference(&job->color_write, cbuf);
- }
-
- pipe_surface_reference(&job->color_read, cbuf);
- }
-
- if (zsbuf && (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
- if (zsbuf->texture->nr_samples > 1) {
- pipe_surface_reference(&job->msaa_zs_write, zsbuf);
- } else {
- pipe_surface_reference(&job->zs_write, zsbuf);
- }
- pipe_surface_reference(&job->zs_read, zsbuf);
+ struct hash_entry *entry;
+ hash_table_foreach(vc4->jobs, entry) {
+ struct vc4_job *job = entry->data;
+ vc4_job_submit(vc4, job);
}
-
- vc4_job_submit(vc4, job);
-
- /* We have no hardware context saved between our draw calls, so we
- * need to flag the next draw as needing all state emitted. Emitting
- * all state at the start of our draws is also what ensures that we
- * return to the state we need after a previous tile has finished.
- */
- vc4->dirty = ~0;
}
static void
@@ -92,64 +66,18 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
}
}
-/**
- * Flushes the current command lists if they reference the given BO.
- *
- * This helps avoid flushing the command buffers when unnecessary.
- */
-bool
-vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo,
- bool include_reads)
-{
- struct vc4_context *vc4 = vc4_context(pctx);
- struct vc4_job *job = vc4->job;
-
- if (!job->needs_flush)
- return false;
-
- /* Walk all the referenced BOs in the drawing command list to see if
- * they match.
- */
- if (include_reads) {
- struct vc4_bo **referenced_bos = job->bo_pointers.base;
- for (int i = 0; i < cl_offset(&job->bo_handles) / 4; i++) {
- if (referenced_bos[i] == bo) {
- return true;
- }
- }
- }
-
- /* Also check for the Z/color buffers, since the references to those
- * are only added immediately before submit.
- */
- struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
- if (csurf) {
- struct vc4_resource *ctex = vc4_resource(csurf->base.texture);
- if (ctex->bo == bo) {
- return true;
- }
- }
-
- struct vc4_surface *zsurf = vc4_surface(vc4->framebuffer.zsbuf);
- if (zsurf) {
- struct vc4_resource *ztex =
- vc4_resource(zsurf->base.texture);
- if (ztex->bo == bo) {
- return true;
- }
- }
-
- return false;
-}
-
static void
vc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct vc4_context *vc4 = vc4_context(pctx);
- struct pipe_surface *zsurf = vc4->framebuffer.zsbuf;
-
- if (zsurf && zsurf->texture == prsc)
- vc4->job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
+ struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs,
+ prsc);
+ if (!entry)
+ return;
+
+ struct vc4_job *job = entry->data;
+ if (job->key.zsbuf && job->key.zsbuf->texture == prsc)
+ job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
}
static void
@@ -157,6 +85,8 @@ vc4_context_destroy(struct pipe_context *pctx)
{
struct vc4_context *vc4 = vc4_context(pctx);
+ vc4_flush(pctx);
+
if (vc4->blitter)
util_blitter_destroy(vc4->blitter);
@@ -205,8 +135,7 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
vc4_query_init(pctx);
vc4_resource_context_init(pctx);
- vc4->job = rzalloc(vc4, struct vc4_job);
- vc4_job_init(vc4->job);
+ vc4_job_init(vc4);
vc4->fd = screen->fd;