nir, ir3: Add option to use unscaled FragCoord for input attachments

When rendering a scaled tile, we need to use the original, hardware
FragCoord when accessing input attachments that are on-tile (i.e. were
rendered to in a previous subpass) because they are also scaled in the
same way that FragCoord is scaled. For input attachments that aren't
already on-tile, however, we need to use the fixed gl_FragCoord. Add a
new intrinsic and a bitfield of input attachments which should use it.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20304>
This commit is contained in:
Connor Abbott
2022-12-13 18:09:28 +01:00
committed by Marge Bot
parent 715327ff85
commit b474ed1f3a
4 changed files with 31 additions and 5 deletions
+1
View File
@@ -5480,6 +5480,7 @@ typedef struct nir_input_attachment_options {
bool use_fragcoord_sysval;
bool use_layer_id_sysval;
bool use_view_id_for_layer;
uint32_t unscaled_input_attachment_ir3;
} nir_input_attachment_options;
bool nir_lower_input_attachments(nir_shader *shader,
+4
View File
@@ -1193,6 +1193,10 @@ system_value("rel_patch_id_ir3", 1)
# System values for freedreno compute shaders.
system_value("subgroup_id_shift_ir3", 1)
# System values for freedreno fragment shaders.
intrinsic("load_frag_coord_unscaled_ir3", dest_comp=4,
flags=[CAN_ELIMINATE, CAN_REORDER], bit_sizes=[32])
# IR3-specific intrinsics for tessellation control shaders. cond_end_ir3 end
# the shader when src0 is false and is used to narrow down the TCS shader to
# just thread 0 before writing out tessellation levels.
+25 -5
View File
@@ -25,10 +25,30 @@
#include "nir_builder.h"
static nir_ssa_def *
load_frag_coord(nir_builder *b, const nir_input_attachment_options *options)
load_frag_coord(nir_builder *b, nir_deref_instr *deref,
const nir_input_attachment_options *options)
{
if (options->use_fragcoord_sysval)
return nir_load_frag_coord(b);
if (options->use_fragcoord_sysval) {
nir_ssa_def *frag_coord = nir_load_frag_coord(b);
if (options->unscaled_input_attachment_ir3) {
nir_variable *var = nir_deref_instr_get_variable(deref);
unsigned base = var->data.index;
nir_ssa_def *unscaled_frag_coord = nir_load_frag_coord_unscaled_ir3(b);
if (deref->deref_type == nir_deref_type_array) {
nir_ssa_def *unscaled =
nir_i2b(b, nir_iand(b, nir_ishr(b,
nir_imm_int(b, options->unscaled_input_attachment_ir3 >> base),
deref->arr.index.ssa),
nir_imm_int(b, 1)));
frag_coord = nir_bcsel(b, unscaled, unscaled_frag_coord, frag_coord);
} else {
assert(deref->deref_type == nir_deref_type_var);
bool unscaled = (options->unscaled_input_attachment_ir3 >> base) & 1;
frag_coord = unscaled ? unscaled_frag_coord : frag_coord;
}
}
return frag_coord;
}
nir_variable *pos =
nir_find_variable_with_location(b->shader, nir_var_shader_in,
@@ -92,7 +112,7 @@ try_lower_input_load(nir_builder *b, nir_intrinsic_instr *load,
b->cursor = nir_instr_remove(&load->instr);
nir_ssa_def *frag_coord = load_frag_coord(b, options);
nir_ssa_def *frag_coord = load_frag_coord(b, deref, options);
frag_coord = nir_f2i32(b, frag_coord);
nir_ssa_def *offset = nir_ssa_for_src(b, load->src[1], 2);
nir_ssa_def *pos = nir_iadd(b, frag_coord, offset);
@@ -162,7 +182,7 @@ try_lower_input_texop(nir_builder *b, nir_tex_instr *tex,
b->cursor = nir_before_instr(&tex->instr);
nir_ssa_def *frag_coord = load_frag_coord(b, options);
nir_ssa_def *frag_coord = load_frag_coord(b, deref, options);
frag_coord = nir_f2i32(b, frag_coord);
nir_ssa_def *layer = load_layer_id(b, options);
+1
View File
@@ -2092,6 +2092,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
emit_intrinsic_copy_ubo_to_uniform(ctx, intr);
break;
case nir_intrinsic_load_frag_coord:
case nir_intrinsic_load_frag_coord_unscaled_ir3:
ir3_split_dest(b, dst, get_frag_coord(ctx, intr), 0, 4);
break;
case nir_intrinsic_load_sample_pos_from_id: {