mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-14 06:30:26 +01:00
etnaviv: blt: Enable masked clear for color and stencil
This commit adds support for masked clear operations in the BLT path, allowing partial clears of specific color channels and stencil bits. For color clears, calculate which bits to clear based on the clear_mask by examining the format's channel layout. The clear_bits field is now set according to the mask instead of clearing all channels. For stencil clears, use the clear_mask parameter through to mask the stencil bits in the S8_UINT_Z24_UNORM format path, which was previously hardcoded to 0xff. Update etna_blt_will_fastclear() to check that clear_mask is 0xf (all channels) before allowing fast clear, since masked clears require the full clear path. Enable the clear_masked capability when BLT is available and the BLT_64bpp_MASKED_CLEAR_FIX cap is supported. Passes the following dEQPs: - dEQP-GLES2.functional.*_clear.*masked* - dEQP-GLES3.functional.*_clear.*masked* Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31512>
This commit is contained in:
parent
8d3945219d
commit
c156da579c
2 changed files with 43 additions and 12 deletions
|
|
@ -282,28 +282,49 @@ emit_blt_genmipmap(struct etna_cmd_stream *stream, const struct blt_genmipmap_op
|
|||
|
||||
static inline bool
|
||||
etna_blt_will_fastclear(const struct etna_resource_level *level,
|
||||
const struct pipe_scissor_state *scissor_state)
|
||||
const struct pipe_scissor_state *scissor_state,
|
||||
unsigned clear_mask,
|
||||
unsigned full_mask)
|
||||
{
|
||||
if (!scissor_state)
|
||||
return true;
|
||||
return clear_mask == full_mask;
|
||||
|
||||
return scissor_state->minx == 0 &&
|
||||
scissor_state->miny == 0 &&
|
||||
scissor_state->maxx >= level->width &&
|
||||
scissor_state->maxy >= level->height;
|
||||
scissor_state->maxy >= level->height &&
|
||||
clear_mask == full_mask;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
etna_calculate_clear_bits(enum pipe_format format, unsigned clear_mask)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
uint64_t clear_bits = 0;
|
||||
|
||||
for (unsigned i = 0; i < desc->nr_channels; i++) {
|
||||
if (clear_mask & (1 << desc->swizzle[i])) {
|
||||
const unsigned mask = (1 << desc->channel[i].size) - 1;
|
||||
clear_bits |= mask << desc->channel[i].shift;
|
||||
}
|
||||
}
|
||||
|
||||
return clear_bits;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_blit_clear_color_blt(struct pipe_context *pctx, unsigned idx,
|
||||
const union pipe_color_union *color,
|
||||
const struct pipe_scissor_state *scissor_state)
|
||||
const struct pipe_scissor_state *scissor_state,
|
||||
unsigned clear_mask)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct pipe_surface *dst = &ctx->framebuffer_s.cbufs[idx];
|
||||
struct etna_resource *dst_res = etna_resource_get_render_compatible(pctx, dst->texture);
|
||||
struct etna_resource_level *dst_level = &dst_res->levels[dst->level];
|
||||
uint64_t new_clear_value = etna_clear_blit_pack_rgba(dst->format, color);
|
||||
bool fast_clear = etna_blt_will_fastclear(dst_level, scissor_state);
|
||||
const uint64_t clear_bits = etna_calculate_clear_bits(dst->format, clear_mask);
|
||||
bool fast_clear = etna_blt_will_fastclear(dst_level, scissor_state, clear_mask, 0xf);
|
||||
int msaa_xscale = 1, msaa_yscale = 1;
|
||||
bool is_128bit_format = format_is_128bit(dst->format);
|
||||
|
||||
|
|
@ -334,8 +355,8 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, unsigned idx,
|
|||
|
||||
clr.clear_value[0] = new_clear_value;
|
||||
clr.clear_value[1] = new_clear_value >> 32;
|
||||
clr.clear_bits[0] = 0xffffffff; /* TODO: Might want to clear only specific channels? */
|
||||
clr.clear_bits[1] = 0xffffffff;
|
||||
clr.clear_bits[0] = clear_bits;
|
||||
clr.clear_bits[1] = clear_bits >> 32;
|
||||
|
||||
if (scissor_state) {
|
||||
clr.rect_x = scissor_state->minx * msaa_xscale;
|
||||
|
|
@ -390,13 +411,14 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, unsigned idx,
|
|||
static void
|
||||
etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
|
||||
unsigned buffers, double depth, unsigned stencil,
|
||||
const struct pipe_scissor_state *scissor_state)
|
||||
const struct pipe_scissor_state *scissor_state,
|
||||
unsigned clear_mask)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_resource *dst_res = etna_resource_get_render_compatible(pctx, dst->texture);
|
||||
struct etna_resource_level *dst_level = &dst_res->levels[dst->level];
|
||||
uint32_t new_clear_value = translate_clear_depth_stencil(dst->format, depth, stencil);
|
||||
bool fast_clear = etna_blt_will_fastclear(dst_level, scissor_state);
|
||||
bool fast_clear = etna_blt_will_fastclear(dst_level, scissor_state, clear_mask, 0xff);
|
||||
uint32_t new_clear_bits = 0, clear_bits_depth, clear_bits_stencil;
|
||||
int msaa_xscale = 1, msaa_yscale = 1;
|
||||
|
||||
|
|
@ -412,7 +434,7 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
break;
|
||||
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
|
||||
clear_bits_depth = 0xffffff00;
|
||||
clear_bits_stencil = 0x000000ff;
|
||||
clear_bits_stencil = clear_mask;
|
||||
break;
|
||||
default:
|
||||
clear_bits_depth = clear_bits_stencil = 0xffffffff;
|
||||
|
|
@ -478,6 +500,12 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
etna_resource_level_mark_changed(dst_level);
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
color_mask_for_buffer(unsigned mask, unsigned buffer)
|
||||
{
|
||||
return ((mask) >> (4 * (buffer))) & 0xf;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_clear_blt(struct pipe_context *pctx, unsigned buffers,
|
||||
uint32_t color_clear_mask, uint8_t stencil_clear_mask,
|
||||
|
|
@ -502,7 +530,8 @@ etna_clear_blt(struct pipe_context *pctx, unsigned buffers,
|
|||
if (!(buffers & (PIPE_CLEAR_COLOR0 << idx)))
|
||||
continue;
|
||||
|
||||
etna_blit_clear_color_blt(pctx, idx, color, scissor_state);
|
||||
etna_blit_clear_color_blt(pctx, idx, color, scissor_state,
|
||||
color_mask_for_buffer(color_clear_mask, idx));
|
||||
|
||||
if (!etna_resource(psurf->texture)->explicit_flush)
|
||||
etna_context_add_flush_resource(ctx, psurf->texture);
|
||||
|
|
@ -510,7 +539,7 @@ etna_clear_blt(struct pipe_context *pctx, unsigned buffers,
|
|||
}
|
||||
|
||||
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ctx->framebuffer_s.zsbuf.texture != NULL)
|
||||
etna_blit_clear_zs_blt(pctx, &ctx->framebuffer_s.zsbuf, buffers, depth, stencil, scissor_state);
|
||||
etna_blit_clear_zs_blt(pctx, &ctx->framebuffer_s.zsbuf, buffers, depth, stencil, scissor_state, stencil_clear_mask);
|
||||
|
||||
etna_stall(ctx->stream, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_BLT);
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ etna_init_screen_caps(struct etna_screen *screen)
|
|||
caps->fs_point_is_sysval = false;
|
||||
caps->generate_mipmap =
|
||||
caps->clear_scissored = screen->specs.use_blt;
|
||||
caps->clear_masked = screen->specs.use_blt &&
|
||||
VIV_FEATURE(screen, ETNA_FEATURE_BLT_64BPP_MASKED_CLEAR_FIX);
|
||||
|
||||
/* Memory */
|
||||
caps->constant_buffer_offset_alignment = 256;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue