shader: Always emit shader with alpha test support in core profile

This prevents shader recompilation when the guest wants to enable/disable
alpha test. Can make a performance difference when lots of fragment
shaders suddenly have to be recompiled only because the application
called `glEnable(GL_ALPHA_TEST)`.

Signed-off-by: Italo Nicola <italonicola@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Italo Nicola 3 years ago committed by Gert Wollny
parent 14b0e482ec
commit 2f054bd976
  1. 31
      src/vrend_renderer.c
  2. 73
      src/vrend_shader.c
  3. 2
      src/vrend_shader.h

@ -418,6 +418,7 @@ struct vrend_linked_shader_program {
GLint fs_stipple_loc; GLint fs_stipple_loc;
GLint fs_alpha_ref_val_loc; GLint fs_alpha_ref_val_loc;
GLint fs_alpha_func_loc;
GLuint clip_locs[8]; GLuint clip_locs[8];
@ -1741,10 +1742,15 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_sub_c
sprog->fs_stipple_loc = glGetUniformLocation(prog_id, "pstipple_sampler"); sprog->fs_stipple_loc = glGetUniformLocation(prog_id, "pstipple_sampler");
else else
sprog->fs_stipple_loc = -1; sprog->fs_stipple_loc = -1;
if (vrend_shader_needs_alpha_func(&fs->key))
sprog->fs_alpha_ref_val_loc = glGetUniformLocation(prog_id, "alpha_ref_val"); if (vrend_state.use_core_profile) {
else sprog->fs_alpha_ref_val_loc = glGetUniformLocation(prog_id, "alpha_ref_val");
sprog->fs_alpha_ref_val_loc = -1; sprog->fs_alpha_func_loc = glGetUniformLocation(prog_id, "alpha_func");
} else {
sprog->fs_alpha_ref_val_loc = -1;
sprog->fs_alpha_func_loc = -1;
}
sprog->vs_ws_adjust_loc = glGetUniformLocation(prog_id, "winsys_adjust_y"); sprog->vs_ws_adjust_loc = glGetUniformLocation(prog_id, "winsys_adjust_y");
vrend_use_program(sub_ctx, prog_id); vrend_use_program(sub_ctx, prog_id);
@ -3534,7 +3540,6 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx,
if (vrend_state.use_core_profile) { if (vrend_state.use_core_profile) {
int i; int i;
bool add_alpha_test = true;
// Only use integer info when drawing to avoid stale info. // Only use integer info when drawing to avoid stale info.
if (vrend_state.use_integer && sub_ctx->drawing && if (vrend_state.use_integer && sub_ctx->drawing &&
@ -3549,17 +3554,12 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx,
if (vrend_format_is_emulated_alpha(sub_ctx->surf[i]->format)) if (vrend_format_is_emulated_alpha(sub_ctx->surf[i]->format))
key->fs.cbufs_are_a8_bitmask |= (1 << i); key->fs.cbufs_are_a8_bitmask |= (1 << i);
if (util_format_is_pure_integer(sub_ctx->surf[i]->format)) { if (util_format_is_pure_integer(sub_ctx->surf[i]->format)) {
add_alpha_test = false;
UPDATE_INT_SIGN_MASK(sub_ctx->surf[i]->format, i, UPDATE_INT_SIGN_MASK(sub_ctx->surf[i]->format, i,
key->fs.cbufs_signed_int_bitmask, key->fs.cbufs_signed_int_bitmask,
key->fs.cbufs_unsigned_int_bitmask); key->fs.cbufs_unsigned_int_bitmask);
} }
key->fs.surface_component_bits[i] = util_format_get_component_bits(sub_ctx->surf[i]->format, UTIL_FORMAT_COLORSPACE_RGB, 0); key->fs.surface_component_bits[i] = util_format_get_component_bits(sub_ctx->surf[i]->format, UTIL_FORMAT_COLORSPACE_RGB, 0);
} }
if (add_alpha_test) {
key->add_alpha_test = sub_ctx->dsa_state.alpha.enabled;
key->alpha_test = sub_ctx->dsa_state.alpha.func;
}
} }
key->pstipple_tex = sub_ctx->rs_state.poly_stipple_enable; key->pstipple_tex = sub_ctx->rs_state.poly_stipple_enable;
@ -4625,7 +4625,16 @@ static void vrend_draw_bind_objects(struct vrend_sub_context *sub_ctx, bool new_
glUniform1i(sub_ctx->prog->fs_stipple_loc, next_sampler_id); glUniform1i(sub_ctx->prog->fs_stipple_loc, next_sampler_id);
} }
if (vrend_state.use_core_profile && sub_ctx->prog->fs_alpha_ref_val_loc != -1) { if (sub_ctx->prog->fs_alpha_ref_val_loc != -1) {
assert(sub_ctx->prog->fs_alpha_func_loc != -1);
/* If it's an integer format surface, alpha test shouldn't do anything. */
if (sub_ctx->dsa_state.alpha.enabled && sub_ctx->surf[0] &&
!util_format_is_pure_integer(sub_ctx->surf[0]->format))
glUniform1i(sub_ctx->prog->fs_alpha_func_loc, sub_ctx->dsa_state.alpha.func);
else
glUniform1i(sub_ctx->prog->fs_alpha_func_loc, PIPE_FUNC_ALWAYS);
glUniform1f(sub_ctx->prog->fs_alpha_ref_val_loc, sub_ctx->dsa_state.alpha.ref_value); glUniform1f(sub_ctx->prog->fs_alpha_ref_val_loc, sub_ctx->dsa_state.alpha.ref_value);
} }
} }

@ -259,6 +259,7 @@ struct dump_ctx {
int num_in_clip_dist; int num_in_clip_dist;
int num_out_clip_dist; int num_out_clip_dist;
int fs_uses_clipdist_input; int fs_uses_clipdist_input;
bool fs_has_color_outputs;
int glsl_ver_required; int glsl_ver_required;
int color_in_mask; int color_in_mask;
int color_out_mask; int color_out_mask;
@ -1403,6 +1404,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
ctx->key->fs.cbufs_unsigned_int_bitmask, ctx->key->fs.cbufs_unsigned_int_bitmask,
ctx->outputs[i].sid); ctx->outputs[i].sid);
name_prefix = ctx->key->fs.logicop_enabled ? "fsout_tmp" : "fsout"; name_prefix = ctx->key->fs.logicop_enabled ? "fsout_tmp" : "fsout";
ctx->fs_has_color_outputs = true;
} else { } else {
if (ctx->glsl_ver_required < 140) { if (ctx->glsl_ver_required < 140) {
ctx->outputs[i].glsl_no_index = true; ctx->outputs[i].glsl_no_index = true;
@ -1839,23 +1841,10 @@ static void emit_a8_swizzle(struct vrend_glsl_strbufs *glsl_strbufs)
emit_buf(glsl_strbufs, "fsout_c0.x = fsout_c0.w;\n"); emit_buf(glsl_strbufs, "fsout_c0.x = fsout_c0.w;\n");
} }
static const char *atests[PIPE_FUNC_ALWAYS + 1] = {
"false",
"<",
"==",
"<=",
">",
"!=",
">=",
"true"
};
static void emit_alpha_test(const struct dump_ctx *ctx, static void emit_alpha_test(const struct dump_ctx *ctx,
struct vrend_glsl_strbufs *glsl_strbufs) struct vrend_glsl_strbufs *glsl_strbufs)
{ {
char comp_buf[128]; if (!ctx->fs_has_color_outputs)
if (!ctx->num_outputs)
return; return;
if (!ctx->write_all_cbufs) { if (!ctx->write_all_cbufs) {
@ -1863,26 +1852,19 @@ static void emit_alpha_test(const struct dump_ctx *ctx,
if (ctx->outputs[0].sid != 0) if (ctx->outputs[0].sid != 0)
return; return;
} }
switch (ctx->key->alpha_test) {
case PIPE_FUNC_NEVER:
case PIPE_FUNC_ALWAYS:
snprintf(comp_buf, 128, "%s", atests[ctx->key->alpha_test]);
break;
case PIPE_FUNC_LESS:
case PIPE_FUNC_EQUAL:
case PIPE_FUNC_LEQUAL:
case PIPE_FUNC_GREATER:
case PIPE_FUNC_NOTEQUAL:
case PIPE_FUNC_GEQUAL:
snprintf(comp_buf, 128, "%s %s alpha_ref_val", "fsout_c0.w", atests[ctx->key->alpha_test]);
break;
default:
vrend_printf( "invalid alpha-test: %x\n", ctx->key->alpha_test);
set_buf_error(glsl_strbufs);
return;
}
emit_buff(glsl_strbufs, "if (!(%s)) {\n\tdiscard;\n}\n", comp_buf); emit_buff(glsl_strbufs, "if (alpha_func != 7 /* PIPE_FUNC_ALWAYS */) {\n"
" switch (alpha_func) {\n"
" case 0: discard; break;\n"
" case 1: if (!(fsout_c0.w < alpha_ref_val)) discard; break;\n"
" case 2: if (!(fsout_c0.w == alpha_ref_val)) discard; break;\n"
" case 3: if (!(fsout_c0.w <= alpha_ref_val)) discard; break;\n"
" case 4: if (!(fsout_c0.w > alpha_ref_val)) discard; break;\n"
" case 5: if (!(fsout_c0.w != alpha_ref_val)) discard; break;\n"
" case 6: if (!(fsout_c0.w >= alpha_ref_val)) discard; break;\n"
" default: break;\n"
" }\n"
"}\n");
} }
static void emit_pstipple_pass(struct vrend_glsl_strbufs *glsl_strbufs) static void emit_pstipple_pass(struct vrend_glsl_strbufs *glsl_strbufs)
@ -2340,9 +2322,8 @@ static void handle_fragment_proc_exit(const struct dump_ctx *ctx,
if (ctx->key->fs.cbufs_are_a8_bitmask) if (ctx->key->fs.cbufs_are_a8_bitmask)
emit_a8_swizzle(glsl_strbufs); emit_a8_swizzle(glsl_strbufs);
if (ctx->key->add_alpha_test) if (ctx->cfg->use_core_profile)
emit_alpha_test(ctx, glsl_strbufs); emit_alpha_test(ctx, glsl_strbufs);
if (ctx->key->fs.logicop_enabled) if (ctx->key->fs.logicop_enabled)
emit_fragment_logicop(ctx, glsl_strbufs); emit_fragment_logicop(ctx, glsl_strbufs);
@ -6653,8 +6634,9 @@ static void emit_ios_fs(const struct dump_ctx *ctx,
} }
} }
if (vrend_shader_needs_alpha_func(ctx->key)) { if (ctx->cfg->use_core_profile) {
emit_hdr(glsl_strbufs, "uniform float alpha_ref_val;\n"); emit_hdr(glsl_strbufs, "uniform float alpha_ref_val;\n");
emit_hdr(glsl_strbufs, "uniform int alpha_func;\n");
} }
if (ctx->key->color_two_side) { if (ctx->key->color_two_side) {
@ -7733,18 +7715,3 @@ fail:
return false; return false;
} }
bool vrend_shader_needs_alpha_func(const struct vrend_shader_key *key) {
if (!key->add_alpha_test)
return false;
switch (key->alpha_test) {
default:
return false;
case PIPE_FUNC_LESS:
case PIPE_FUNC_EQUAL:
case PIPE_FUNC_LEQUAL:
case PIPE_FUNC_GREATER:
case PIPE_FUNC_NOTEQUAL:
case PIPE_FUNC_GEQUAL:
return true;
}
}

@ -178,14 +178,12 @@ struct vrend_shader_key {
uint32_t sampler_views_lower_swizzle_mask; uint32_t sampler_views_lower_swizzle_mask;
uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS]; uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS];
uint8_t alpha_test;
uint8_t clip_plane_enable; uint8_t clip_plane_enable;
uint8_t num_in_cull : 4; uint8_t num_in_cull : 4;
uint8_t num_in_clip : 4; uint8_t num_in_clip : 4;
uint8_t num_out_cull : 4; uint8_t num_out_cull : 4;
uint8_t num_out_clip : 4; uint8_t num_out_clip : 4;
uint8_t pstipple_tex : 1; uint8_t pstipple_tex : 1;
uint8_t add_alpha_test : 1;
uint8_t color_two_side : 1; uint8_t color_two_side : 1;
uint8_t gs_present : 1; uint8_t gs_present : 1;
uint8_t tcs_present : 1; uint8_t tcs_present : 1;

Loading…
Cancel
Save