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);
}
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);
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) |
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);