panvk: Leave holes in the attribute locations used by a shader

If we want to be able to emit attribute descriptors based on
vk_vertex_input_state without adjusting it every time a new vertex
shader is bound, we need to rely on the shader attribute location
info instead of compacting the location range.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28927>
This commit is contained in:
Boris Brezillon 2024-04-23 17:30:06 +02:00 committed by Marge Bot
parent 3683aaeb02
commit bd71c586cb
2 changed files with 34 additions and 12 deletions

View file

@ -714,20 +714,16 @@ parse_vertex_input(struct panvk_graphics_pipeline *pipeline,
attribs->buf[i].instance_divisor = desc->divisor;
}
const struct pan_shader_info *vs = &shaders[MESA_SHADER_VERTEX]->info;
uint32_t vi_attrib_count = util_last_bit(vi->attributes_valid);
attribs->attrib_count = util_last_bit(vi->attributes_valid);
for (unsigned i = 0; i < attribs->attrib_count; i++) {
if (!(vi->attributes_valid & BITFIELD_BIT(i)))
continue;
attribs->attrib_count = 0;
for (unsigned i = 0; i < vi_attrib_count; i++) {
const struct vk_vertex_attribute_state *desc = &vi->attributes[i];
unsigned attrib = i + VERT_ATTRIB_GENERIC0;
unsigned slot =
util_bitcount64(vs->attributes_read & BITFIELD64_MASK(attrib));
attribs->attrib[slot].buf = desc->binding;
attribs->attrib[slot].format = vk_format_to_pipe_format(desc->format);
attribs->attrib[slot].offset = desc->offset;
attribs->attrib_count = MAX2(attribs->attrib_count, slot + 1);
attribs->attrib[i].buf = desc->binding;
attribs->attrib[i].format = vk_format_to_pipe_format(desc->format);
attribs->attrib[i].offset = desc->offset;
}
}

View file

@ -339,7 +339,21 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, gl_shader_stage stage,
NIR_PASS_V(nir, nir_split_var_copies);
NIR_PASS_V(nir, nir_lower_var_copies);
nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, stage);
if (stage == MESA_SHADER_VERTEX) {
/* We need the driver_location to match the vertex attribute location,
* so we can use the attribute layout described by
* vk_vertex_input_state where there are holes in the attribute locations.
*/
nir_foreach_shader_in_variable(var, nir) {
assert(var->data.location >= VERT_ATTRIB_GENERIC0 &&
var->data.location <= VERT_ATTRIB_GENERIC15);
var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
}
} else {
nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
stage);
}
nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
stage);
@ -389,6 +403,18 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, gl_shader_stage stage,
shader->info.sampler_count = layout->num_samplers;
shader->info.texture_count = layout->num_textures;
if (stage == MESA_SHADER_VERTEX) {
/* We leave holes in the attribute locations, but pan_shader.c assumes the
* opposite. Patch attribute_count accordingly, so
* pan_shader_prepare_rsd() does what we expect.
*/
uint32_t gen_attribs =
(shader->info.attributes_read & VERT_BIT_GENERIC_ALL) >>
VERT_ATTRIB_GENERIC0;
shader->info.attribute_count = util_last_bit(gen_attribs);
}
/* Image attributes start at MAX_VS_ATTRIBS in the VS attribute table,
* and zero in other stages.
*/