diff options
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 40 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_gmem.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_gmem.h | 1 |
3 files changed, 35 insertions, 8 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index dde71ba97b9..72fe6f766f8 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); diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 80cf7c89c6f..2d4de442452 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -143,6 +143,8 @@ calculate_tiles(struct fd_context *ctx) gmem->bin_w = bin_w; gmem->nbins_x = nbins_x; gmem->nbins_y = nbins_y; + gmem->minx = minx; + gmem->miny = miny; gmem->width = width; gmem->height = height; diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.h b/src/gallium/drivers/freedreno/freedreno_gmem.h index b52557c952b..c7c687419b4 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.h +++ b/src/gallium/drivers/freedreno/freedreno_gmem.h @@ -50,6 +50,7 @@ struct fd_gmem_stateobj { uint cpp; uint16_t bin_h, nbins_y; uint16_t bin_w, nbins_x; + uint16_t minx, miny; uint16_t width, height; bool has_zs; /* gmem config using depth/stencil? */ }; |