summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_gmem.c40
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.c2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.h1
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? */
};