diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index 56e430239fb..93d20cb5ab3 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -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; } } diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 01b75698d6a..f039a3d8430 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -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. */