radv/nir: lower unassigned vertex attributes to (0,0,0,0)

The spec allows both 0,0,0,0 and 0,0,0,1. Returning all zeroes makes it
consistent with vertex prologs.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35423>
This commit is contained in:
Samuel Pitoiset 2025-03-18 16:19:03 +01:00 committed by Marge Bot
parent 4e46cabb75
commit 99fb1a9bd7
3 changed files with 23 additions and 9 deletions

View file

@ -196,6 +196,11 @@ lower_load_vs_input(nir_builder *b, nir_intrinsic_instr *intrin, lower_vs_inputs
const unsigned bit_size = intrin->def.bit_size;
const unsigned dest_num_components = intrin->def.num_components;
if (!(s->gfx_state->vi.attributes_valid & (1 << location))) {
/* Return early for unassigned attribute reads. */
return nir_imm_zero(b, intrin->def.num_components, intrin->def.bit_size);
}
/* Convert the component offset to bit_size units.
* (Intrinsic component offset is in 32-bit units.)
*
@ -442,19 +447,25 @@ opt_vs_input_to_const(nir_builder *b, nir_intrinsic_instr *intrin, void *state)
const unsigned bit_size = intrin->def.bit_size;
const unsigned component = var->data.location_frac >> (bit_size == 64 ? 1 : 0);
const enum pipe_format attrib_format = gfx_state->vi.vertex_attribute_formats[location];
const struct util_format_description *f = util_format_description(attrib_format);
b->cursor = nir_after_instr(&intrin->instr);
nir_def *res = &intrin->def;
for (unsigned i = 0; i < intrin->def.num_components; i++) {
const unsigned c = i + component;
if (f->swizzle[c] >= f->nr_channels) {
/* Handle input loads that are larger than their format. */
nir_def *channel = oob_input_load_value(b, c, bit_size, !is_integer);
res = nir_vector_insert_imm(b, res, channel, i);
if (gfx_state->vi.attributes_valid & (1 << location)) {
const enum pipe_format attrib_format = gfx_state->vi.vertex_attribute_formats[location];
const struct util_format_description *f = util_format_description(attrib_format);
for (unsigned i = 0; i < intrin->def.num_components; i++) {
const unsigned c = i + component;
if (f->swizzle[c] >= f->nr_channels) {
/* Handle input loads that are larger than their format. */
nir_def *channel = oob_input_load_value(b, c, bit_size, !is_integer);
res = nir_vector_insert_imm(b, res, channel, i);
}
}
} else {
/* Use (0,0,0,0) for unassigned attribute reads. */
res = nir_imm_zero(b, intrin->def.num_components, intrin->def.bit_size);
}
if (res != &intrin->def) {

View file

@ -1852,6 +1852,8 @@ radv_generate_graphics_state_key(const struct radv_device *device, const struct
/* Vertex input state */
if (state->vi) {
key.vi.attributes_valid = state->vi->attributes_valid;
u_foreach_bit (i, state->vi->attributes_valid) {
uint32_t binding = state->vi->attributes[i].binding;
uint32_t offset = state->vi->attributes[i].offset;

View file

@ -137,6 +137,7 @@ struct radv_graphics_state_key {
} ia;
struct {
uint32_t attributes_valid;
uint32_t instance_rate_inputs;
uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
uint8_t vertex_attribute_formats[MAX_VERTEX_ATTRIBS];