ac/nir: clamp vertex color outputs in the right place
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33024>
This commit is contained in:
@@ -69,15 +69,6 @@ ac_nir_create_gs_copy_shader(const nir_shader *gs_nir,
|
||||
nir_load_buffer_amd(&b, 1, 32, gsvs_ring, vtx_offset, zero, zero,
|
||||
.base = offset,
|
||||
.access = ACCESS_COHERENT | ACCESS_NON_TEMPORAL);
|
||||
|
||||
/* clamp legacy color output */
|
||||
if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1 ||
|
||||
i == VARYING_SLOT_BFC0 || i == VARYING_SLOT_BFC1) {
|
||||
nir_def *color = out.outputs[i][j];
|
||||
nir_def *clamp = nir_load_clamp_vertex_color_amd(&b);
|
||||
out.outputs[i][j] = nir_bcsel(&b, clamp, nir_fsat(&b, color), color);
|
||||
}
|
||||
|
||||
offset += gs_nir->info.gs.vertices_out * 16 * 4;
|
||||
}
|
||||
}
|
||||
@@ -117,6 +108,9 @@ ac_nir_create_gs_copy_shader(const nir_shader *gs_nir,
|
||||
if (stream_id)
|
||||
ac_nir_emit_legacy_streamout(&b, stream, info, &out);
|
||||
|
||||
/* This should be after streamout and before exports. */
|
||||
ac_nir_clamp_vertex_color_outputs(&b, &out);
|
||||
|
||||
if (stream == 0) {
|
||||
uint64_t export_outputs = b.shader->info.outputs_written | VARYING_BIT_POS;
|
||||
if (kill_pointsize)
|
||||
|
||||
@@ -179,6 +179,9 @@ ac_nir_pack_ngg_prim_exp_arg(nir_builder *b, unsigned num_vertices_per_primitive
|
||||
nir_def *vertex_indices[3], nir_def *is_null_prim,
|
||||
enum amd_gfx_level gfx_level);
|
||||
|
||||
void
|
||||
ac_nir_clamp_vertex_color_outputs(nir_builder *b, ac_nir_prerast_out *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,6 @@ ac_nir_lower_legacy_vs(nir_shader *nir,
|
||||
bool force_vrs)
|
||||
{
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
nir_metadata preserved = nir_metadata_control_flow;
|
||||
|
||||
nir_builder b = nir_builder_at(nir_after_impl(impl));
|
||||
|
||||
@@ -65,10 +64,11 @@ ac_nir_lower_legacy_vs(nir_shader *nir,
|
||||
nir->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID);
|
||||
}
|
||||
|
||||
if (!disable_streamout && nir->xfb_info) {
|
||||
if (!disable_streamout && nir->xfb_info)
|
||||
ac_nir_emit_legacy_streamout(&b, 0, ac_nir_get_sorted_xfb_info(nir), &out);
|
||||
preserved = nir_metadata_none;
|
||||
}
|
||||
|
||||
/* This should be after streamout and before exports. */
|
||||
ac_nir_clamp_vertex_color_outputs(&b, &out);
|
||||
|
||||
uint64_t export_outputs = nir->info.outputs_written | VARYING_BIT_POS;
|
||||
if (kill_pointsize)
|
||||
@@ -86,5 +86,5 @@ ac_nir_lower_legacy_vs(nir_shader *nir,
|
||||
&out);
|
||||
}
|
||||
|
||||
nir_metadata_preserve(impl, preserved);
|
||||
nir_metadata_preserve(impl, nir_metadata_none);
|
||||
}
|
||||
|
||||
@@ -2635,6 +2635,9 @@ ac_nir_lower_ngg_nogs(nir_shader *shader, const ac_nir_lower_ngg_options *option
|
||||
ngg_nogs_gather_outputs(b, &if_es_thread->then_list, &state);
|
||||
b->cursor = nir_after_cf_list(&if_es_thread->then_list);
|
||||
|
||||
/* This should be after streamout and before exports. */
|
||||
ac_nir_clamp_vertex_color_outputs(b, &state.out);
|
||||
|
||||
if (state.has_user_edgeflags)
|
||||
ngg_nogs_store_edgeflag_to_lds(b, &state);
|
||||
|
||||
@@ -3124,6 +3127,9 @@ ngg_gs_export_vertices(nir_builder *b, nir_def *max_num_out_vtx, nir_def *tid_in
|
||||
}
|
||||
}
|
||||
|
||||
/* This should be after streamout and before exports. */
|
||||
ac_nir_clamp_vertex_color_outputs(b, &s->out);
|
||||
|
||||
uint64_t export_outputs = b->shader->info.outputs_written | VARYING_BIT_POS;
|
||||
if (s->options->kill_pointsize)
|
||||
export_outputs &= ~VARYING_BIT_PSIZ;
|
||||
|
||||
@@ -824,3 +824,30 @@ ac_nir_pack_ngg_prim_exp_arg(nir_builder *b, unsigned num_vertices_per_primitive
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void
|
||||
ac_nir_clamp_vertex_color_outputs(nir_builder *b, ac_nir_prerast_out *out)
|
||||
{
|
||||
/* Clamp color outputs. */
|
||||
if (!(b->shader->info.outputs_written & (VARYING_BIT_COL0 | VARYING_BIT_COL1 |
|
||||
VARYING_BIT_BFC0 | VARYING_BIT_BFC1)))
|
||||
return;
|
||||
|
||||
nir_def *color_channels[16] = {0};
|
||||
|
||||
nir_if *if_clamp = nir_push_if(b, nir_load_clamp_vertex_color_amd(b));
|
||||
{
|
||||
for (unsigned i = 0; i < 16; i++) {
|
||||
const unsigned slot = (i / 8 ? VARYING_SLOT_BFC0 : VARYING_SLOT_COL0) + (i % 8) / 4;
|
||||
if (out->outputs[slot][i % 4])
|
||||
color_channels[i] = nir_fsat(b, out->outputs[slot][i % 4]);
|
||||
}
|
||||
}
|
||||
nir_pop_if(b, if_clamp);
|
||||
for (unsigned i = 0; i < 16; i++) {
|
||||
if (color_channels[i]) {
|
||||
const unsigned slot = (i / 8 ? VARYING_SLOT_BFC0 : VARYING_SLOT_COL0) + (i % 8) / 4;
|
||||
out->outputs[slot][i % 4] = nir_if_phi(b, color_channels[i], out->outputs[slot][i % 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1803,43 +1803,6 @@ static bool si_nir_kill_ps_outputs(nir_shader *nir, const union si_shader_key *k
|
||||
nir_metadata_control_flow, (void*)key);
|
||||
}
|
||||
|
||||
static bool clamp_vertex_color_instr(nir_builder *b,
|
||||
nir_intrinsic_instr *intrin, void *state)
|
||||
{
|
||||
if (intrin->intrinsic != nir_intrinsic_store_output)
|
||||
return false;
|
||||
|
||||
unsigned location = nir_intrinsic_io_semantics(intrin).location;
|
||||
if (location != VARYING_SLOT_COL0 && location != VARYING_SLOT_COL1 &&
|
||||
location != VARYING_SLOT_BFC0 && location != VARYING_SLOT_BFC1)
|
||||
return false;
|
||||
|
||||
/* no indirect output */
|
||||
assert(nir_src_is_const(intrin->src[1]) && !nir_src_as_uint(intrin->src[1]));
|
||||
/* only scalar output */
|
||||
assert(intrin->src[0].ssa->num_components == 1);
|
||||
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
|
||||
nir_def *color = intrin->src[0].ssa;
|
||||
nir_def *clamp = nir_load_clamp_vertex_color_amd(b);
|
||||
nir_def *new_color = nir_bcsel(b, clamp, nir_fsat(b, color), color);
|
||||
nir_src_rewrite(&intrin->src[0], new_color);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool si_nir_clamp_vertex_color(nir_shader *nir)
|
||||
{
|
||||
uint64_t mask = VARYING_BIT_COL0 | VARYING_BIT_COL1 | VARYING_BIT_BFC0 | VARYING_BIT_BFC1;
|
||||
if (!(nir->info.outputs_written & mask))
|
||||
return false;
|
||||
|
||||
return nir_shader_intrinsics_pass(nir, clamp_vertex_color_instr,
|
||||
nir_metadata_control_flow,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static unsigned si_map_io_driver_location(unsigned semantic)
|
||||
{
|
||||
if ((semantic >= VARYING_SLOT_PATCH0 && semantic < VARYING_SLOT_TESS_MAX) ||
|
||||
@@ -2428,18 +2391,13 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_
|
||||
NIR_PASS(progress, nir, nir_lower_non_uniform_access, &options);
|
||||
}
|
||||
|
||||
/* Legacy GS is not the last VGT stage because there is also the GS copy shader. */
|
||||
bool is_last_vgt_stage =
|
||||
(nir->info.stage == MESA_SHADER_VERTEX ||
|
||||
nir->info.stage == MESA_SHADER_TESS_EVAL ||
|
||||
(nir->info.stage == MESA_SHADER_GEOMETRY && shader->key.ge.as_ngg)) &&
|
||||
!shader->key.ge.as_ls && !shader->key.ge.as_es;
|
||||
|
||||
/* Legacy GS is not last VGT stage because it has GS copy shader. */
|
||||
bool is_legacy_gs = nir->info.stage == MESA_SHADER_GEOMETRY && !key->ge.as_ngg;
|
||||
|
||||
if (is_last_vgt_stage || is_legacy_gs)
|
||||
NIR_PASS(progress, nir, si_nir_clamp_vertex_color);
|
||||
|
||||
if (progress) {
|
||||
si_nir_opts(sel->screen, nir, true);
|
||||
late_opts = true;
|
||||
@@ -2497,7 +2455,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_
|
||||
sel->screen->options.vrs2x2);
|
||||
}
|
||||
progress = true;
|
||||
} else if (is_legacy_gs) {
|
||||
} else if (nir->info.stage == MESA_SHADER_GEOMETRY && !key->ge.as_ngg) {
|
||||
NIR_PASS_V(nir, ac_nir_lower_legacy_gs, false, sel->screen->use_ngg, output_info);
|
||||
progress = true;
|
||||
} else if (nir->info.stage == MESA_SHADER_FRAGMENT && shader->is_monolithic) {
|
||||
|
||||
Reference in New Issue
Block a user