ac/nir: lower barycentric_at_offset/sample in ac_nir_lower_ps_early
i.e. before future linking optimizations and shader_info gathering They are lowered together because one depends on the other. 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:
@@ -275,6 +275,9 @@ typedef struct {
|
||||
bool force_linear_sample_interp;
|
||||
bool force_persp_center_interp;
|
||||
bool force_linear_center_interp;
|
||||
bool interpolate_at_sample_force_center;
|
||||
bool load_sample_positions_always_loads_current_ones;
|
||||
bool dynamic_rasterization_samples;
|
||||
int force_front_face; /* 0 -> keep, 1 -> set to true, -1 -> set to false */
|
||||
unsigned ps_iter_samples;
|
||||
|
||||
|
||||
@@ -295,6 +295,25 @@ lower_ps_load_sample_mask_in(nir_builder *b, nir_intrinsic_instr *intrin, lower_
|
||||
return true;
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
lower_load_barycentric_at_offset(nir_builder *b, nir_def *offset, enum glsl_interp_mode mode)
|
||||
{
|
||||
nir_def *baryc = nir_load_barycentric_pixel(b, 32, .interp_mode = mode);
|
||||
nir_def *i = nir_channel(b, baryc, 0);
|
||||
nir_def *j = nir_channel(b, baryc, 1);
|
||||
nir_def *offset_x = nir_channel(b, offset, 0);
|
||||
nir_def *offset_y = nir_channel(b, offset, 1);
|
||||
nir_def *ddx_i = nir_ddx(b, i);
|
||||
nir_def *ddx_j = nir_ddx(b, j);
|
||||
nir_def *ddy_i = nir_ddy(b, i);
|
||||
nir_def *ddy_j = nir_ddy(b, j);
|
||||
|
||||
/* Interpolate standard barycentrics by offset. */
|
||||
nir_def *offset_i = nir_ffma(b, ddy_i, offset_y, nir_ffma(b, ddx_i, offset_x, i));
|
||||
nir_def *offset_j = nir_ffma(b, ddy_j, offset_y, nir_ffma(b, ddx_j, offset_x, j));
|
||||
return nir_vec2(b, offset_i, offset_j);
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_ps_intrinsic(nir_builder *b, nir_instr *instr, void *state)
|
||||
{
|
||||
@@ -339,6 +358,49 @@ lower_ps_intrinsic(nir_builder *b, nir_instr *instr, void *state)
|
||||
/* sample_pos = ffract(frag_coord.xy); */
|
||||
nir_def_replace(&intrin->def, nir_ffract(b, nir_channels(b, nir_load_frag_coord(b), 0x3)));
|
||||
return true;
|
||||
case nir_intrinsic_load_barycentric_at_offset:
|
||||
nir_def_replace(&intrin->def,
|
||||
lower_load_barycentric_at_offset(b, intrin->src[0].ssa,
|
||||
nir_intrinsic_interp_mode(intrin)));
|
||||
return true;
|
||||
case nir_intrinsic_load_barycentric_at_sample: {
|
||||
unsigned mode = nir_intrinsic_interp_mode(intrin);
|
||||
|
||||
if (s->options->interpolate_at_sample_force_center) {
|
||||
nir_def_replace(&intrin->def, nir_load_barycentric_pixel(b, 32, .interp_mode = mode));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If load_sample_positions_always_loads_current_ones is true, load_sample_positions_amd
|
||||
* always loads the sample positions that are currently set in the rasterizer state
|
||||
* even if MSAA is disabled.
|
||||
*/
|
||||
nir_def *num_samples = s->options->load_sample_positions_always_loads_current_ones ?
|
||||
nir_undef(b, 1, 32) : nir_load_rasterization_samples_amd(b);
|
||||
nir_def *sample_id = intrin->src[0].ssa;
|
||||
nir_def *sample_pos = nir_load_sample_positions_amd(b, 32, sample_id, num_samples);
|
||||
sample_pos = nir_fadd_imm(b, sample_pos, -0.5f);
|
||||
|
||||
if (s->options->dynamic_rasterization_samples) {
|
||||
assert(!s->options->load_sample_positions_always_loads_current_ones);
|
||||
nir_def *pixel, *at_sample;
|
||||
|
||||
nir_push_if(b, nir_ieq_imm(b, num_samples, 1));
|
||||
{
|
||||
pixel = nir_load_barycentric_pixel(b, 32, .interp_mode = mode);
|
||||
}
|
||||
nir_push_else(b, NULL);
|
||||
{
|
||||
at_sample = lower_load_barycentric_at_offset(b, sample_pos, mode);
|
||||
}
|
||||
nir_pop_if(b, NULL);
|
||||
nir_def_replace(&intrin->def, nir_if_phi(b, pixel, at_sample));
|
||||
} else {
|
||||
nir_def_replace(&intrin->def,
|
||||
lower_load_barycentric_at_offset(b, sample_pos, mode));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -531,23 +531,12 @@ static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_s
|
||||
replacement = nir_imm_int(b, (1 << 2) | (1 << 4));
|
||||
}
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_at_sample: {
|
||||
unsigned mode = nir_intrinsic_interp_mode(intrin);
|
||||
|
||||
if (key->ps.mono.interpolate_at_sample_force_center) {
|
||||
replacement = nir_load_barycentric_pixel(b, 32, .interp_mode = mode);
|
||||
} else {
|
||||
nir_def *sample_id = intrin->src[0].ssa;
|
||||
/* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */
|
||||
nir_def *offset = nir_ishl_imm(b, sample_id, 3);
|
||||
|
||||
nir_def *buf = si_nir_load_internal_binding(b, args, SI_PS_CONST_SAMPLE_POSITIONS, 4);
|
||||
nir_def *sample_pos = nir_load_ubo(b, 2, 32, buf, offset, .range = ~0);
|
||||
|
||||
sample_pos = nir_fadd_imm(b, sample_pos, -0.5);
|
||||
|
||||
replacement = nir_load_barycentric_at_offset(b, 32, sample_pos, .interp_mode = mode);
|
||||
}
|
||||
case nir_intrinsic_load_sample_positions_amd: {
|
||||
/* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */
|
||||
nir_def *buf = si_nir_load_internal_binding(b, args, SI_PS_CONST_SAMPLE_POSITIONS, 4);
|
||||
nir_def *sample_id = intrin->src[0].ssa;
|
||||
nir_def *offset = nir_ishl_imm(b, sample_id, 3);
|
||||
replacement = nir_load_ubo(b, 2, 32, buf, offset, .range = ~0);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_output: {
|
||||
|
||||
@@ -2528,6 +2528,8 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_
|
||||
.force_linear_sample_interp = key->ps.part.prolog.force_linear_sample_interp,
|
||||
.force_persp_center_interp = key->ps.part.prolog.force_persp_center_interp,
|
||||
.force_linear_center_interp = key->ps.part.prolog.force_linear_center_interp,
|
||||
.interpolate_at_sample_force_center = key->ps.mono.interpolate_at_sample_force_center,
|
||||
.load_sample_positions_always_loads_current_ones = true,
|
||||
.force_front_face = key->ps.opt.force_front_face_input,
|
||||
.ps_iter_samples = 1 << key->ps.part.prolog.samplemask_log_ps_iter,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user