From 33cd22cd8cbbfbee0ff388d580b6ae5ea2c59288 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 3 Dec 2025 22:34:13 -0500 Subject: [PATCH] panvk/csf: Emit varying descriptors based on the VS varying layout Co-authored-by: Lorenzo Rossi Reviewed-by: Lorenzo Rossi Acked-by: Eric R. Smith Part-of: --- src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c | 69 ++++++++++----------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c index d87966be9a5..dedb15ee110 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c @@ -363,53 +363,52 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf, return VK_SUCCESS; } -static uint32_t -get_varying_slots(const struct panvk_cmd_buffer *cmdbuf) +static void +emit_varying_descs(const struct panvk_cmd_buffer *cmdbuf, + struct mali_attribute_packed *descs) { const struct panvk_shader_variant *vs = panvk_shader_hw_variant(cmdbuf->state.gfx.vs.shader); const struct panvk_shader_variant *fs = panvk_shader_only_variant(get_fs(cmdbuf)); - uint32_t varying_slots = 0; - if (fs) { - unsigned vs_vars = vs->info.varyings.output_count; - unsigned fs_vars = fs->info.varyings.input_count; - varying_slots = MAX2(vs_vars, fs_vars); - } + const struct pan_varying_layout *vs_layout = &vs->info.varyings.formats; + const struct pan_varying_layout *fs_format = &fs->info.varyings.formats; + pan_varying_layout_require_layout(vs_layout); + pan_varying_layout_require_format(fs_format); - return varying_slots; -} + for (uint32_t i = 0; i < fs_format->count; i++) { + const struct pan_varying_slot *fs_slot = + pan_varying_layout_slot_at(fs_format, i); -static void -emit_varying_descs(const struct panvk_cmd_buffer *cmdbuf, - struct mali_attribute_packed *descs) -{ - uint32_t varying_slots = get_varying_slots(cmdbuf); - /* Assumes 16 byte slots. We could do better. */ - uint32_t varying_size = varying_slots * 16; - - const struct panvk_shader_variant *fs = - panvk_shader_only_variant(get_fs(cmdbuf)); - - for (uint32_t i = 0; i < varying_slots; i++) { - const struct pan_shader_varying *var = &fs->info.varyings.input[i]; - /* Skip special varyings. */ - if (var->location < VARYING_SLOT_VAR0) + /* Skip empty slots and special varyings. */ + if (!fs_slot || fs_slot->section != PAN_VARYING_SECTION_GENERIC) continue; - uint32_t loc = var->location - VARYING_SLOT_VAR0; + unsigned offset = 0; + enum pipe_format format = PIPE_FORMAT_NONE; + + const struct pan_varying_slot *vs_slot = + pan_varying_layout_find_slot(vs_layout, fs_slot->location); + if (vs_slot) { + nir_alu_type base_type = nir_alu_type_get_base_type(fs_slot->alu_type); + nir_alu_type bit_size = nir_alu_type_get_type_size(vs_slot->alu_type); + + offset = vs_slot->offset; + format = pan_varying_format(base_type | bit_size, vs_slot->ncomps); + } + pan_pack(&descs[i], ATTRIBUTE, cfg) { cfg.attribute_type = MALI_ATTRIBUTE_TYPE_VERTEX_PACKET; cfg.offset_enable = false; - cfg.format = GENX(pan_format_from_pipe_format)(var->format)->hw; + cfg.format = GENX(pan_format_from_pipe_format)(format)->hw; cfg.table = 61; cfg.frequency = MALI_ATTRIBUTE_FREQUENCY_VERTEX; - cfg.offset = 1024 + (loc * 16); + cfg.offset = 1024 + offset; /* On v12+, the hardware-controlled buffer is at index 1 for varyings */ cfg.buffer_index = PAN_ARCH >= 12 ? 1 : 0; - cfg.attribute_stride = varying_size; - cfg.packet_stride = varying_size + 16; + cfg.attribute_stride = vs_layout->generic_size_B; + cfg.packet_stride = vs_layout->generic_size_B + 16; } } } @@ -1671,7 +1670,9 @@ prepare_fs(struct panvk_cmd_buffer *cmdbuf) panvk_get_cs_builder(cmdbuf, PANVK_SUBQUEUE_VERTEX_TILER); if (fs && - (gfx_state_dirty(cmdbuf, FS) || gfx_state_dirty(cmdbuf, DESC_STATE))) { + (gfx_state_dirty(cmdbuf, VS) || + gfx_state_dirty(cmdbuf, FS) || + gfx_state_dirty(cmdbuf, DESC_STATE))) { VkResult result = prepare_fs_driver_set(cmdbuf); if (result != VK_SUCCESS) return result; @@ -2350,15 +2351,13 @@ prepare_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) if (result != VK_SUCCESS) return result; - /* Assumes 16 byte slots. We could do better. */ - uint32_t varying_size = get_varying_slots(cmdbuf) * 16; - cs_update_vt_ctx(b) { prepare_index_buffer(cmdbuf, draw); set_tiler_idvs_flags(b, cmdbuf, draw); - cs_move32_to(b, cs_sr_reg32(b, IDVS, VARY_SIZE), varying_size); + cs_move32_to(b, cs_sr_reg32(b, IDVS, VARY_SIZE), + vs->info.varyings.formats.generic_size_B); struct pan_earlyzs_state earlyzs = {0};