mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 20:00:11 +01:00
radeonsi: kill Z and stencil PS outputs if depth or stencil is disabled
This adds kill_z and kill_stencil flags to the shader PS epilog key, which removes those outputs if depth or stencil are disabled. It must be implemented in: * ACO PS epilog * LLVM PS epilog * ac_nir_lower_ps for monolithic shaders Some of the samplemask code wasn't completely correct, but probably harmless. Reviewed-by: Qiang Yu <yuq825@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32713>
This commit is contained in:
parent
0beeb16e41
commit
de996ac481
12 changed files with 105 additions and 50 deletions
|
|
@ -286,9 +286,11 @@ typedef struct {
|
|||
/* OpenGL only */
|
||||
bool clamp_color;
|
||||
bool alpha_to_one;
|
||||
bool kill_samplemask;
|
||||
enum compare_func alpha_func;
|
||||
unsigned broadcast_last_cbuf;
|
||||
bool kill_z;
|
||||
bool kill_stencil;
|
||||
bool kill_samplemask;
|
||||
|
||||
/* Vulkan only */
|
||||
unsigned enable_mrt_output_nan_fixup;
|
||||
|
|
|
|||
|
|
@ -215,11 +215,13 @@ gather_ps_store_output(nir_builder *b, nir_intrinsic_instr *intrin, lower_ps_sta
|
|||
switch (slot) {
|
||||
case FRAG_RESULT_DEPTH:
|
||||
assert(comp == 0);
|
||||
s->depth = chan;
|
||||
if (!s->options->kill_z)
|
||||
s->depth = chan;
|
||||
break;
|
||||
case FRAG_RESULT_STENCIL:
|
||||
assert(comp == 0);
|
||||
s->stencil = chan;
|
||||
if (!s->options->kill_stencil)
|
||||
s->stencil = chan;
|
||||
break;
|
||||
case FRAG_RESULT_SAMPLE_MASK:
|
||||
assert(comp == 0);
|
||||
|
|
|
|||
|
|
@ -13540,9 +13540,9 @@ select_ps_epilog(Program* program, void* pinfo, ac_shader_config* config,
|
|||
emit_clamp_alpha_test(&ctx, einfo, colors[i], i);
|
||||
}
|
||||
|
||||
bool has_mrtz_depth = einfo->depth.used;
|
||||
bool has_mrtz_stencil = einfo->stencil.used;
|
||||
bool has_mrtz_samplemask = einfo->samplemask.used;
|
||||
bool has_mrtz_depth = einfo->depth.used && !einfo->kill_depth;
|
||||
bool has_mrtz_stencil = einfo->stencil.used && !einfo->kill_stencil;
|
||||
bool has_mrtz_samplemask = einfo->samplemask.used && !einfo->kill_samplemask;
|
||||
bool has_mrtz_export =
|
||||
has_mrtz_depth || has_mrtz_stencil || has_mrtz_samplemask || has_mrtz_alpha;
|
||||
if (has_mrtz_export) {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ struct aco_ps_epilog_info {
|
|||
bool skip_null_export;
|
||||
unsigned broadcast_last_cbuf;
|
||||
enum compare_func alpha_func;
|
||||
/* Depth/stencil/samplemask are always passed via VGPRs, and the epilog key can choose
|
||||
* not to export them using these flags, which can be dynamic states.
|
||||
*/
|
||||
bool kill_depth;
|
||||
bool kill_stencil;
|
||||
bool kill_samplemask;
|
||||
|
||||
struct ac_arg alpha_reference;
|
||||
struct ac_arg depth;
|
||||
struct ac_arg stencil;
|
||||
|
|
|
|||
|
|
@ -669,10 +669,10 @@ void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args)
|
|||
|
||||
/* Outputs for the epilog. */
|
||||
num_return_sgprs = SI_SGPR_ALPHA_REF + 1;
|
||||
num_returns =
|
||||
num_return_sgprs + util_bitcount(shader->selector->info.colors_written) * 4 +
|
||||
shader->selector->info.writes_z + shader->selector->info.writes_stencil +
|
||||
shader->ps.writes_samplemask + 1 /* SampleMaskIn */;
|
||||
/* These must always be declared even if Z/stencil/samplemask are killed. */
|
||||
num_returns = num_return_sgprs + util_bitcount(shader->selector->info.colors_written) * 4 +
|
||||
sel->info.writes_z + sel->info.writes_stencil + sel->info.writes_samplemask +
|
||||
1 /* SampleMaskIn */;
|
||||
|
||||
for (i = 0; i < num_return_sgprs; i++)
|
||||
ac_add_return(&args->ac, AC_ARG_SGPR);
|
||||
|
|
@ -1327,8 +1327,8 @@ void si_shader_dump_stats_for_shader_db(struct si_screen *screen, struct si_shad
|
|||
unreachable("invalid shader key");
|
||||
} else if (shader->selector->stage == MESA_SHADER_FRAGMENT) {
|
||||
num_ps_outputs = util_bitcount(shader->selector->info.colors_written) +
|
||||
(shader->selector->info.writes_z ||
|
||||
shader->selector->info.writes_stencil ||
|
||||
(shader->ps.writes_z ||
|
||||
shader->ps.writes_stencil ||
|
||||
shader->ps.writes_samplemask);
|
||||
}
|
||||
|
||||
|
|
@ -1575,6 +1575,8 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f)
|
|||
fprintf(f, " epilog.clamp_color = %u\n", key->ps.part.epilog.clamp_color);
|
||||
fprintf(f, " epilog.dual_src_blend_swizzle = %u\n", key->ps.part.epilog.dual_src_blend_swizzle);
|
||||
fprintf(f, " epilog.rbplus_depth_only_opt = %u\n", key->ps.part.epilog.rbplus_depth_only_opt);
|
||||
fprintf(f, " epilog.kill_z = %u\n", key->ps.part.epilog.kill_z);
|
||||
fprintf(f, " epilog.kill_stencil = %u\n", key->ps.part.epilog.kill_stencil);
|
||||
fprintf(f, " epilog.kill_samplemask = %u\n", key->ps.part.epilog.kill_samplemask);
|
||||
fprintf(f, " mono.poly_line_smoothing = %u\n", key->ps.mono.poly_line_smoothing);
|
||||
fprintf(f, " mono.point_smoothing = %u\n", key->ps.mono.point_smoothing);
|
||||
|
|
@ -2525,6 +2527,8 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_
|
|||
.alpha_to_one = key->ps.part.epilog.alpha_to_one,
|
||||
.alpha_func = key->ps.part.epilog.alpha_func,
|
||||
.broadcast_last_cbuf = key->ps.part.epilog.last_cbuf,
|
||||
.kill_z = key->ps.part.epilog.kill_z,
|
||||
.kill_stencil = key->ps.part.epilog.kill_stencil,
|
||||
.kill_samplemask = key->ps.part.epilog.kill_samplemask,
|
||||
|
||||
.bc_optimize_for_persp = key->ps.part.prolog.bc_optimize_for_persp,
|
||||
|
|
@ -2947,12 +2951,28 @@ debug_message_stderr(void *data, unsigned *id, enum util_debug_type ptype,
|
|||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
determine_shader_variant_info(struct si_screen *sscreen, struct si_shader *shader)
|
||||
{
|
||||
struct si_shader_selector *sel = shader->selector;
|
||||
|
||||
if (sel->stage == MESA_SHADER_FRAGMENT) {
|
||||
shader->ps.writes_z = sel->info.writes_z && !shader->key.ps.part.epilog.kill_z;
|
||||
shader->ps.writes_stencil = sel->info.writes_stencil &&
|
||||
!shader->key.ps.part.epilog.kill_stencil;
|
||||
shader->ps.writes_samplemask = sel->info.writes_samplemask &&
|
||||
!shader->key.ps.part.epilog.kill_samplemask;
|
||||
}
|
||||
}
|
||||
|
||||
bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler,
|
||||
struct si_shader *shader, struct util_debug_callback *debug)
|
||||
{
|
||||
bool ret = true;
|
||||
struct si_shader_selector *sel = shader->selector;
|
||||
|
||||
determine_shader_variant_info(sscreen, shader);
|
||||
|
||||
/* ACO need spi_ps_input in advance to init args and used in compiler. */
|
||||
if (sel->stage == MESA_SHADER_FRAGMENT && sel->info.base.use_aco_amd)
|
||||
si_set_spi_ps_input_config(shader);
|
||||
|
|
@ -3381,8 +3401,7 @@ void si_get_ps_epilog_key(struct si_shader *shader, union si_shader_part_key *ke
|
|||
key->ps_epilog.color_types = info->output_color_types;
|
||||
key->ps_epilog.writes_z = info->writes_z;
|
||||
key->ps_epilog.writes_stencil = info->writes_stencil;
|
||||
key->ps_epilog.writes_samplemask = info->writes_samplemask &&
|
||||
!shader->key.ps.part.epilog.kill_samplemask;
|
||||
key->ps_epilog.writes_samplemask = info->writes_samplemask;
|
||||
key->ps_epilog.states = shader->key.ps.part.epilog;
|
||||
}
|
||||
|
||||
|
|
@ -3459,11 +3478,6 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler
|
|||
struct si_shader_selector *sel = shader->selector;
|
||||
struct si_shader *mainp = *si_get_main_shader_part(sel, &shader->key, shader->wave_size);
|
||||
|
||||
if (sel->stage == MESA_SHADER_FRAGMENT) {
|
||||
shader->ps.writes_samplemask = sel->info.writes_samplemask &&
|
||||
!shader->key.ps.part.epilog.kill_samplemask;
|
||||
}
|
||||
|
||||
/* LS, ES, VS are compiled on demand if the main part hasn't been
|
||||
* compiled for that stage.
|
||||
*
|
||||
|
|
@ -3498,6 +3512,8 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler
|
|||
if (!mainp)
|
||||
return false;
|
||||
|
||||
determine_shader_variant_info(sscreen, shader);
|
||||
|
||||
/* Copy the compiled shader data over. */
|
||||
shader->is_binary_shared = true;
|
||||
shader->binary = mainp->binary;
|
||||
|
|
|
|||
|
|
@ -686,6 +686,8 @@ struct si_ps_epilog_bits {
|
|||
unsigned clamp_color : 1;
|
||||
unsigned dual_src_blend_swizzle : 1; /* gfx11+ */
|
||||
unsigned rbplus_depth_only_opt:1;
|
||||
unsigned kill_z:1;
|
||||
unsigned kill_stencil:1;
|
||||
unsigned kill_samplemask:1;
|
||||
};
|
||||
|
||||
|
|
@ -1015,6 +1017,8 @@ struct si_shader {
|
|||
unsigned num_interp;
|
||||
unsigned spi_gs_out_config_ps;
|
||||
unsigned pa_sc_hisz_control;
|
||||
bool writes_z;
|
||||
bool writes_stencil;
|
||||
bool writes_samplemask;
|
||||
} ps;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -314,14 +314,18 @@ si_aco_build_ps_epilog(struct aco_compiler_options *options,
|
|||
.spi_shader_col_format = key->ps_epilog.states.spi_shader_col_format,
|
||||
.color_is_int8 = key->ps_epilog.states.color_is_int8,
|
||||
.color_is_int10 = key->ps_epilog.states.color_is_int10,
|
||||
.mrt0_is_dual_src = key->ps_epilog.states.dual_src_blend_swizzle,
|
||||
.color_types = key->ps_epilog.color_types,
|
||||
.clamp_color = key->ps_epilog.states.clamp_color,
|
||||
.alpha_to_one = key->ps_epilog.states.alpha_to_one,
|
||||
.alpha_to_coverage_via_mrtz = key->ps_epilog.states.alpha_to_coverage_via_mrtz,
|
||||
.skip_null_export = options->gfx_level >= GFX10 && !key->ps_epilog.uses_discard,
|
||||
.broadcast_last_cbuf = key->ps_epilog.states.last_cbuf,
|
||||
.alpha_func = key->ps_epilog.states.alpha_func,
|
||||
.alpha_to_one = key->ps_epilog.states.alpha_to_one,
|
||||
.alpha_to_coverage_via_mrtz = key->ps_epilog.states.alpha_to_coverage_via_mrtz,
|
||||
.clamp_color = key->ps_epilog.states.clamp_color,
|
||||
.mrt0_is_dual_src = key->ps_epilog.states.dual_src_blend_swizzle,
|
||||
/* rbplus_depth_only_opt only affects registers, not the shader */
|
||||
.kill_depth = key->ps_epilog.states.kill_z,
|
||||
.kill_stencil = key->ps_epilog.states.kill_stencil,
|
||||
.kill_samplemask = key->ps_epilog.states.kill_samplemask,
|
||||
.skip_null_export = options->gfx_level >= GFX10 && !key->ps_epilog.uses_discard,
|
||||
.color_types = key->ps_epilog.color_types,
|
||||
.color_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -816,7 +816,9 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *
|
|||
|
||||
if (sel->stage == MESA_SHADER_FRAGMENT) {
|
||||
exports_color_null = sel->info.colors_written;
|
||||
exports_mrtz = sel->info.writes_z || sel->info.writes_stencil || shader->ps.writes_samplemask;
|
||||
exports_mrtz = shader->ps.writes_z || shader->ps.writes_stencil ||
|
||||
shader->ps.writes_samplemask ||
|
||||
shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz;
|
||||
if (!exports_mrtz && !exports_color_null)
|
||||
exports_color_null = si_shader_uses_discard(shader) || sscreen->info.gfx_level < GFX10;
|
||||
}
|
||||
|
|
@ -901,8 +903,9 @@ bool si_llvm_build_shader_part(struct si_screen *sscreen, gl_shader_stage stage,
|
|||
shader.key.ps.part.epilog = key->ps_epilog.states;
|
||||
wave32 = key->ps_epilog.wave32;
|
||||
exports_color_null = key->ps_epilog.colors_written;
|
||||
exports_mrtz = key->ps_epilog.writes_z || key->ps_epilog.writes_stencil ||
|
||||
key->ps_epilog.writes_samplemask;
|
||||
exports_mrtz = (key->ps_epilog.writes_z && !key->ps_epilog.states.kill_z) ||
|
||||
(key->ps_epilog.writes_stencil && !key->ps_epilog.states.kill_stencil) ||
|
||||
(key->ps_epilog.writes_samplemask && !key->ps_epilog.states.kill_samplemask);
|
||||
if (!exports_mrtz && !exports_color_null)
|
||||
exports_color_null = key->ps_epilog.uses_discard || sscreen->info.gfx_level < GFX10;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,22 +693,23 @@ void si_llvm_build_ps_epilog(struct si_shader_context *ctx, union si_shader_part
|
|||
|
||||
si_llvm_build_clamp_alpha_test(ctx, color[write_i], write_i);
|
||||
}
|
||||
bool writes_z = key->ps_epilog.writes_z && !key->ps_epilog.states.kill_z;
|
||||
bool writes_stencil = key->ps_epilog.writes_stencil && !key->ps_epilog.states.kill_stencil;
|
||||
bool writes_samplemask = key->ps_epilog.writes_samplemask && !key->ps_epilog.states.kill_samplemask;
|
||||
|
||||
LLVMValueRef mrtz_alpha =
|
||||
key->ps_epilog.states.alpha_to_coverage_via_mrtz ? color[0][3] : NULL;
|
||||
assert(writes_z || writes_stencil || writes_samplemask || !mrtz_alpha);
|
||||
|
||||
/* Prepare the mrtz export. */
|
||||
if (key->ps_epilog.writes_z ||
|
||||
key->ps_epilog.writes_stencil ||
|
||||
key->ps_epilog.writes_samplemask ||
|
||||
mrtz_alpha) {
|
||||
if (writes_z || writes_stencil || writes_samplemask || mrtz_alpha) {
|
||||
LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
|
||||
|
||||
if (key->ps_epilog.writes_z)
|
||||
if (writes_z)
|
||||
depth = ac_get_arg(&ctx->ac, depth_arg);
|
||||
if (key->ps_epilog.writes_stencil)
|
||||
if (writes_stencil)
|
||||
stencil = ac_get_arg(&ctx->ac, stencil_arg);
|
||||
if (key->ps_epilog.writes_samplemask)
|
||||
if (writes_samplemask)
|
||||
samplemask = ac_get_arg(&ctx->ac, samplemask_arg);
|
||||
|
||||
ac_export_mrt_z(&ctx->ac, depth, stencil, samplemask, mrtz_alpha, false,
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state)
|
|||
old_blend->dual_src_blend != blend->dual_src_blend ||
|
||||
old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
|
||||
old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit)
|
||||
si_ps_key_update_framebuffer_blend_rasterizer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
|
||||
|
||||
if (old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit ||
|
||||
old_blend->alpha_to_coverage != blend->alpha_to_coverage)
|
||||
|
|
@ -1344,7 +1344,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
|
|||
si_mark_atom_dirty(sctx, &sctx->atoms.s.dpbb_state);
|
||||
|
||||
if (old_rs->multisample_enable != rs->multisample_enable)
|
||||
si_ps_key_update_framebuffer_blend_rasterizer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
|
||||
|
||||
if (old_rs->flatshade != rs->flatshade ||
|
||||
old_rs->clamp_fragment_color != rs->clamp_fragment_color)
|
||||
|
|
@ -1540,7 +1540,8 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
|
|||
dsa->alpha_func = PIPE_FUNC_ALWAYS;
|
||||
}
|
||||
|
||||
dsa->depth_enabled = state->depth_enabled;
|
||||
dsa->depth_enabled = state->depth_enabled &&
|
||||
(state->depth_writemask || state->depth_func != PIPE_FUNC_ALWAYS);
|
||||
dsa->depth_write_enabled = state->depth_enabled && state->depth_writemask;
|
||||
dsa->stencil_enabled = state->stencil[0].enabled;
|
||||
dsa->stencil_write_enabled =
|
||||
|
|
@ -1714,6 +1715,12 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
|
|||
sctx->do_update_shaders = true;
|
||||
}
|
||||
|
||||
if (old_dsa->depth_enabled != dsa->depth_enabled ||
|
||||
old_dsa->stencil_enabled != dsa->stencil_enabled) {
|
||||
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
|
||||
sctx->do_update_shaders = true;
|
||||
}
|
||||
|
||||
if (sctx->occlusion_query_mode == SI_OCCLUSION_QUERY_MODE_PRECISE_BOOLEAN &&
|
||||
(old_dsa->depth_enabled != dsa->depth_enabled ||
|
||||
old_dsa->depth_write_enabled != dsa->depth_write_enabled))
|
||||
|
|
@ -2781,7 +2788,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
|
|||
}
|
||||
|
||||
si_ps_key_update_framebuffer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_rasterizer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
|
||||
si_ps_key_update_framebuffer_rasterizer_sample_shading(sctx);
|
||||
si_vs_ps_key_update_rast_prim_smooth_stipple(sctx);
|
||||
si_update_ps_inputs_read_or_disabled(sctx);
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ unsigned si_get_num_vertices_per_output_prim(struct si_shader *shader);
|
|||
bool si_update_ngg(struct si_context *sctx);
|
||||
void si_vs_ps_key_update_rast_prim_smooth_stipple(struct si_context *sctx);
|
||||
void si_ps_key_update_framebuffer(struct si_context *sctx);
|
||||
void si_ps_key_update_framebuffer_blend_rasterizer(struct si_context *sctx);
|
||||
void si_ps_key_update_framebuffer_blend_dsa_rasterizer(struct si_context *sctx);
|
||||
void si_ps_key_update_rasterizer(struct si_context *sctx);
|
||||
void si_ps_key_update_dsa(struct si_context *sctx);
|
||||
void si_ps_key_update_sample_shading(struct si_context *sctx);
|
||||
|
|
|
|||
|
|
@ -2078,8 +2078,8 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
|
|||
!G_0286CC_LINEAR_CENTER_ENA(input_ena) || !G_0286CC_LINEAR_CENTROID_ENA(input_ena));
|
||||
|
||||
/* DB_SHADER_CONTROL */
|
||||
shader->ps.db_shader_control = S_02880C_Z_EXPORT_ENABLE(info->writes_z) |
|
||||
S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(info->writes_stencil) |
|
||||
shader->ps.db_shader_control = S_02880C_Z_EXPORT_ENABLE(shader->ps.writes_z) |
|
||||
S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(shader->ps.writes_stencil) |
|
||||
S_02880C_MASK_EXPORT_ENABLE(shader->ps.writes_samplemask) |
|
||||
S_02880C_KILL_ENABLE(si_shader_uses_discard(shader));
|
||||
if (sscreen->info.gfx_level >= GFX12)
|
||||
|
|
@ -2170,7 +2170,8 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
|
|||
shader->ps.spi_ps_input_addr = shader->config.spi_ps_input_addr;
|
||||
shader->ps.num_interp = si_get_ps_num_interp(shader);
|
||||
shader->ps.spi_shader_z_format =
|
||||
ac_get_spi_shader_z_format(info->writes_z, info->writes_stencil, shader->ps.writes_samplemask,
|
||||
ac_get_spi_shader_z_format(shader->ps.writes_z, shader->ps.writes_stencil,
|
||||
shader->ps.writes_samplemask,
|
||||
shader->key.ps.part.epilog.alpha_to_coverage_via_mrtz);
|
||||
|
||||
/* Ensure that some export memory is always allocated, for two reasons:
|
||||
|
|
@ -2190,7 +2191,7 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
|
|||
*
|
||||
* RB+ depth-only rendering requires SPI_SHADER_32_R.
|
||||
*/
|
||||
bool has_mrtz = info->writes_z || info->writes_stencil || shader->ps.writes_samplemask;
|
||||
bool has_mrtz = shader->ps.spi_shader_z_format != V_028710_SPI_SHADER_ZERO;
|
||||
|
||||
if (!shader->ps.spi_shader_col_format) {
|
||||
if (shader->key.ps.part.epilog.rbplus_depth_only_opt) {
|
||||
|
|
@ -2572,7 +2573,7 @@ void si_ps_key_update_framebuffer(struct si_context *sctx)
|
|||
}
|
||||
}
|
||||
|
||||
void si_ps_key_update_framebuffer_blend_rasterizer(struct si_context *sctx)
|
||||
void si_ps_key_update_framebuffer_blend_dsa_rasterizer(struct si_context *sctx)
|
||||
{
|
||||
struct si_shader_selector *sel = sctx->shader.ps.cso;
|
||||
if (!sel)
|
||||
|
|
@ -2580,6 +2581,7 @@ void si_ps_key_update_framebuffer_blend_rasterizer(struct si_context *sctx)
|
|||
|
||||
union si_shader_key *key = &sctx->shader.ps.key;
|
||||
struct si_state_blend *blend = sctx->queued.named.blend;
|
||||
struct si_state_dsa *dsa = sctx->queued.named.dsa;
|
||||
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
|
||||
bool alpha_to_coverage = blend->alpha_to_coverage && rs->multisample_enable &&
|
||||
sctx->framebuffer.nr_samples >= 2;
|
||||
|
|
@ -2594,10 +2596,10 @@ void si_ps_key_update_framebuffer_blend_rasterizer(struct si_context *sctx)
|
|||
memcpy(&old_key, &key->ps, sizeof(old_key));
|
||||
#endif
|
||||
|
||||
key->ps.part.epilog.alpha_to_one = blend->alpha_to_one && rs->multisample_enable;
|
||||
key->ps.part.epilog.alpha_to_coverage_via_mrtz =
|
||||
sctx->gfx_level >= GFX11 && alpha_to_coverage &&
|
||||
(sel->info.writes_z || sel->info.writes_stencil || sel->info.writes_samplemask);
|
||||
key->ps.part.epilog.kill_z = sel->info.writes_z &&
|
||||
(!sctx->framebuffer.state.zsbuf || !dsa->depth_enabled);
|
||||
key->ps.part.epilog.kill_stencil = sel->info.writes_stencil &&
|
||||
(!sctx->framebuffer.has_stencil || !dsa->stencil_enabled);
|
||||
|
||||
/* Remove the gl_SampleMask fragment shader output if MSAA is disabled.
|
||||
* This is required for correctness and it's also an optimization.
|
||||
|
|
@ -2606,6 +2608,13 @@ void si_ps_key_update_framebuffer_blend_rasterizer(struct si_context *sctx)
|
|||
(sctx->framebuffer.nr_samples <= 1 ||
|
||||
!rs->multisample_enable);
|
||||
|
||||
key->ps.part.epilog.alpha_to_one = blend->alpha_to_one && rs->multisample_enable;
|
||||
key->ps.part.epilog.alpha_to_coverage_via_mrtz =
|
||||
sctx->gfx_level >= GFX11 && alpha_to_coverage &&
|
||||
((sel->info.writes_z && !key->ps.part.epilog.kill_z) ||
|
||||
(sel->info.writes_stencil && !key->ps.part.epilog.kill_stencil) ||
|
||||
(sel->info.writes_samplemask && !key->ps.part.epilog.kill_samplemask));
|
||||
|
||||
/* If alpha-to-coverage isn't exported via MRTZ, set that we need to export alpha
|
||||
* through MRT0.
|
||||
*/
|
||||
|
|
@ -3975,7 +3984,7 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
|
|||
si_update_ps_colorbuf0_slot(sctx);
|
||||
|
||||
si_ps_key_update_framebuffer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_rasterizer(sctx);
|
||||
si_ps_key_update_framebuffer_blend_dsa_rasterizer(sctx);
|
||||
si_ps_key_update_rasterizer(sctx);
|
||||
si_ps_key_update_dsa(sctx);
|
||||
si_ps_key_update_sample_shading(sctx);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue