diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx/fd3_gmem.c')
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index dde71ba..72fe6f7 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -115,6 +115,24 @@ static bool use_hw_binning(struct fd_context *ctx) { struct fd_gmem_stateobj *gmem = &ctx->gmem; + + /* workaround: combining scissor optimization and hw binning + * seems problematic. Seems like we end up with a mismatch + * between binning pass and rendering pass, wrt. where the hw + * thinks the vertices belong. And the blob driver doesn't + * seem to implement anything like scissor optimization, so + * not entirely sure what I might be missing. + * + * But scissor optimization is mainly for window managers, + * which don't have many vertices (and therefore doesn't + * benefit much from binning pass). + * + * So for now just disable binning if scissor optimization is + * used. + */ + if (gmem->minx || gmem->miny) + return false; + return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) > 2); } @@ -644,10 +662,16 @@ update_vsc_pipe(struct fd_context *ctx) static void emit_binning_pass(struct fd_context *ctx) { + struct fd_gmem_stateobj *gmem = &ctx->gmem; struct pipe_framebuffer_state *pfb = &ctx->framebuffer; struct fd_ringbuffer *ring = ctx->ring; int i; + uint32_t x1 = gmem->minx; + uint32_t y1 = gmem->miny; + uint32_t x2 = gmem->minx + gmem->width - 1; + uint32_t y2 = gmem->miny + gmem->height - 1; + if (ctx->screen->gpu_id == 320) { emit_binning_workaround(ctx); @@ -670,21 +694,21 @@ emit_binning_pass(struct fd_context *ctx) OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1); OUT_RING(ring, A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER) | A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE | - A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx->gmem.bin_w)); + A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w)); /* setup scissor/offset for whole screen: */ OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1); - OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(0) | - A3XX_RB_WINDOW_OFFSET_Y(0)); + OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(x1) | + A3XX_RB_WINDOW_OFFSET_Y(y1)); OUT_PKT0(ring, REG_A3XX_RB_LRZ_VSC_CONTROL, 1); OUT_RING(ring, A3XX_RB_LRZ_VSC_CONTROL_BINNING_ENABLE); OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2); - OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) | - A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0)); - OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) | - A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1)); + OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) | + A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1)); + OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) | + A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2)); OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1); OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_TILING_PASS) | @@ -731,7 +755,7 @@ emit_binning_pass(struct fd_context *ctx) A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE); OUT_RING(ring, A3XX_RB_RENDER_CONTROL_ENABLE_GMEM | A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER) | - A3XX_RB_RENDER_CONTROL_BIN_WIDTH(ctx->gmem.bin_w)); + A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w)); OUT_PKT3(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, CACHE_FLUSH); |