diff options
author | Eric Anholt <[email protected]> | 2014-08-01 15:33:06 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-08-11 14:45:31 -0700 |
commit | 2259cc5aebcb16636b1399dd438beed9d9867e67 (patch) | |
tree | 23c5a96fefbf0fc88555931a57806e06c97820fe | |
parent | 6b2583412f0789d2aec71e55e1e187d1ad17f721 (diff) |
vc4: Avoid flushing when mapping buffers that aren't in the batch.
This should prevent a bunch of unnecessary flushes for things like
updating immediate vertex data.
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.c | 48 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_resource.c | 2 |
3 files changed, 50 insertions, 1 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c index 6799e7ebf61..11e42a3ad91 100644 --- a/src/gallium/drivers/vc4/vc4_context.c +++ b/src/gallium/drivers/vc4/vc4_context.c @@ -248,6 +248,54 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, vc4_flush(pctx); } +/** + * Flushes the current command lists if they reference the given BO. + * + * This helps avoid flushing the command buffers when unnecessary. + */ +void +vc4_flush_for_bo(struct pipe_context *pctx, struct vc4_bo *bo) +{ + struct vc4_context *vc4 = vc4_context(pctx); + + if (!vc4->needs_flush) + return; + + /* Walk all the referenced BOs in the drawing command list to see if + * they match. + */ + struct vc4_bo **referenced_bos = vc4->bo_pointers.base; + for (int i = 0; i < (vc4->bo_handles.next - + vc4->bo_handles.base) / 4; i++) { + if (referenced_bos[i] == bo) { + vc4_flush(pctx); + return; + } + } + + /* 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) { + vc4_flush(pctx); + return; + } + } + + struct vc4_surface *zsurf = vc4_surface(vc4->framebuffer.zsbuf); + if (zsurf) { + struct vc4_resource *ztex = + vc4_resource(zsurf->base.texture); + if (ztex->bo == bo) { + vc4_flush(pctx); + return; + } + } +} + static void vc4_context_destroy(struct pipe_context *pctx) { diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index 85cdf41e427..d6367871358 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -217,6 +217,7 @@ void vc4_write_uniforms(struct vc4_context *vc4, int shader_index); void vc4_flush(struct pipe_context *pctx); +void vc4_flush_for_bo(struct pipe_context *pctx, struct vc4_bo *bo); void vc4_emit_state(struct pipe_context *pctx); void vc4_generate_code(struct qcompile *c); void vc4_update_compiled_shaders(struct vc4_context *vc4); diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c index 9df2aae435b..3b1abd11152 100644 --- a/src/gallium/drivers/vc4/vc4_resource.c +++ b/src/gallium/drivers/vc4/vc4_resource.c @@ -57,7 +57,7 @@ vc4_resource_transfer_map(struct pipe_context *pctx, enum pipe_format format = prsc->format; char *buf; - vc4_flush(pctx); + vc4_flush_for_bo(pctx, rsc->bo); ptrans = util_slab_alloc(&vc4->transfer_pool); if (!ptrans) |