From 6d700284ac9b4217af193550cb0b0b43ce36d291 Mon Sep 17 00:00:00 2001 From: Mary Guillemard Date: Wed, 1 Apr 2026 17:30:25 +0200 Subject: [PATCH] nvk: Use SET_PRIMITIVE_TOPOLOGY instead of MME scratch Instead of keeping track of the topology with some scratch value in MME, we can rely on SET_PRIMITIVE_TOPOLOGY to directly set it. This simplify some of the MME codegen but does not seems to have any impact on performance in general. Signed-off-by: Mary Guillemard Reviewed-by: Mel Henning Part-of: --- src/nouveau/vulkan/nvk_cmd_draw.c | 79 ++++++++++++++++++++----------- src/nouveau/vulkan/nvk_mme.h | 1 - 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index ed81e6bd4c3..9d676adc000 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -574,6 +574,7 @@ nvk_push_draw_state_init(struct nvk_queue *queue, struct nv_push *p) P_IMMD(p, NV9097, SET_POINT_CENTER_MODE, V_OGL); P_IMMD(p, NV9097, SET_EDGE_FLAG, V_TRUE); P_IMMD(p, NV9097, SET_SAMPLER_BINDING, V_INDEPENDENTLY); + P_IMMD(p, NV9097, SET_PRIMITIVE_TOPOLOGY_CONTROL, OVERRIDE_USE_SEPARATE_TOPOLOGY_STATE); uint64_t zero_addr = dev->zero_page->va->addr; P_MTHD(p, NV9097, SET_VERTEX_STREAM_SUBSTITUTE_A); @@ -2303,31 +2304,31 @@ vk_to_nv9097_primitive_topology(VkPrimitiveTopology prim) { switch (prim) { case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: - return NV9097_BEGIN_OP_POINTS; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_POINTLIST; case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: - return NV9097_BEGIN_OP_LINES; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_LINELIST; case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: - return NV9097_BEGIN_OP_LINE_STRIP; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_LINESTRIP; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch" case VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA: #pragma GCC diagnostic pop - return NV9097_BEGIN_OP_TRIANGLES; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_TRIANGLELIST; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: - return NV9097_BEGIN_OP_TRIANGLE_STRIP; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_TRIANGLESTRIP; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: - return NV9097_BEGIN_OP_TRIANGLE_FAN; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_LEGACY_TRIANGLEFAN; case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: - return NV9097_BEGIN_OP_LINELIST_ADJCY; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_LINELIST_ADJCY; case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: - return NV9097_BEGIN_OP_LINESTRIP_ADJCY; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_LINESTRIP_ADJCY; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: - return NV9097_BEGIN_OP_TRIANGLELIST_ADJCY; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_TRIANGLELIST_ADJCY; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: - return NV9097_BEGIN_OP_TRIANGLESTRIP_ADJCY; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_TRIANGLESTRIP_ADJCY; case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: - return NV9097_BEGIN_OP_PATCH; + return NV9097_SET_PRIMITIVE_TOPOLOGY_V_PATCHLIST; default: UNREACHABLE("Invalid primitive topology"); } @@ -2341,7 +2342,7 @@ nvk_flush_ia_state(struct nvk_cmd_buffer *cmd) if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY)) { struct nv_push *p = nvk_cmd_buffer_push(cmd, 2); - P_MTHD(p, NV9097, SET_MME_SHADOW_SCRATCH(NVK_MME_SCRATCH_DRAW_TOPOLOGY)); + P_MTHD(p, NV9097, SET_PRIMITIVE_TOPOLOGY); P_INLINE_DATA(p, vk_to_nv9097_primitive_topology(dyn->ia.primitive_topology)); } @@ -4511,27 +4512,36 @@ nvk_mme_build_draw_loop(struct mme_builder *b, { if (b->devinfo->cls_eng3d >= TURING_A) { - struct mme_value draw_control_a = nvk_mme_load_scratch(b, DRAW_TOPOLOGY); - mme_set_field_enum(b, draw_control_a, NVC597_SET_DRAW_CONTROL_A_INSTANCE_ITERATE_ENABLE, TRUE); + uint32_t draw_control_a; + V_NVC597_SET_DRAW_CONTROL_A(draw_control_a, { + .primitive_id = PRIMITIVE_ID_FIRST, + .instance_id = INSTANCE_ID_FIRST, + .split_mode = SPLIT_MODE_NORMAL_BEGIN_NORMAL_END, + .instance_iterate_enable = true, + }); mme_mthd(b, NVC597_SET_DRAW_CONTROL_A); - mme_emit(b, draw_control_a); + mme_emit(b, mme_imm(draw_control_a)); mme_emit(b, instance_count); mme_mthd(b, NVC597_DRAW_VERTEX_ARRAY_BEGIN_END_A); mme_emit(b, first_vertex); mme_emit(b, vertex_count); - - mme_free_reg(b, draw_control_a); } else { - struct mme_value begin = nvk_mme_load_scratch(b, DRAW_TOPOLOGY); + uint32_t begin_initial_value; + V_NVC197_BEGIN(begin_initial_value, { + .primitive_id = PRIMITIVE_ID_FIRST, + .instance_id = INSTANCE_ID_FIRST, + .split_mode = SPLIT_MODE_NORMAL_BEGIN_NORMAL_END, + .instance_iterate_enable = b->devinfo->cls_eng3d >= PASCAL_B, + }); + struct mme_value begin = mme_mov(b, mme_imm(begin_initial_value)); if (b->devinfo->cls_eng3d < PASCAL_B) { mme_start_loop(b, instance_count); } else { mme_mthd(b, NVC197_SET_INSTANCE_COUNT); mme_emit(b, instance_count); - mme_set_field_enum(b, begin, NVC197_BEGIN_INSTANCE_ITERATE_ENABLE, TRUE); } mme_mthd(b, NV9097_BEGIN); @@ -4679,25 +4689,34 @@ nvk_mme_build_draw_indexed_loop(struct mme_builder *b, { if (b->devinfo->cls_eng3d >= TURING_A) { - struct mme_value draw_control_a = nvk_mme_load_scratch(b, DRAW_TOPOLOGY); - mme_set_field_enum(b, draw_control_a, NVC597_SET_DRAW_CONTROL_A_INSTANCE_ITERATE_ENABLE, TRUE); + uint32_t draw_control_a; + V_NVC597_SET_DRAW_CONTROL_A(draw_control_a, { + .primitive_id = PRIMITIVE_ID_FIRST, + .instance_id = INSTANCE_ID_FIRST, + .split_mode = SPLIT_MODE_NORMAL_BEGIN_NORMAL_END, + .instance_iterate_enable = true, + }); mme_mthd(b, NVC597_SET_DRAW_CONTROL_A); - mme_emit(b, draw_control_a); + mme_emit(b, mme_imm(draw_control_a)); mme_emit(b, instance_count); mme_emit(b, first_index); mme_emit(b, index_count); - - mme_free_reg(b, draw_control_a); } else { - struct mme_value begin = nvk_mme_load_scratch(b, DRAW_TOPOLOGY); + uint32_t begin_initial_value; + V_NVC197_BEGIN(begin_initial_value, { + .primitive_id = PRIMITIVE_ID_FIRST, + .instance_id = INSTANCE_ID_FIRST, + .split_mode = SPLIT_MODE_NORMAL_BEGIN_NORMAL_END, + .instance_iterate_enable = b->devinfo->cls_eng3d >= PASCAL_B, + }); + struct mme_value begin = mme_mov(b, mme_imm(begin_initial_value)); if (b->devinfo->cls_eng3d < PASCAL_B) { mme_start_loop(b, instance_count); } else { mme_mthd(b, NVC197_SET_INSTANCE_COUNT); mme_emit(b, instance_count); - mme_set_field_enum(b, begin, NVC197_BEGIN_INSTANCE_ITERATE_ENABLE, TRUE); } mme_mthd(b, NV9097_BEGIN); @@ -5178,7 +5197,13 @@ nvk_mme_xfb_draw_indirect_loop(struct mme_builder *b, struct mme_value instance_count, struct mme_value counter) { - struct mme_value begin = nvk_mme_load_scratch(b, DRAW_TOPOLOGY); + uint32_t begin_initial_value; + V_NVC197_BEGIN(begin_initial_value, { + .primitive_id = PRIMITIVE_ID_FIRST, + .instance_id = INSTANCE_ID_FIRST, + .split_mode = SPLIT_MODE_NORMAL_BEGIN_NORMAL_END, + }); + struct mme_value begin = mme_mov(b, mme_imm(begin_initial_value)); /* NVC197_BEGIN_INSTANCE_ITERATE_ENABLE seems to be incompatible with xfb. * Always use an mme loop instead. diff --git a/src/nouveau/vulkan/nvk_mme.h b/src/nouveau/vulkan/nvk_mme.h index c4c6e44fc31..a4d7f7ba309 100644 --- a/src/nouveau/vulkan/nvk_mme.h +++ b/src/nouveau/vulkan/nvk_mme.h @@ -61,7 +61,6 @@ enum nvk_mme_scratch { NVK_MME_SCRATCH_CS_INVOCATIONS_HI, NVK_MME_SCRATCH_CS_INVOCATIONS_LO, - NVK_MME_SCRATCH_DRAW_TOPOLOGY, NVK_MME_SCRATCH_DRAW_COUNT, NVK_MME_SCRATCH_DRAW_PAD_DW, NVK_MME_SCRATCH_DRAW_IDX,