diff options
author | Rob Clark <[email protected]> | 2014-01-07 10:55:07 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2014-01-08 16:30:18 -0500 |
commit | c0766528baaef48902c87bbdaa4f5926c472269b (patch) | |
tree | f825706059f50c37a9fda7961ec596b0fb6a65da /src/gallium/drivers/freedreno/freedreno_context.c | |
parent | bfb44c24bc1eff850d47984b2cb60c957ffc143d (diff) |
freedreno/a3xx: support for hw binning pass
The binning pass sorts vertices into which bins/tiles they apply to.
The visibility information generated during the binning pass can be
used to speed up the rendering pass by filtering out vertices which
do not apply to the current tile. See:
https://github.com/freedreno/freedreno/wiki/Adreno-tiling#optimized-approach
This brings a significant fps boost. A rough assortment of tests
(supertuxkart, etracer, tremulous, glmark2 'build' test, etc) seems
to yield a ~35-45% fps improvement.
For now, to be conservative, the binning pass is not enabled yet by
default. To enable it use:
FD_MESA_DEBUG=binning
So far I haven't found anything that breaks with binning enabled,
but I'd like a bit more testing before I enable it as default.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_context.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_context.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 28be508e329..23f6a67734d 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -34,16 +34,11 @@ #include "freedreno_gmem.h" #include "freedreno_util.h" -static void -fd_context_next_rb(struct pipe_context *pctx) +static struct fd_ringbuffer *next_rb(struct fd_context *ctx) { - struct fd_context *ctx = fd_context(pctx); struct fd_ringbuffer *ring; uint32_t ts; - fd_ringmarker_del(ctx->draw_start); - fd_ringmarker_del(ctx->draw_end); - /* grab next ringbuffer: */ ring = ctx->rings[(ctx->rings_idx++) % ARRAY_SIZE(ctx->rings)]; @@ -56,10 +51,36 @@ fd_context_next_rb(struct pipe_context *pctx) fd_ringbuffer_reset(ring); + return ring; +} + +static void +fd_context_next_rb(struct pipe_context *pctx) +{ + struct fd_context *ctx = fd_context(pctx); + struct fd_ringbuffer *ring; + + fd_ringmarker_del(ctx->draw_start); + fd_ringmarker_del(ctx->draw_end); + + ring = next_rb(ctx); + ctx->draw_start = fd_ringmarker_new(ring); ctx->draw_end = fd_ringmarker_new(ring); + fd_ringbuffer_set_parent(ring, NULL); ctx->ring = ring; + + fd_ringmarker_del(ctx->binning_start); + fd_ringmarker_del(ctx->binning_end); + + ring = next_rb(ctx); + + ctx->binning_start = fd_ringmarker_new(ring); + ctx->binning_end = fd_ringmarker_new(ring); + + fd_ringbuffer_set_parent(ring, ctx->ring); + ctx->binning_ring = ring; } /* emit accumulated render cmds, needed for example if render target has @@ -121,6 +142,10 @@ fd_context_destroy(struct pipe_context *pctx) DBG(""); + util_slab_destroy(&ctx->transfer_pool); + + util_dynarray_fini(&ctx->draw_patches); + if (ctx->blitter) util_blitter_destroy(ctx->blitter); @@ -129,7 +154,11 @@ fd_context_destroy(struct pipe_context *pctx) fd_ringmarker_del(ctx->draw_start); fd_ringmarker_del(ctx->draw_end); - fd_ringbuffer_del(ctx->ring); + fd_ringmarker_del(ctx->binning_start); + fd_ringmarker_del(ctx->binning_end); + + for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) + fd_ringbuffer_del(ctx->rings[i]); for (i = 0; i < ARRAY_SIZE(ctx->pipe); i++) { struct fd_vsc_pipe *pipe = &ctx->pipe[i]; @@ -176,6 +205,8 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, fd_context_next_rb(pctx); fd_reset_rmw_state(ctx); + util_dynarray_init(&ctx->draw_patches); + util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); |