nvk: Use SET_PRIMITIVE_TOPOLOGY instead of MME scratch
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

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 <mary@mary.zone>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40749>
This commit is contained in:
Mary Guillemard 2026-04-01 17:30:25 +02:00 committed by Marge Bot
parent bbed00ac81
commit 6d700284ac
2 changed files with 52 additions and 28 deletions

View file

@ -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.

View file

@ -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,