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:
@@ -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,
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user