gallium/u_blitter: remove UTIL_BLITTER_ATTRIB_COLOR, use a constant buffer

Pass the clear color via a constant buffer instead of a FS input.
This results in less driver code and it could be faster on some GPUs.

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33837>
This commit is contained in:
Marek Olšák 2025-03-02 11:04:47 -05:00 committed by Marge Bot
parent 99b5970eb2
commit ca09c173f6
16 changed files with 50 additions and 114 deletions

View file

@ -75,8 +75,7 @@ struct blitter_context_priv
/* Fragment shaders. */
void *fs_empty;
void *fs_write_one_cbuf;
void *fs_clear_all_cbufs;
void *fs_clear_color[2];
/* FS which outputs a color from a texture where
* the 1st index indicates the texture type / destination type,
@ -450,30 +449,18 @@ static void bind_fs_empty(struct blitter_context_priv *ctx)
ctx->bind_fs_state(pipe, ctx->fs_empty);
}
static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx)
static void bind_fs_clear_color(struct blitter_context_priv *ctx,
bool write_all_cbufs)
{
struct pipe_context *pipe = ctx->base.pipe;
if (!ctx->fs_write_one_cbuf) {
if (!ctx->fs_clear_color[write_all_cbufs]) {
assert(!ctx->cached_all_shaders);
ctx->fs_write_one_cbuf =
util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
TGSI_INTERPOLATE_CONSTANT, false);
ctx->fs_clear_color[write_all_cbufs] =
util_make_fs_clear_color(pipe, write_all_cbufs);
}
ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
}
static void bind_fs_clear_all_cbufs(struct blitter_context_priv *ctx)
{
struct pipe_context *pipe = ctx->base.pipe;
if (!ctx->fs_clear_all_cbufs) {
assert(!ctx->cached_all_shaders);
ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
}
ctx->bind_fs_state(pipe, ctx->fs_clear_all_cbufs);
ctx->bind_fs_state(pipe, ctx->fs_clear_color[write_all_cbufs]);
}
void util_blitter_destroy(struct blitter_context *blitter)
@ -569,10 +556,11 @@ void util_blitter_destroy(struct blitter_context *blitter)
if (ctx->fs_empty)
ctx->delete_fs_state(pipe, ctx->fs_empty);
if (ctx->fs_write_one_cbuf)
ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
if (ctx->fs_clear_all_cbufs)
ctx->delete_fs_state(pipe, ctx->fs_clear_all_cbufs);
for (i = 0; i < ARRAY_SIZE(ctx->fs_clear_color); i++) {
if (ctx->fs_clear_color[i])
ctx->delete_fs_state(pipe, ctx->fs_clear_color[i]);
}
for (i = 0; i < ARRAY_SIZE(ctx->fs_stencil_blit_fallback); ++i)
if (ctx->fs_stencil_blit_fallback[i])
@ -863,20 +851,6 @@ static void blitter_set_rectangle(struct blitter_context_priv *ctx,
ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport);
}
static void blitter_set_clear_color(struct blitter_context_priv *ctx,
const float color[4])
{
int i;
if (color) {
for (i = 0; i < 4; i++)
memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
} else {
for (i = 0; i < 4; i++)
memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
}
}
static void get_texcoords(struct pipe_sampler_view *src,
unsigned src_width0, unsigned src_height0,
int x1, int y1, int x2, int y2,
@ -1354,11 +1328,8 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
ctx->fs_empty = util_make_empty_fragment_shader(pipe);
ctx->fs_write_one_cbuf =
util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
TGSI_INTERPOLATE_CONSTANT, false);
ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
ctx->fs_clear_color[0] = util_make_fs_clear_color(pipe, false);
ctx->fs_clear_color[1] = util_make_fs_clear_color(pipe, true);
ctx->cached_all_shaders = true;
}
@ -1431,10 +1402,6 @@ void util_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned i;
switch (type) {
case UTIL_BLITTER_ATTRIB_COLOR:
blitter_set_clear_color(ctx, attrib->color);
break;
case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
for (i = 0; i < 4; i++) {
ctx->vertices[i][1][2] = attrib->texcoord.z;
@ -1565,7 +1532,7 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
};
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
false, &cb);
bind_fs_clear_all_cbufs(ctx);
bind_fs_clear_color(ctx, true);
} else {
bind_fs_empty(ctx);
}
@ -2408,7 +2375,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
/* bind states */
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
bind_fs_write_one_cbuf(ctx);
bind_fs_clear_color(ctx, false);
/* set a framebuffer state */
fb_state.width = dstsurf->width;
@ -2426,8 +2393,12 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter_set_common_draw_rect_state(ctx, false, msaa);
union blitter_attrib attrib;
memcpy(attrib.color, color->ui, sizeof(color->ui));
struct pipe_constant_buffer cb = {
.user_buffer = color->f,
.buffer_size = 4 * sizeof(float),
};
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
false, &cb);
num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
@ -2440,10 +2411,11 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
dstx, dsty, dstx+width, dsty+height, 0,
num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
util_blitter_restore_vertex_states(blitter);
util_blitter_restore_fragment_states(blitter);
util_blitter_restore_constant_buffer_state(blitter);
util_blitter_restore_fb_state(blitter);
util_blitter_restore_render_cond(blitter);
util_blitter_unset_running_flag(blitter);
@ -2558,7 +2530,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
ctx->blend[0][0]);
pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
if (cbsurf)
bind_fs_write_one_cbuf(ctx);
bind_fs_clear_color(ctx, false);
else
bind_fs_empty(ctx);
@ -2685,7 +2657,7 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter,
/* bind states */
pipe->bind_blend_state(pipe, custom_blend);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
bind_fs_write_one_cbuf(ctx);
bind_fs_clear_color(ctx, false);
pipe->set_sample_mask(pipe, sample_mask);
if (pipe->set_min_samples)
pipe->set_min_samples(pipe, 1);
@ -2753,7 +2725,7 @@ void util_blitter_custom_color(struct blitter_context *blitter,
pipe->bind_blend_state(pipe, custom_blend ? custom_blend
: ctx->blend[PIPE_MASK_RGBA][0]);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
bind_fs_write_one_cbuf(ctx);
bind_fs_clear_color(ctx, false);
/* set a framebuffer state */
fb_state.width = dstsurf->width;

View file

@ -40,14 +40,11 @@ struct pipe_context;
enum blitter_attrib_type {
UTIL_BLITTER_ATTRIB_NONE,
UTIL_BLITTER_ATTRIB_COLOR,
UTIL_BLITTER_ATTRIB_TEXCOORD_XY,
UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
};
union blitter_attrib {
float color[4];
struct {
float x1, y1, x2, y2, z, w;
} texcoord;

View file

@ -1313,16 +1313,19 @@ util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src, bool has_txq
}
void *
util_make_fs_clear_all_cbufs(struct pipe_context *pipe)
util_make_fs_clear_color(struct pipe_context *pipe, bool write_all_cbufs)
{
static const char text[] =
static const char text_templ[] =
"FRAG\n"
"PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n"
"PROPERTY FS_COLOR0_WRITES_ALL_CBUFS %u\n"
"DCL OUT[0], COLOR[0]\n"
"DCL CONST[0][0]\n"
"MOV OUT[0], CONST[0][0]\n"
"END\n";
char text[1000];
snprintf(text, ARRAY_SIZE(text), text_templ, write_all_cbufs);
struct tgsi_token tokens[1000];
struct pipe_shader_state state = { 0 };

View file

@ -161,7 +161,7 @@ void *
util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src, bool has_txq);
void *
util_make_fs_clear_all_cbufs(struct pipe_context *pipe);
util_make_fs_clear_color(struct pipe_context *pipe, bool write_all_cbufs);
#ifdef __cplusplus
}

View file

@ -85,7 +85,7 @@ panfrost_clear_render_target(struct pipe_context *pipe,
return;
panfrost_blitter_save(
ctx, render_condition_enabled ? PAN_RENDER_COND : PAN_RENDER_BASE);
ctx, (render_condition_enabled ? PAN_RENDER_COND : PAN_RENDER_BASE) | PAN_SAVE_FRAGMENT_CONSTANT);
util_blitter_clear_render_target(ctx->blitter, dst, color, dstx, dsty, width,
height);
}

View file

@ -1161,11 +1161,9 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned last_is_point = r300->is_point;
unsigned width = x2 - x1;
unsigned height = y2 - y1;
unsigned vertex_size =
type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
unsigned vertex_size = !r300->draw ? 8 : 4;
unsigned dwords = 13 + vertex_size +
(type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY ? 7 : 0);
static const union blitter_attrib zeros;
CS_LOCALS(r300);
/* XXX workaround for a lockup in MSAA resolve on SWTCL chipsets, this
@ -1234,9 +1232,8 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
OUT_CS_32F(1);
if (vertex_size == 8) {
if (!attrib)
attrib = &zeros;
OUT_CS_TABLE(attrib->color, 4);
static const float zeros[4];
OUT_CS_TABLE(zeros, 4);
}
END_CS;

View file

@ -20,7 +20,7 @@ enum r600_blitter_op /* bitmask */
R600_CLEAR = R600_SAVE_FRAGMENT_STATE | R600_SAVE_CONST_BUF0,
R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER,
R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_SAVE_CONST_BUF0,
R600_COPY_BUFFER = R600_DISABLE_RENDER_COND,

View file

@ -163,11 +163,6 @@ void r600_draw_rectangle(struct blitter_context *blitter,
vb[19] = 1;
switch (type) {
case UTIL_BLITTER_ATTRIB_COLOR:
memcpy(vb+4, attrib->color, sizeof(float)*4);
memcpy(vb+12, attrib->color, sizeof(float)*4);
memcpy(vb+20, attrib->color, sizeof(float)*4);
break;
case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
vb[6] = vb[14] = vb[22] = attrib->texcoord.z;

View file

@ -13,7 +13,7 @@
enum {
SI_CLEAR = SI_SAVE_FRAGMENT_STATE | SI_SAVE_FRAGMENT_CONSTANT,
SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE,
SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE | SI_SAVE_FRAGMENT_CONSTANT,
};
void si_init_buffer_clear(struct si_clear_info *info,

View file

@ -132,22 +132,17 @@ load_vs_input_from_blit_sgpr(nir_builder *b, unsigned input_index,
assert(input_index == 1);
unsigned vs_blit_property = b->shader->info.vs.blit_sgprs_amd;
if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_COLOR + has_attribute_ring_address) {
for (int i = 0; i < 4; i++)
out[i] = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 3 + i);
} else {
assert(vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD + has_attribute_ring_address);
assert(vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD + has_attribute_ring_address);
nir_def *x1 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 3);
nir_def *y1 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 4);
nir_def *x2 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 5);
nir_def *y2 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 6);
nir_def *x1 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 3);
nir_def *y1 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 4);
nir_def *x2 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 5);
nir_def *y2 = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 6);
out[0] = nir_bcsel(b, sel_x1, x1, x2);
out[1] = nir_bcsel(b, sel_y1, y1, y2);
out[2] = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 7);
out[3] = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 8);
}
out[0] = nir_bcsel(b, sel_x1, x1, x2);
out[1] = nir_bcsel(b, sel_y1, y1, y2);
out[2] = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 7);
out[3] = ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vs_blit_inputs, 8);
}
}

View file

@ -251,10 +251,6 @@ static void si_destroy_context(struct pipe_context *context)
sctx->b.delete_vs_state(&sctx->b, sctx->vs_blit_pos);
if (sctx->vs_blit_pos_layered)
sctx->b.delete_vs_state(&sctx->b, sctx->vs_blit_pos_layered);
if (sctx->vs_blit_color)
sctx->b.delete_vs_state(&sctx->b, sctx->vs_blit_color);
if (sctx->vs_blit_color_layered)
sctx->b.delete_vs_state(&sctx->b, sctx->vs_blit_color_layered);
if (sctx->vs_blit_texcoord)
sctx->b.delete_vs_state(&sctx->b, sctx->vs_blit_texcoord);
if (sctx->cs_clear_buffer_rmw)

View file

@ -973,8 +973,6 @@ struct si_context {
void *custom_blend_dcc_decompress;
void *vs_blit_pos;
void *vs_blit_pos_layered;
void *vs_blit_color;
void *vs_blit_color_layered;
void *vs_blit_texcoord;
void *cs_clear_buffer_rmw;
void *cs_ubyte_to_ushort;

View file

@ -294,15 +294,7 @@ static void declare_vs_blit_inputs(struct si_shader *shader, struct si_shader_ar
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* depth */
if (info->vs.blit_sgprs_amd ==
SI_VS_BLIT_SGPRS_POS_COLOR + has_attribute_ring_address) {
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* color0 */
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* color1 */
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* color2 */
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* color3 */
if (has_attribute_ring_address)
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, NULL); /* attribute ring address */
} else if (info->vs.blit_sgprs_amd ==
SI_VS_BLIT_SGPRS_POS_TEXCOORD + has_attribute_ring_address) {
SI_VS_BLIT_SGPRS_POS_TEXCOORD + has_attribute_ring_address) {
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* texcoord.x1 */
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* texcoord.y1 */
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_FLOAT, NULL); /* texcoord.x2 */

View file

@ -326,7 +326,6 @@ enum
{
/* These represent the number of SGPRs the shader uses. */
SI_VS_BLIT_SGPRS_POS = 3,
SI_VS_BLIT_SGPRS_POS_COLOR = 7,
SI_VS_BLIT_SGPRS_POS_TEXCOORD = 9,
MAX_SI_VS_BLIT_SGPRS = 10, /* +1 for the attribute ring address */

View file

@ -300,10 +300,6 @@ void *si_get_blitter_vs(struct si_context *sctx, enum blitter_attrib_type type,
vs = num_layers > 1 ? &sctx->vs_blit_pos_layered : &sctx->vs_blit_pos;
vs_blit_property = SI_VS_BLIT_SGPRS_POS;
break;
case UTIL_BLITTER_ATTRIB_COLOR:
vs = num_layers > 1 ? &sctx->vs_blit_color_layered : &sctx->vs_blit_color;
vs_blit_property = SI_VS_BLIT_SGPRS_POS_COLOR;
break;
case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
assert(num_layers == 1);

View file

@ -2498,10 +2498,6 @@ static void si_draw_rectangle(struct blitter_context *blitter, void *vertex_elem
sctx->vs_blit_sh_data[2] = fui(depth);
switch (type) {
case UTIL_BLITTER_ATTRIB_COLOR:
memcpy(&sctx->vs_blit_sh_data[3], attrib->color, sizeof(float) * 4);
sctx->vs_blit_sh_data[7] = attribute_ring_address_lo;
break;
case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
memcpy(&sctx->vs_blit_sh_data[3], &attrib->texcoord, sizeof(attrib->texcoord));