mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-15 19:40:30 +01:00
anv: implement draw calls for EXT_mesh_shader
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18371>
This commit is contained in:
parent
637063ffc6
commit
d5dedecfe7
1 changed files with 157 additions and 7 deletions
|
|
@ -4570,16 +4570,42 @@ genX(CmdDrawMeshTasksNV)(
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
genX(CmdDrawMeshTasksEXT)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t z)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
if (anv_batch_has_error(&cmd_buffer->batch))
|
||||
return;
|
||||
|
||||
/* TODO(mesh): Check if this is not emitting more packets than we need. */
|
||||
genX(cmd_buffer_flush_state)(cmd_buffer);
|
||||
|
||||
if (cmd_buffer->state.conditional_render_enabled)
|
||||
genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DMESH_3D), m) {
|
||||
m.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
|
||||
m.ThreadGroupCountX = x;
|
||||
m.ThreadGroupCountY = y;
|
||||
m.ThreadGroupCountZ = z;
|
||||
}
|
||||
}
|
||||
|
||||
#define GFX125_3DMESH_TG_COUNT 0x26F0
|
||||
#define GFX125_3DMESH_STARTING_TGID 0x26F4
|
||||
#define GFX10_3DPRIM_XP(n) (0x2690 + (n) * 4) /* n = { 0, 1, 2 } */
|
||||
|
||||
static void
|
||||
mesh_load_indirect_parameters(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct mi_builder *b,
|
||||
struct anv_address addr,
|
||||
bool emit_xp0,
|
||||
uint32_t xp0)
|
||||
mesh_load_indirect_parameters_3dmesh_1d(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct mi_builder *b,
|
||||
struct anv_address addr,
|
||||
bool emit_xp0,
|
||||
uint32_t xp0)
|
||||
{
|
||||
const size_t taskCountOff = offsetof(VkDrawMeshTasksIndirectCommandNV, taskCount);
|
||||
const size_t firstTaskOff = offsetof(VkDrawMeshTasksIndirectCommandNV, firstTask);
|
||||
|
|
@ -4608,6 +4634,44 @@ emit_indirect_3dmesh_1d(struct anv_batch *batch,
|
|||
dw[len - 1] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mesh_load_indirect_parameters_3dmesh_3d(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct mi_builder *b,
|
||||
struct anv_address addr,
|
||||
bool emit_xp0,
|
||||
uint32_t xp0)
|
||||
{
|
||||
const size_t groupCountXOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, groupCountX);
|
||||
const size_t groupCountYOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, groupCountY);
|
||||
const size_t groupCountZOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, groupCountZ);
|
||||
|
||||
mi_store(b, mi_reg32(GFX125_3DMESH_TG_COUNT),
|
||||
mi_mem32(anv_address_add(addr, groupCountXOff)));
|
||||
|
||||
mi_store(b, mi_reg32(GFX10_3DPRIM_XP(1)),
|
||||
mi_mem32(anv_address_add(addr, groupCountYOff)));
|
||||
|
||||
mi_store(b, mi_reg32(GFX10_3DPRIM_XP(2)),
|
||||
mi_mem32(anv_address_add(addr, groupCountZOff)));
|
||||
|
||||
if (emit_xp0)
|
||||
mi_store(b, mi_reg32(GFX10_3DPRIM_XP(0)), mi_imm(xp0));
|
||||
}
|
||||
|
||||
static void
|
||||
emit_indirect_3dmesh_3d(struct anv_batch *batch,
|
||||
bool predicate_enable,
|
||||
bool uses_drawid)
|
||||
{
|
||||
uint32_t len = GENX(3DMESH_3D_length) + uses_drawid;
|
||||
uint32_t *dw = anv_batch_emitn(batch, len, GENX(3DMESH_3D),
|
||||
.PredicateEnable = predicate_enable,
|
||||
.IndirectParameterEnable = true,
|
||||
.ExtendedParameter0Present = uses_drawid);
|
||||
if (uses_drawid)
|
||||
dw[len - 1] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
genX(CmdDrawMeshTasksIndirectNV)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
|
|
@ -4639,7 +4703,7 @@ genX(CmdDrawMeshTasksIndirectNV)(
|
|||
for (uint32_t i = 0; i < drawCount; i++) {
|
||||
struct anv_address draw = anv_address_add(buffer->address, offset);
|
||||
|
||||
mesh_load_indirect_parameters(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
mesh_load_indirect_parameters_3dmesh_1d(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
|
||||
emit_indirect_3dmesh_1d(&cmd_buffer->batch,
|
||||
cmd_state->conditional_render_enabled, uses_drawid);
|
||||
|
|
@ -4648,6 +4712,46 @@ genX(CmdDrawMeshTasksIndirectNV)(
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
genX(CmdDrawMeshTasksIndirectEXT)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
VkDeviceSize offset,
|
||||
uint32_t drawCount,
|
||||
uint32_t stride)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
||||
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||
const struct brw_task_prog_data *task_prog_data = get_task_prog_data(pipeline);
|
||||
const struct brw_mesh_prog_data *mesh_prog_data = get_mesh_prog_data(pipeline);
|
||||
struct anv_cmd_state *cmd_state = &cmd_buffer->state;
|
||||
|
||||
if (anv_batch_has_error(&cmd_buffer->batch))
|
||||
return;
|
||||
|
||||
genX(cmd_buffer_flush_state)(cmd_buffer);
|
||||
|
||||
if (cmd_state->conditional_render_enabled)
|
||||
genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
|
||||
|
||||
bool uses_drawid = (task_prog_data && task_prog_data->uses_drawid) ||
|
||||
mesh_prog_data->uses_drawid;
|
||||
struct mi_builder b;
|
||||
mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
|
||||
|
||||
for (uint32_t i = 0; i < drawCount; i++) {
|
||||
struct anv_address draw = anv_address_add(buffer->address, offset);
|
||||
|
||||
mesh_load_indirect_parameters_3dmesh_3d(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
|
||||
emit_indirect_3dmesh_3d(&cmd_buffer->batch,
|
||||
cmd_state->conditional_render_enabled, uses_drawid);
|
||||
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genX(CmdDrawMeshTasksIndirectCountNV)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
|
|
@ -4685,13 +4789,59 @@ genX(CmdDrawMeshTasksIndirectCountNV)(
|
|||
|
||||
emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
|
||||
|
||||
mesh_load_indirect_parameters(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
mesh_load_indirect_parameters_3dmesh_1d(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
|
||||
emit_indirect_3dmesh_1d(&cmd_buffer->batch, true, uses_drawid);
|
||||
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genX(CmdDrawMeshTasksIndirectCountEXT)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
VkDeviceSize offset,
|
||||
VkBuffer _countBuffer,
|
||||
VkDeviceSize countBufferOffset,
|
||||
uint32_t maxDrawCount,
|
||||
uint32_t stride)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
|
||||
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||
const struct brw_task_prog_data *task_prog_data = get_task_prog_data(pipeline);
|
||||
const struct brw_mesh_prog_data *mesh_prog_data = get_mesh_prog_data(pipeline);
|
||||
|
||||
if (anv_batch_has_error(&cmd_buffer->batch))
|
||||
return;
|
||||
|
||||
genX(cmd_buffer_flush_state)(cmd_buffer);
|
||||
|
||||
bool uses_drawid = (task_prog_data && task_prog_data->uses_drawid) ||
|
||||
mesh_prog_data->uses_drawid;
|
||||
|
||||
struct mi_builder b;
|
||||
mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
|
||||
|
||||
struct mi_value max =
|
||||
prepare_for_draw_count_predicate(cmd_buffer, &b,
|
||||
count_buffer, countBufferOffset);
|
||||
|
||||
for (uint32_t i = 0; i < maxDrawCount; i++) {
|
||||
struct anv_address draw = anv_address_add(buffer->address, offset);
|
||||
|
||||
emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
|
||||
|
||||
mesh_load_indirect_parameters_3dmesh_3d(cmd_buffer, &b, draw, uses_drawid, i);
|
||||
|
||||
emit_indirect_3dmesh_3d(&cmd_buffer->batch, true, uses_drawid);
|
||||
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GFX_VERx10 >= 125 */
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue