From b74000dbce3a18b2ed730c0372193c9e9d0e2312 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 23 Oct 2025 18:27:18 -0400 Subject: [PATCH] nvk: Emit inactive vertex attributes VK_KHR_maintenance9 requires that vertex attributes in shaders which map to vertex attributes that aren't bound at the API return a consistent value. In order to do this, we need toemit SET_VERTEX_ATTRIBUTE_A, even for unused attributes. The RGBA32F format was chosen to ensure we return (0, 0, 0, 0) from unbound attributes. Fixes: 7692d3c0e1a2 ("nvk: Advertise VK_KHR_maintenance9") (cherry picked from commit d39221cef30d5c54b3d7651b6d89ab85c23e0480) Part-of: --- .pick_status.json | 2 +- src/nouveau/vulkan/nvk_cmd_draw.c | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index e0f84ed7673..91c1b7a1ce2 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -184,7 +184,7 @@ "description": "nvk: Emit inactive vertex attributes", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "7692d3c0e1a2b54c82c945335d23fc174252fda1", "notes": null diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index 3d058a4d7f6..56036fb24d9 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -1822,17 +1822,28 @@ nvk_flush_vi_state(struct nvk_cmd_buffer *cmd) if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VI) || BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VI_BINDINGS_VALID)) { - u_foreach_bit(a, dyn->vi->attributes_valid) { - const struct nvk_va_format *fmt = - nvk_get_va_format(pdev, dyn->vi->attributes[a].format); + P_MTHD(p, NV9097, SET_VERTEX_ATTRIBUTE_A(0)); + for (uint32_t a = 0; a < 32; a++) { + if (dyn->vi->attributes_valid & BITFIELD_BIT(a)) { + const struct nvk_va_format *fmt = + nvk_get_va_format(pdev, dyn->vi->attributes[a].format); - P_IMMD(p, NV9097, SET_VERTEX_ATTRIBUTE_A(a), { - .stream = dyn->vi->attributes[a].binding, - .offset = dyn->vi->attributes[a].offset, - .component_bit_widths = fmt->bit_widths, - .numerical_type = fmt->type, - .swap_r_and_b = fmt->swap_rb, - }); + P_NV9097_SET_VERTEX_ATTRIBUTE_A(p, a, { + .stream = dyn->vi->attributes[a].binding, + .source = SOURCE_ACTIVE, + .offset = dyn->vi->attributes[a].offset, + .component_bit_widths = fmt->bit_widths, + .numerical_type = fmt->type, + .swap_r_and_b = fmt->swap_rb, + }); + } else { + P_NV9097_SET_VERTEX_ATTRIBUTE_A(p, a, { + .source = SOURCE_INACTIVE, + /* Using RGBA32 gives us (0, 0, 0, 0) for inactive attributes. */ + .component_bit_widths = COMPONENT_BIT_WIDTHS_R32_G32_B32_A32, + .numerical_type = NUMERICAL_TYPE_NUM_FLOAT, + }); + } } u_foreach_bit(b, dyn->vi->bindings_valid) {