From 52942f18c60253ad79f7d7fa26775bda83860e8a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Jun 2020 10:10:01 -0700 Subject: [PATCH] turnip: Move vertex buffer bindings to SET_DRAW_STATE. This means that the HW can skip over the vertex buffer state when it's not used in a bin. The blob also has this behavior. Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 70 +++++++++++++++++----------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index b7eae22962e..7c76a08b4ba 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -1743,6 +1743,10 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer, return VK_SUCCESS; } +/* Sets vertex buffers to HW binding points. We emit VBs in SDS (so that bin + * rendering can skip over unused state), so we need to collect all the + * bindings together into a single state emit at draw time. + */ void tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, @@ -1755,12 +1759,14 @@ tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer, assert(firstBinding + bindingCount <= MAX_VBS); for (uint32_t i = 0; i < bindingCount; i++) { - cmd->state.vb.buffers[firstBinding + i] = - tu_buffer_from_handle(pBuffers[i]); + struct tu_buffer *buf = tu_buffer_from_handle(pBuffers[i]); + + cmd->state.vb.buffers[firstBinding + i] = buf; cmd->state.vb.offsets[firstBinding + i] = pOffsets[i]; + + tu_bo_list_add(&cmd->bo_list, buf->bo, MSM_SUBMIT_BO_READ); } - /* VB states depend on VkPipelineVertexInputStateCreateInfo */ cmd->state.dirty |= TU_CMD_DIRTY_VERTEX_BUFFERS; } @@ -2469,6 +2475,7 @@ enum tu_draw_state_group_id { TU_DRAW_STATE_PROGRAM, TU_DRAW_STATE_PROGRAM_BINNING, + TU_DRAW_STATE_VB, TU_DRAW_STATE_VI, TU_DRAW_STATE_VI_BINNING, TU_DRAW_STATE_VP, @@ -2656,6 +2663,30 @@ tu6_emit_vs_params(struct tu_cmd_buffer *cmd, return VK_SUCCESS; } +static struct tu_cs_entry +tu6_emit_vertex_buffers(struct tu_cmd_buffer *cmd, + const struct tu_pipeline *pipeline) +{ + struct tu_cs cs; + tu_cs_begin_sub_stream(&cmd->sub_cs, 4 * MAX_VBS, &cs); + + for (uint32_t i = 0; i < pipeline->vi.count; i++) { + const uint32_t binding = pipeline->vi.bindings[i]; + const struct tu_buffer *buf = cmd->state.vb.buffers[binding]; + const VkDeviceSize offset = buf->bo_offset + + cmd->state.vb.offsets[binding]; + const VkDeviceSize size = + offset < buf->size ? buf->size - offset : 0; + + tu_cs_emit_regs(&cs, + A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset), + A6XX_VFD_FETCH_SIZE(i, size)); + + } + + return tu_cs_end_sub_stream(&cmd->sub_cs, &cs); +} + static VkResult tu6_emit_descriptor_sets(struct tu_cmd_buffer *cmd, const struct tu_pipeline *pipeline, @@ -2909,22 +2940,6 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd, tu6_emit_scissor(cs, &cmd->state.dynamic.scissor.scissors[0]); } - if (cmd->state.dirty & - (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) { - for (uint32_t i = 0; i < pipeline->vi.count; i++) { - const uint32_t binding = pipeline->vi.bindings[i]; - const struct tu_buffer *buf = cmd->state.vb.buffers[binding]; - const VkDeviceSize offset = buf->bo_offset + - cmd->state.vb.offsets[binding]; - const VkDeviceSize size = - offset < buf->size ? buf->size - offset : 0; - - tu_cs_emit_regs(cs, - A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset), - A6XX_VFD_FETCH_SIZE(i, size)); - } - } - if (cmd->state.dirty & TU_CMD_DIRTY_PIPELINE) { draw_state_groups[draw_state_group_count++] = (struct tu_draw_state_group) { @@ -2998,6 +3013,16 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd, }; } + if (cmd->state.dirty & + (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) { + draw_state_groups[draw_state_group_count++] = + (struct tu_draw_state_group) { + .id = TU_DRAW_STATE_VB, + .enable_mask = ENABLE_ALL, + .ib = tu6_emit_vertex_buffers(cmd, pipeline) + }; + } + if (cmd->state.dirty & TU_CMD_DIRTY_STREAMOUT_BUFFERS) tu6_emit_streamout(cmd, cs); @@ -3122,13 +3147,6 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd, tu_cs_sanity_check(cs); /* track BOs */ - if (cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) { - for (uint32_t i = 0; i < MAX_VBS; i++) { - const struct tu_buffer *buf = cmd->state.vb.buffers[i]; - if (buf) - tu_bo_list_add(&cmd->bo_list, buf->bo, MSM_SUBMIT_BO_READ); - } - } if (cmd->state.dirty & TU_CMD_DIRTY_DESCRIPTOR_SETS) { unsigned i; for_each_bit(i, descriptors_state->valid) { -- 2.30.2