nvk: Switch to nir_intrinsic_load_input_attachment_coord

The important change here is that we're no longer using state to
determine whether or not we're multiview.  We just assume that layer_id
is zero when in multiview (this appears to be the case when SET_RT_LAYER
is set to CONTROL_V_SELECTS_LAYER) and that view_index is zero when not
in multiview (this is required by Vulkan) and add the two together.
This fixes a long-standing bug where multiview input attachments didn't
work properly with shader objects.

Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35551>
This commit is contained in:
Faith Ekstrand 2025-06-16 09:37:44 -04:00 committed by Marge Bot
parent e1e32fcf0d
commit 0e740fa8e6
2 changed files with 25 additions and 11 deletions

View file

@ -834,6 +834,26 @@ lower_load_push_constant(nir_builder *b, nir_intrinsic_instr *load,
return true;
}
static bool
lower_load_input_attachment_coord(nir_builder *b, nir_intrinsic_instr *load,
const struct lower_descriptors_ctx *ctx)
{
b->cursor = nir_before_instr(&load->instr);
nir_def *pos = nir_f2i32(b, nir_load_frag_coord(b));
nir_def *layer = nir_load_layer_id(b);
nir_def *view = load_root_table(b, 1, 32, draw.view_index, ctx);
nir_def *coord = nir_vec3(b, nir_channel(b, pos, 0),
nir_channel(b, pos, 1),
nir_iadd(b, layer, view));
nir_def_replace(&load->def, coord);
return true;
}
static void
get_resource_deref_binding(nir_builder *b, nir_deref_instr *deref,
uint32_t *set, uint32_t *binding,
@ -1182,6 +1202,9 @@ try_lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
case nir_intrinsic_load_view_index:
return lower_sysval_to_root_table(b, intrin, draw.view_index, ctx);
case nir_intrinsic_load_input_attachment_coord:
return lower_load_input_attachment_coord(b, intrin, ctx);
case nir_intrinsic_image_deref_load:
case nir_intrinsic_image_deref_sparse_load:
case nir_intrinsic_image_deref_store:

View file

@ -204,9 +204,6 @@ nvk_hash_state(struct vk_physical_device *device,
nvk_populate_fs_key(&key, state);
_mesa_blake3_update(&blake3_ctx, &key, sizeof(key));
const bool is_multiview = state->rp->view_mask != 0;
_mesa_blake3_update(&blake3_ctx, &is_multiview, sizeof(is_multiview));
/* This doesn't impact the shader compile but it does go in the
* nvk_shader and gets [de]serialized along with the binary so we
* need to hash it.
@ -335,7 +332,6 @@ static void
nvk_lower_nir(struct nvk_device *dev, nir_shader *nir,
VkShaderCreateFlagsEXT shader_flags,
const struct vk_pipeline_robustness_state *rs,
bool is_multiview,
uint32_t set_layout_count,
struct vk_descriptor_set_layout * const *set_layouts,
struct nvk_cbuf_map *cbuf_map_out)
@ -345,9 +341,7 @@ nvk_lower_nir(struct nvk_device *dev, nir_shader *nir,
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS(_, nir, nir_lower_input_attachments,
&(nir_input_attachment_options) {
.use_fragcoord_sysval = true,
.use_layer_id_sysval = true,
.use_view_id_for_layer = is_multiview,
.use_ia_coord_intrin = true,
});
}
@ -896,10 +890,7 @@ nvk_compile_shader(struct nvk_device *dev,
return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY);
}
/* TODO: Multiview with ESO */
const bool is_multiview = state && state->rp->view_mask != 0;
nvk_lower_nir(dev, nir, info->flags, info->robustness, is_multiview,
nvk_lower_nir(dev, nir, info->flags, info->robustness,
info->set_layout_count, info->set_layouts,
&shader->cbuf_map);