freedreno/a6xx: Push RB_A2D_PIXEL_CNTL magic into blitter

This is about partial (only z or only s) z24s8 blits.  Just push the
buffers mask down to blitter to consolidate the magic.

Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42089>
This commit is contained in:
Rob Clark 2026-05-07 11:11:47 -07:00 committed by Marge Bot
parent 301a1f9a61
commit 88210dfcf5
3 changed files with 45 additions and 39 deletions

View file

@ -297,7 +297,8 @@ template <chip CHIP>
static void
emit_blit_setup(fd_ncrb<CHIP> &ncrb, enum pipe_format pfmt,
bool scissor_enable, union pipe_color_union *color,
uint32_t unknown_8c01, enum a6xx_rotation rotate)
BITMASK_ENUM(fd_buffer_mask) buffers,
enum a6xx_rotation rotate)
{
enum a6xx_format fmt = fd6_color_format(pfmt, TILE6_LINEAR);
bool is_srgb = util_format_is_srgb(pfmt);
@ -347,7 +348,19 @@ emit_blit_setup(fd_ncrb<CHIP> &ncrb, enum pipe_format pfmt,
.mask = 0xf,
));
ncrb.add(A6XX_RB_A2D_PIXEL_CNTL(.dword = unknown_8c01));
/* Handle D24S8 blits where we are only updating depth or stencil: */
if (pfmt == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
buffers &= FD_BUFFER_DEPTH | FD_BUFFER_STENCIL;
if (buffers == FD_BUFFER_DEPTH) {
ncrb.add(A6XX_RB_A2D_PIXEL_CNTL(.dword = 0x08000041));
} else if (buffers == FD_BUFFER_STENCIL) {
ncrb.add(A6XX_RB_A2D_PIXEL_CNTL(.dword = 0x00084001));
} else {
ncrb.add(A6XX_RB_A2D_PIXEL_CNTL());
}
} else {
ncrb.add(A6XX_RB_A2D_PIXEL_CNTL());
}
}
/* nregs: 4 */
@ -421,7 +434,8 @@ emit_blit_buffer(struct fd_context *ctx, fd_cs &cs, const struct pipe_blit_info
dshift = dbox->x & 0x3f;
with_ncrb (cs, 5)
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_R8_UNORM, false, NULL, 0, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_R8_UNORM, false, NULL,
FD_BUFFER_ALL, ROTATE_0);
for (unsigned off = 0; off < sbox->width; off += (0x4000 - 0x40)) {
unsigned soff, doff, w, p;
@ -484,7 +498,8 @@ clear_ubwc_setup(fd_cs &cs)
union pipe_color_union color = {};
fd_ncrb<CHIP> ncrb(cs, 18);
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_R8_UNORM, false, &color, 0, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_R8_UNORM, false, &color,
FD_BUFFER_ALL, ROTATE_0);
ncrb.add(TPL1_A2D_SRC_TEXTURE_INFO(CHIP));
ncrb.add(TPL1_A2D_SRC_TEXTURE_SIZE(CHIP));
@ -707,7 +722,8 @@ emit_blit_texture_setup(fd_cs &cs, const struct pipe_blit_info *info)
));
}
emit_blit_setup<CHIP>(ncrb, info->dst.format, info->scissor_enable, NULL, 0, rotate);
emit_blit_setup<CHIP>(ncrb, info->dst.format, info->scissor_enable, NULL,
FD_BUFFER_ALL, rotate);
}
template <chip CHIP>
@ -818,7 +834,8 @@ clear_lrz_setup(fd_cs &cs, struct fd_resource *zsbuf, struct fd_bo *lrz, double
union pipe_color_union clear_color = { .f = {depth} };
emit_clear_color<CHIP>(ncrb, PIPE_FORMAT_Z16_UNORM, &clear_color);
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_Z16_UNORM, false, &clear_color, 0, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, PIPE_FORMAT_Z16_UNORM, false, &clear_color,
FD_BUFFER_ALL, ROTATE_0);
ncrb.add(A6XX_RB_A2D_DEST_BUFFER_INFO(
.color_format = FMT6_16_UNORM,
@ -973,7 +990,8 @@ fd6_clear_buffer(struct pipe_context *pctx,
with_ncrb (cs, 9) {
emit_clear_color(ncrb, dst_fmt, &color);
emit_blit_setup<CHIP>(ncrb, dst_fmt, false, &color, 0, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, dst_fmt, false, &color,
FD_BUFFER_ALL, ROTATE_0);
}
/*
@ -1028,7 +1046,7 @@ template <chip CHIP>
static void
clear_surface_setup(fd_cs &cs, struct pipe_surface *psurf,
const struct pipe_box *box2d, union pipe_color_union *color,
uint32_t unknown_8c01)
BITMASK_ENUM(fd_buffer_mask) buffers)
{
uint32_t nr_samples = fd_resource_nr_samples(psurf->texture);
fd_ncrb<CHIP> ncrb(cs, 11);
@ -1045,14 +1063,15 @@ clear_surface_setup(fd_cs &cs, struct pipe_surface *psurf,
union pipe_color_union clear_color = convert_color(psurf->format, color);
emit_clear_color(ncrb, psurf->format, &clear_color);
emit_blit_setup<CHIP>(ncrb, psurf->format, false, &clear_color, unknown_8c01, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, psurf->format, false, &clear_color, buffers, ROTATE_0);
}
template <chip CHIP>
void
fd6_clear_surface(struct fd_context *ctx, fd_cs &cs,
struct pipe_surface *psurf, const struct pipe_box *box2d,
union pipe_color_union *color, uint32_t unknown_8c01)
union pipe_color_union *color,
BITMASK_ENUM(fd_buffer_mask) buffers)
{
if (DEBUG_BLIT) {
fprintf(stderr, "surface clear:\ndst resource: ");
@ -1060,7 +1079,7 @@ fd6_clear_surface(struct fd_context *ctx, fd_cs &cs,
fprintf(stderr, "\n");
}
clear_surface_setup<CHIP>(cs, psurf, box2d, color, unknown_8c01);
clear_surface_setup<CHIP>(cs, psurf, box2d, color, buffers);
for (unsigned i = psurf->first_layer; i <= psurf->last_layer; i++) {
with_ncrb (cs, 10)
@ -1142,7 +1161,7 @@ fd6_clear_texture(struct pipe_context *pctx, struct pipe_resource *prsc,
.texture = prsc,
};
fd6_clear_surface<CHIP>(ctx, cs, &surf, box, &color, 0);
fd6_clear_surface<CHIP>(ctx, cs, &surf, box, &color, FD_BUFFER_ALL);
fd6_emit_flushes<CHIP>(batch->ctx, cs,
FD6_FLUSH_CCU_COLOR |
@ -1162,7 +1181,8 @@ fd6_clear_texture(struct pipe_context *pctx, struct pipe_resource *prsc,
template <chip CHIP>
static void
resolve_tile_setup(struct fd_batch *batch, fd_cs &cs, uint32_t base,
struct pipe_surface *psurf, uint32_t unknown_8c01)
struct pipe_surface *psurf,
BITMASK_ENUM(fd_buffer_mask) buffers)
{
const struct fd_gmem_stateobj *gmem = batch->gmem_state;
uint32_t gmem_pitch = gmem->bin_w * batch->framebuffer.samples *
@ -1182,7 +1202,7 @@ resolve_tile_setup(struct fd_batch *batch, fd_cs &cs, uint32_t base,
/* Enable scissor bit, which will take into account the window scissor
* which is set per-tile
*/
emit_blit_setup<CHIP>(ncrb, psurf->format, true, NULL, unknown_8c01, ROTATE_0);
emit_blit_setup<CHIP>(ncrb, psurf->format, true, NULL, buffers, ROTATE_0);
/* We shouldn't be using GMEM in the layered rendering case: */
assert(psurf->first_layer == psurf->last_layer);
@ -1219,9 +1239,10 @@ resolve_tile_setup(struct fd_batch *batch, fd_cs &cs, uint32_t base,
template <chip CHIP>
void
fd6_resolve_tile(struct fd_batch *batch, fd_cs &cs, uint32_t base,
struct pipe_surface *psurf, uint32_t unknown_8c01)
struct pipe_surface *psurf,
BITMASK_ENUM(fd_buffer_mask) buffers)
{
resolve_tile_setup<CHIP>(batch, cs, base, psurf, unknown_8c01);
resolve_tile_setup<CHIP>(batch, cs, base, psurf, buffers);
/* sync GMEM writes with CACHE. */
fd6_cache_inv<CHIP>(batch->ctx, cs);

View file

@ -32,9 +32,11 @@ void fd6_clear_lrz(fd_cs &cs, struct fd_resource *zsbuf,
template <chip CHIP>
void fd6_clear_surface(struct fd_context *ctx, fd_cs &cs,
struct pipe_surface *psurf, const struct pipe_box *box2d,
union pipe_color_union *color, uint32_t unknown_8c01) assert_dt;
union pipe_color_union *color,
BITMASK_ENUM(fd_buffer_mask) buffers) assert_dt;
template <chip CHIP>
void fd6_resolve_tile(struct fd_batch *batch, fd_cs &cs, uint32_t base,
struct pipe_surface *psurf, uint32_t unknown_8c01) assert_dt;
struct pipe_surface *psurf,
BITMASK_ENUM(fd_buffer_mask) buffers) assert_dt;
#endif /* FD6_BLIT_H_ */

View file

@ -1830,23 +1830,6 @@ needs_resolve(struct pipe_surface *psurf)
(psurf->nr_samples != psurf->texture->nr_samples);
}
/**
* Returns the UNKNOWN_8C01 value for handling partial depth/stencil
* clear/stores to Z24S8.
*/
static uint32_t
fd6_unknown_8c01(enum pipe_format format, unsigned buffers)
{
buffers &= FD_BUFFER_DEPTH | FD_BUFFER_STENCIL;
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
if (buffers == FD_BUFFER_DEPTH)
return 0x08000041;
else if (buffers == FD_BUFFER_STENCIL)
return 0x00084001;
}
return 0;
}
template <chip CHIP>
static void
emit_resolve_blit(struct fd_batch *batch, fd_cs &cs,
@ -1867,12 +1850,12 @@ emit_resolve_blit(struct fd_batch *batch, fd_cs &cs,
*/
if (needs_resolve(psurf) && !blit_can_resolve(psurf->format) &&
(buffer != FD_BUFFER_STENCIL)) {
/* We could potentially use fd6_unknown_8c01() to handle partial z/s
/* We could potentially use RB_A2D_PIXEL_CNTL to handle partial z/s
* resolve to packed z/s, but we would need a corresponding ability in the
* !resolve case below, so batch_draw_tracking_for_dirty_bits() has us
* just do a restore of the other channel for partial packed z/s writes.
*/
fd6_resolve_tile<CHIP>(batch, cs, base, psurf, 0);
fd6_resolve_tile<CHIP>(batch, cs, base, psurf, FD_BUFFER_ALL);
return;
}
@ -2064,7 +2047,7 @@ emit_sysmem_clears(fd_cs &cs, struct fd_batch *batch, struct fd_batch_subpass *s
value.f[0] = subpass->clear_depth;
value.ui[1] = subpass->clear_stencil;
fd6_clear_surface<CHIP>(ctx, cs, &pfb->zsbuf, &box2d,
&value, fd6_unknown_8c01(pfb->zsbuf.format, buffers));
&value, buffers);
}
if (separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) {
@ -2074,7 +2057,7 @@ emit_sysmem_clears(fd_cs &cs, struct fd_batch *batch, struct fd_batch_subpass *s
stencil_surf.format = PIPE_FORMAT_S8_UINT;
stencil_surf.texture = separate_stencil;
fd6_clear_surface<CHIP>(ctx, cs, &stencil_surf, &box2d, &value, 0);
fd6_clear_surface<CHIP>(ctx, cs, &stencil_surf, &box2d, &value, buffers);
}
}