From 2f823a54ea98afce1ced9df9f935af31d768811b Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Tue, 6 Aug 2024 09:34:23 +0200 Subject: [PATCH] lavapipe: Implement some functions required by the common BVH framework Acked-by: Mike Blumenkrantz Part-of: --- .../lavapipe/lvp_acceleration_structure.c | 90 +++++++++++++++++++ src/gallium/frontends/lavapipe/lvp_execute.c | 62 +++++++++++++ src/gallium/frontends/lavapipe/lvp_private.h | 19 ++++ 3 files changed, 171 insertions(+) diff --git a/src/gallium/frontends/lavapipe/lvp_acceleration_structure.c b/src/gallium/frontends/lavapipe/lvp_acceleration_structure.c index fea775ad666..c963b3aaf04 100644 --- a/src/gallium/frontends/lavapipe/lvp_acceleration_structure.c +++ b/src/gallium/frontends/lavapipe/lvp_acceleration_structure.c @@ -9,6 +9,96 @@ #include "util/format/format_utils.h" #include "util/half_float.h" +static void +lvp_write_buffer_cp(VkCommandBuffer cmdbuf, VkDeviceAddress addr, + void *data, uint32_t size) +{ + VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf); + + struct vk_cmd_queue_entry *entry = + vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct vk_cmd_queue_entry), + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!entry) + return; + + entry->type = LVP_CMD_WRITE_BUFFER_CP; + + struct lvp_cmd_write_buffer_cp *cmd = + vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct lvp_cmd_write_buffer_cp) + size, + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!entry) { + vk_free(cmd_buffer->vk.cmd_queue.alloc, entry); + return; + } + + cmd->addr = addr; + cmd->data = cmd + 1; + cmd->size = size; + + memcpy(cmd->data, data, size); + + entry->driver_data = cmd; + + list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds); +} + +static void +lvp_flush_buffer_write_cp(VkCommandBuffer cmdbuf) +{ +} + +static void +lvp_cmd_dispatch_unaligned(VkCommandBuffer cmdbuf, uint32_t invocations_x, + uint32_t invocations_y, uint32_t invocations_z) +{ + VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf); + + struct vk_cmd_queue_entry *entry = + vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct vk_cmd_queue_entry), + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!entry) + return; + + entry->type = LVP_CMD_DISPATCH_UNALIGNED; + + entry->u.dispatch.group_count_x = invocations_x; + entry->u.dispatch.group_count_y = invocations_y; + entry->u.dispatch.group_count_z = invocations_z; + + list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds); +} + +static void +lvp_cmd_fill_buffer_addr(VkCommandBuffer cmdbuf, VkDeviceAddress addr, + VkDeviceSize size, uint32_t data) +{ + VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf); + + struct vk_cmd_queue_entry *entry = + vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct vk_cmd_queue_entry), + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!entry) + return; + + entry->type = LVP_CMD_FILL_BUFFER_ADDR; + + struct lvp_cmd_fill_buffer_addr *cmd = + vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(struct lvp_cmd_write_buffer_cp), + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!entry) { + vk_free(cmd_buffer->vk.cmd_queue.alloc, entry); + return; + } + + cmd->addr = addr; + cmd->size = size; + cmd->data = data; + + entry->driver_data = cmd; + + list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds); +} + static_assert(sizeof(struct lvp_bvh_triangle_node) % 8 == 0, "lvp_bvh_triangle_node is not padded"); static_assert(sizeof(struct lvp_bvh_aabb_node) % 8 == 0, "lvp_bvh_aabb_node is not padded"); static_assert(sizeof(struct lvp_bvh_instance_node) % 8 == 0, "lvp_bvh_instance_node is not padded"); diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 197cb945deb..14df435b873 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -4785,6 +4785,55 @@ handle_trace_rays_indirect2(struct vk_cmd_queue_entry *cmd, struct rendering_sta state->pctx->launch_grid(state->pctx, &state->trace_rays_info); } +static void +handle_write_buffer_cp(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) +{ + struct lvp_cmd_write_buffer_cp *write = cmd->driver_data; + + finish_fence(state); + + memcpy((void *)(uintptr_t)write->addr, write->data, write->size); +} + +static void +handle_dispatch_unaligned(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) +{ + assert(cmd->u.dispatch.group_count_y == 1); + assert(cmd->u.dispatch.group_count_z == 1); + + uint32_t last_block_size = state->dispatch_info.block[0]; + + state->dispatch_info.grid[0] = cmd->u.dispatch.group_count_x / last_block_size; + state->dispatch_info.grid[1] = 1; + state->dispatch_info.grid[2] = 1; + state->dispatch_info.grid_base[0] = 0; + state->dispatch_info.grid_base[1] = 0; + state->dispatch_info.grid_base[2] = 0; + state->dispatch_info.indirect = NULL; + state->pctx->launch_grid(state->pctx, &state->dispatch_info); + + if (cmd->u.dispatch.group_count_x % last_block_size) { + state->dispatch_info.block[0] = cmd->u.dispatch.group_count_x % last_block_size; + state->dispatch_info.grid[0] = 1; + state->dispatch_info.grid_base[0] = cmd->u.dispatch.group_count_x / last_block_size; + state->pctx->launch_grid(state->pctx, &state->dispatch_info); + state->dispatch_info.block[0] = last_block_size; + } +} + +static void +handle_fill_buffer_addr(struct vk_cmd_queue_entry *cmd, struct rendering_state *state) +{ + struct lvp_cmd_fill_buffer_addr *fill = cmd->driver_data; + + finish_fence(state); + + uint32_t *dst = (void *)(uintptr_t)fill->addr; + for (uint32_t i = 0; i < fill->size / 4; i++) { + dst[i] = fill->data; + } +} + void lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table *disp) { struct vk_device_dispatch_table cmd_enqueue_dispatch; @@ -4952,6 +5001,19 @@ static void lvp_execute_cmd_buffer(struct list_head *cmds, bool did_flush = false; LIST_FOR_EACH_ENTRY(cmd, cmds, cmd_link) { + if (cmd->type >= VK_CMD_TYPE_COUNT) { + uint32_t type = cmd->type; + if (type == LVP_CMD_WRITE_BUFFER_CP) { + handle_write_buffer_cp(cmd, state); + } else if (type == LVP_CMD_DISPATCH_UNALIGNED) { + emit_compute_state(state); + handle_dispatch_unaligned(cmd, state); + } else if (type == LVP_CMD_FILL_BUFFER_ADDR) { + handle_fill_buffer_addr(cmd, state); + } + continue; + } + if (print_cmds) fprintf(stderr, "%s\n", vk_cmd_queue_type_names[cmd->type]); switch ((unsigned)cmd->type) { diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index 7173cd41f67..4d81d76b472 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -835,6 +835,25 @@ enum vk_cmd_type lvp_ext_dgc_token_to_cmd_type(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token); size_t lvp_ext_dgc_token_size(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token); + +struct lvp_cmd_write_buffer_cp { + VkDeviceAddress addr; + void *data; + uint32_t size; +}; + +struct lvp_cmd_fill_buffer_addr { + VkDeviceAddress addr; + VkDeviceSize size; + uint32_t data; +}; + +enum lvp_cmd_type { + LVP_CMD_WRITE_BUFFER_CP = VK_CMD_TYPE_COUNT, + LVP_CMD_DISPATCH_UNALIGNED, + LVP_CMD_FILL_BUFFER_ADDR, +}; + #ifdef __cplusplus } #endif