diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index 64bd862fa98..eff125472ed 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -1417,3 +1417,59 @@ void lvp_CmdPipelineBarrier( /* TODO finish off this */ cmd_buf_queue(cmd_buffer, cmd); } + +void lvp_CmdDrawIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); + LVP_FROM_HANDLE(lvp_buffer, buf, buffer); + LVP_FROM_HANDLE(lvp_buffer, count_buf, countBuffer); + struct lvp_cmd_buffer_entry *cmd; + + cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDIRECT_COUNT); + if (!cmd) + return; + + cmd->u.draw_indirect_count.offset = offset; + cmd->u.draw_indirect_count.buffer = buf; + cmd->u.draw_indirect_count.count_buffer_offset = countBufferOffset; + cmd->u.draw_indirect_count.count_buffer = count_buf; + cmd->u.draw_indirect_count.max_draw_count = maxDrawCount; + cmd->u.draw_indirect_count.stride = stride; + + cmd_buf_queue(cmd_buffer, cmd); +} + +void lvp_CmdDrawIndexedIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); + LVP_FROM_HANDLE(lvp_buffer, buf, buffer); + LVP_FROM_HANDLE(lvp_buffer, count_buf, countBuffer); + struct lvp_cmd_buffer_entry *cmd; + + cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT); + if (!cmd) + return; + + cmd->u.draw_indirect_count.offset = offset; + cmd->u.draw_indirect_count.buffer = buf; + cmd->u.draw_indirect_count.count_buffer_offset = countBufferOffset; + cmd->u.draw_indirect_count.count_buffer = count_buf; + cmd->u.draw_indirect_count.max_draw_count = maxDrawCount; + cmd->u.draw_indirect_count.stride = stride; + + cmd_buf_queue(cmd_buffer, cmd); +} diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index d2bec928089..91bd18fe90c 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -2283,6 +2283,25 @@ static void handle_resolve_image(struct lvp_cmd_buffer_entry *cmd, } } +static void handle_draw_indirect_count(struct lvp_cmd_buffer_entry *cmd, + struct rendering_state *state, bool indexed) +{ + if (indexed) { + state->info.index_bounds_valid = false; + state->info.index_size = state->index_size; + state->info.index.resource = state->index_buffer; + state->info.max_index = ~0; + } else + state->info.index_size = 0; + state->indirect_info.offset = cmd->u.draw_indirect_count.offset; + state->indirect_info.stride = cmd->u.draw_indirect_count.stride; + state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count; + state->indirect_info.buffer = cmd->u.draw_indirect_count.buffer->bo; + state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset; + state->indirect_info.indirect_draw_count = cmd->u.draw_indirect_count.count_buffer->bo; + state->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info, &state->draw, 1); +} + static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, struct rendering_state *state) { @@ -2426,6 +2445,14 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, case LVP_CMD_EXECUTE_COMMANDS: handle_execute_commands(cmd, state); break; + case LVP_CMD_DRAW_INDIRECT_COUNT: + emit_state(state); + handle_draw_indirect_count(cmd, state, false); + break; + case LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT: + emit_state(state); + handle_draw_indirect_count(cmd, state, true); + break; } } } diff --git a/src/gallium/frontends/lavapipe/lvp_extensions.py b/src/gallium/frontends/lavapipe/lvp_extensions.py index df989e92452..05c5c11b40e 100644 --- a/src/gallium/frontends/lavapipe/lvp_extensions.py +++ b/src/gallium/frontends/lavapipe/lvp_extensions.py @@ -65,7 +65,7 @@ EXTENSIONS = [ Extension('VK_KHR_descriptor_update_template', 1, False), Extension('VK_KHR_device_group', 1, False), Extension('VK_KHR_device_group_creation', 1, False), - Extension('VK_KHR_draw_indirect_count', 1, False), + Extension('VK_KHR_draw_indirect_count', 1, True), Extension('VK_KHR_driver_properties', 1, True), Extension('VK_KHR_external_fence', 1, False), Extension('VK_KHR_external_fence_capabilities', 1, True), diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index 1d00af7d6a3..eb31c3cfb36 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -640,6 +640,8 @@ enum lvp_cmds { LVP_CMD_NEXT_SUBPASS, LVP_CMD_END_RENDER_PASS, LVP_CMD_EXECUTE_COMMANDS, + LVP_CMD_DRAW_INDIRECT_COUNT, + LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT, }; struct lvp_cmd_bind_pipeline { @@ -904,6 +906,15 @@ struct lvp_cmd_execute_commands { struct lvp_cmd_buffer *cmd_buffers[0]; }; +struct lvp_cmd_draw_indirect_count { + VkDeviceSize offset; + struct lvp_buffer *buffer; + VkDeviceSize count_buffer_offset; + struct lvp_buffer *count_buffer; + uint32_t max_draw_count; + uint32_t stride; +}; + struct lvp_cmd_buffer_entry { struct list_head cmd_link; uint32_t cmd_type; @@ -944,6 +955,7 @@ struct lvp_cmd_buffer_entry { struct lvp_cmd_begin_render_pass begin_render_pass; struct lvp_cmd_next_subpass next_subpass; struct lvp_cmd_execute_commands execute_commands; + struct lvp_cmd_draw_indirect_count draw_indirect_count; } u; };