mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 12:50:12 +01:00
nir: Add a new load_input_attachment_coord intrinsic
This hoists all the annoyance of figuring out the current pixel's input attachment coordinates to the driver. The pass still deals with all the annoyance of turning an image instruciton into a texture instruction but it gives the driver more control over the position. For most drivers, this will be something like ivec3(int(gl_FragCoord.xy), gl_Layer) or similar, some drivers need something more nuanced. Turnip, for instance, needs unscaled coordinates for some attachments and NVK doesn't really want gl_Layer or gl_ViewIndex for the layer. It's better to just have a new system value that drivers can make what they want. Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35551>
This commit is contained in:
parent
2c13e1e655
commit
9f9cde04ec
4 changed files with 41 additions and 17 deletions
|
|
@ -5711,6 +5711,7 @@ typedef struct nir_lower_idiv_options {
|
|||
bool nir_lower_idiv(nir_shader *shader, const nir_lower_idiv_options *options);
|
||||
|
||||
typedef struct nir_input_attachment_options {
|
||||
bool use_ia_coord_intrin;
|
||||
bool use_fragcoord_sysval;
|
||||
bool use_layer_id_sysval;
|
||||
bool use_view_id_for_layer;
|
||||
|
|
|
|||
|
|
@ -782,6 +782,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
|
|||
case nir_intrinsic_load_barycentric_coord_at_sample:
|
||||
case nir_intrinsic_load_barycentric_coord_at_offset:
|
||||
case nir_intrinsic_load_persp_center_rhw_ir3:
|
||||
case nir_intrinsic_load_input_attachment_coord:
|
||||
case nir_intrinsic_interp_deref_at_offset:
|
||||
case nir_intrinsic_interp_deref_at_sample:
|
||||
case nir_intrinsic_interp_deref_at_centroid:
|
||||
|
|
|
|||
|
|
@ -1125,6 +1125,13 @@ barycentric("coord_at_offset", 3, [2])
|
|||
intrinsic("load_sample_pos_from_id", src_comp=[1], dest_comp=2,
|
||||
flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||
|
||||
# Load input attachment coordinate:
|
||||
#
|
||||
# Takes an input attachment index and returns an ivec with the position in
|
||||
# input attachment space in .xy and the input attachment array index in .z.
|
||||
intrinsic("load_input_attachment_coord", src_comp=[1], dest_comp=3,
|
||||
bit_sizes=[32], flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||
|
||||
# Demote a subset of samples given by a specified sample mask. This acts like a
|
||||
# per-sample demote, or an inverted accumulating gl_SampleMask write.
|
||||
intrinsic("demote_samples", src_comp=[1])
|
||||
|
|
|
|||
|
|
@ -83,6 +83,29 @@ load_layer_id(nir_builder *b, const nir_input_attachment_options *options)
|
|||
return nir_load_var(b, layer_id);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
load_coord(nir_builder *b, nir_deref_instr *deref,
|
||||
const nir_input_attachment_options *options)
|
||||
{
|
||||
if (options->use_ia_coord_intrin) {
|
||||
nir_def *index;
|
||||
if (deref->deref_type == nir_deref_type_array) {
|
||||
ASSERTED nir_deref_instr *parent = nir_deref_instr_parent(deref);
|
||||
assert(parent->deref_type == nir_deref_type_var);
|
||||
index = deref->arr.index.ssa;
|
||||
} else {
|
||||
assert(deref->deref_type == nir_deref_type_var);
|
||||
index = nir_imm_int(b, 0);
|
||||
}
|
||||
|
||||
return nir_load_input_attachment_coord(b, index);
|
||||
} else {
|
||||
nir_def *pos = nir_f2i32(b, load_frag_coord(b, deref, options));
|
||||
nir_def *layer = load_layer_id(b, options);
|
||||
return nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1), layer);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
try_lower_input_load(nir_builder *b, nir_intrinsic_instr *load,
|
||||
const nir_input_attachment_options *options)
|
||||
|
|
@ -99,14 +122,10 @@ try_lower_input_load(nir_builder *b, nir_intrinsic_instr *load,
|
|||
|
||||
b->cursor = nir_instr_remove(&load->instr);
|
||||
|
||||
nir_def *frag_coord = load_frag_coord(b, deref, options);
|
||||
frag_coord = nir_f2i32(b, frag_coord);
|
||||
nir_def *offset = nir_trim_vector(b, load->src[1].ssa, 2);
|
||||
nir_def *pos = nir_iadd(b, frag_coord, offset);
|
||||
|
||||
nir_def *layer = load_layer_id(b, options);
|
||||
nir_def *coord =
|
||||
nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1), layer);
|
||||
nir_def *offset = nir_vec3(b, nir_channel(b, load->src[1].ssa, 0),
|
||||
nir_channel(b, load->src[1].ssa, 1),
|
||||
nir_imm_int(b, 0));
|
||||
nir_def *coord = nir_iadd(b, load_coord(b, deref, options), offset);
|
||||
|
||||
nir_tex_instr *tex = nir_tex_instr_create(b->shader, 3 + multisampled);
|
||||
|
||||
|
|
@ -174,15 +193,11 @@ try_lower_input_texop(nir_builder *b, nir_tex_instr *tex,
|
|||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
nir_def *frag_coord = load_frag_coord(b, deref, options);
|
||||
frag_coord = nir_f2i32(b, frag_coord);
|
||||
|
||||
nir_def *offset = nir_trim_vector(b, tex->src[coord_src_idx].src.ssa, 2);
|
||||
nir_def *pos = nir_iadd(b, frag_coord, offset);
|
||||
|
||||
nir_def *layer = load_layer_id(b, options);
|
||||
nir_def *coord = nir_vec3(b, nir_channel(b, pos, 0),
|
||||
nir_channel(b, pos, 1), layer);
|
||||
nir_def *offset = tex->src[coord_src_idx].src.ssa;
|
||||
offset = nir_vec3(b, nir_channel(b, offset, 0),
|
||||
nir_channel(b, offset, 1),
|
||||
nir_imm_int(b, 0));
|
||||
nir_def *coord = nir_iadd(b, load_coord(b, deref, options), offset);
|
||||
|
||||
tex->coord_components = 3;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue