}
}
+static void
+fd6_clear_ubwc(struct fd_batch *batch, struct fd_resource *rsc)
+{
+ struct fd_ringbuffer *ring = fd_batch_get_prologue(batch);
+ union pipe_color_union color = {};
+
+ emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, &color);
+
+ OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT4(ring, REG_A6XX_RB_2D_SRC_SOLID_C0, 4);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+
+ OUT_PKT4(ring, REG_A6XX_GRAS_2D_SRC_TL_X, 4);
+ OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_X(0));
+ OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_X(0));
+ OUT_RING(ring, A6XX_GRAS_2D_SRC_TL_Y(0));
+ OUT_RING(ring, A6XX_GRAS_2D_SRC_BR_Y(0));
+
+ unsigned size = rsc->layout.slices[0].offset;
+ unsigned offset = 0;
+
+ /* We could be more clever here and realize that we could use a
+ * larger width if the size is aligned to something more than a
+ * single page.. or even use a format larger than r8 in those
+ * cases. But for normal sized textures and even up to 16k x 16k
+ * at <= 4byte/pixel, we'll only go thru the loop once
+ */
+ const unsigned w = 0x1000;
+
+ /* ubwc size should always be page aligned: */
+ assert((size % w) == 0);
+
+ while (size > 0) {
+ const unsigned h = MIN2(0x4000, size / w);
+ /* width is already aligned to a suitable pitch: */
+ const unsigned p = w;
+
+ /*
+ * Emit destination:
+ */
+ OUT_PKT4(ring, REG_A6XX_RB_2D_DST_INFO, 9);
+ OUT_RING(ring, A6XX_RB_2D_DST_INFO_COLOR_FORMAT(FMT6_8_UNORM) |
+ A6XX_RB_2D_DST_INFO_TILE_MODE(TILE6_LINEAR) |
+ A6XX_RB_2D_DST_INFO_COLOR_SWAP(WZYX));
+ OUT_RELOC(ring, rsc->bo, offset, 0, 0); /* RB_2D_DST_LO/HI */
+ OUT_RING(ring, A6XX_RB_2D_DST_PITCH(p));
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+ OUT_RING(ring, 0x00000000);
+
+ /*
+ * Blit command:
+ */
+
+ OUT_PKT4(ring, REG_A6XX_GRAS_2D_DST_TL, 2);
+ OUT_RING(ring, A6XX_GRAS_2D_DST_TL_X(0) | A6XX_GRAS_2D_DST_TL_Y(0));
+ OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(w - 1) | A6XX_GRAS_2D_DST_BR_Y(h - 1));
+
+ OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+ OUT_RING(ring, 0x3f);
+ OUT_WFI5(ring);
+
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
+ OUT_RING(ring, fd6_context(batch->ctx)->magic.RB_UNKNOWN_8E04_blit);
+
+ OUT_PKT7(ring, CP_BLIT, 1);
+ OUT_RING(ring, CP_BLIT_0_OP(BLIT_OP_SCALE));
+
+ OUT_WFI5(ring);
+
+ OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_8E04, 1);
+ OUT_RING(ring, 0); /* RB_UNKNOWN_8E04 */
+
+ offset += w * h;
+ size -= w * h;
+ }
+
+ fd6_event_write(batch, ring, PC_CCU_FLUSH_COLOR_TS, true);
+ fd6_event_write(batch, ring, PC_CCU_FLUSH_DEPTH_TS, true);
+ fd6_event_write(batch, ring, CACHE_FLUSH_TS, true);
+ fd6_cache_inv(batch, ring);
+}
+
static void
emit_blit_dst(struct fd_ringbuffer *ring, struct pipe_resource *prsc, enum pipe_format pfmt, unsigned level, unsigned layer)
{
void
fd6_blitter_init(struct pipe_context *pctx)
{
+ fd_context(pctx)->clear_ubwc = fd6_clear_ubwc;
+
if (fd_mesa_debug & FD_DBG_NOBLIT)
return;