From 6f9319f60fbef06e1fae7d0f427c72161c38a6a2 Mon Sep 17 00:00:00 2001 From: George Ouzounoudis Date: Fri, 4 Nov 2022 22:28:17 +0200 Subject: [PATCH] nvk: Support base instance in instanced draw calls Vulkan's gl_InstanceIndex is different than OpenGL gl_InstanceID. For nvk, gl_InstanceIndex is lowered as gl_BaseInstance + gl_InstanceID in nir code. This means we need to supply base instance to the vertex shader. We load the value at mme draw time to a root constant, as it seems there is no existing system value corresponding to this info. Part-of: --- src/nouveau/vulkan/nvk_cmd_buffer.h | 6 ++++++ src/nouveau/vulkan/nvk_cmd_draw.c | 18 +++++++++++++++++- src/nouveau/vulkan/nvk_shader.c | 4 ++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.h b/src/nouveau/vulkan/nvk_cmd_buffer.h index 331cdafde1e..abf6d44f364 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.h +++ b/src/nouveau/vulkan/nvk_cmd_buffer.h @@ -21,6 +21,12 @@ struct nvk_push_descriptor_set; /** Root descriptor table. This gets pushed to the GPU directly */ struct nvk_root_descriptor_table { union { + struct { + uint32_t base_vertex; + uint32_t base_instance; + uint32_t draw_id; + uint32_t _pad[5]; + } draw; struct { uint32_t block_size[3]; uint32_t grid_size[3]; diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index de535d4ba97..7a218835857 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -33,7 +33,7 @@ nvk_queue_init_context_draw_state(struct nvk_queue *queue) { struct nvk_device *dev = nvk_queue_device(queue); - uint32_t push_data[768]; + uint32_t push_data[1024]; struct nv_push push; nv_push_init(&push, push_data, ARRAY_SIZE(push_data)); struct nv_push *p = &push; @@ -1433,6 +1433,14 @@ nvk_build_mme_draw(struct mme_builder *b, struct mme_value begin) struct mme_value first_vertex = mme_load(b); struct mme_value first_instance = mme_load(b); + // load base instance in root descriptor + const uint32_t base_instance_offset = + nvk_root_descriptor_offset(draw.base_instance); + mme_mthd(b, NV9097_LOAD_CONSTANT_BUFFER_OFFSET); + mme_emit(b, mme_imm(base_instance_offset)); + mme_mthd(b, NV9097_LOAD_CONSTANT_BUFFER(0)); + mme_emit(b, first_instance); + mme_mthd(b, NV9097_SET_GLOBAL_BASE_VERTEX_INDEX); mme_emit(b, mme_zero()); @@ -1511,6 +1519,14 @@ nvk_mme_build_draw_indexed(struct mme_builder *b, struct mme_value vertex_offset = mme_load(b); struct mme_value first_instance = mme_load(b); + // load base instance in root descriptor + const uint32_t base_instance_offset = + nvk_root_descriptor_offset(draw.base_instance); + mme_mthd(b, NV9097_LOAD_CONSTANT_BUFFER_OFFSET); + mme_emit(b, mme_imm(base_instance_offset)); + mme_mthd(b, NV9097_LOAD_CONSTANT_BUFFER(0)); + mme_emit(b, first_instance); + mme_mthd(b, NV9097_SET_GLOBAL_BASE_VERTEX_INDEX); mme_emit(b, vertex_offset); diff --git a/src/nouveau/vulkan/nvk_shader.c b/src/nouveau/vulkan/nvk_shader.c index 08ad84443b6..fd4a38736fc 100644 --- a/src/nouveau/vulkan/nvk_shader.c +++ b/src/nouveau/vulkan/nvk_shader.c @@ -668,10 +668,10 @@ nvk_compile_nir(struct nvk_physical_device *device, nir_shader *nir, info->bin.smemSize = shader->cp.smem_size; info->dbgFlags = debug_get_num_option("NV50_PROG_DEBUG", 0); info->optLevel = debug_get_num_option("NV50_PROG_OPTIMIZE", 3); - info->io.auxCBSlot = 15; + info->io.auxCBSlot = 1; info->io.uboInfoBase = 0; + info->io.drawInfoBase = 0; if (nir->info.stage == MESA_SHADER_COMPUTE) { - info->io.auxCBSlot = 1; info->prop.cp.gridInfoBase = 0; } else { info->assignSlots = nvc0_program_assign_varying_slots;