From: Eric Anholt Date: Thu, 4 Jun 2020 00:07:06 +0000 (-0700) Subject: turnip: Simplify vertex buffer bindings. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec98cff6a9a1e1df7d5ea5a31a0341425eccd64f;p=mesa.git turnip: Simplify vertex buffer bindings. We were remapping the bindings so the HW binding points were consecutive, which there's no need for. Now that we don't shuffle, we can mostly drop the dependency on the pipeline for this SDS. Part-of: --- diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index a67a5838264..a1f690288d7 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2009,6 +2009,13 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, break; } + /* If the new pipeline requires more VBs than we had previously set up, we + * need to re-emit them in SDS. If it requires the same set or fewer, we + * can just re-use the old SDS. + */ + if (pipeline->vi.bindings_used & ~cmd->vertex_bindings_set) + cmd->state.dirty |= TU_CMD_DIRTY_VERTEX_BUFFERS; + tu_bo_list_add(&cmd->bo_list, &pipeline->program.binary_bo, MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP); for (uint32_t i = 0; i < pipeline->cs.bo_count; i++) { @@ -2670,18 +2677,20 @@ tu6_emit_vertex_buffers(struct tu_cmd_buffer *cmd, 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]; + int binding; + for_each_bit(binding, pipeline->vi.bindings_used) { const struct tu_buffer *buf = cmd->state.vb.buffers[binding]; const VkDeviceSize offset = buf->bo_offset + cmd->state.vb.offsets[binding]; tu_cs_emit_regs(&cs, - A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset), - A6XX_VFD_FETCH_SIZE(i, buf->size - offset)); + A6XX_VFD_FETCH_BASE(binding, .bo = buf->bo, .bo_offset = offset), + A6XX_VFD_FETCH_SIZE(binding, buf->size - offset)); } + cmd->vertex_bindings_set = pipeline->vi.bindings_used; + return tu_cs_end_sub_stream(&cmd->sub_cs, &cs); } @@ -3011,8 +3020,7 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd, }; } - if (cmd->state.dirty & - (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) { + if (cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) { draw_state_groups[draw_state_group_count++] = (struct tu_draw_state_group) { .id = TU_DRAW_STATE_VB, diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 5002f9f6f2a..4b04a98dd25 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -1621,10 +1621,8 @@ static void tu6_emit_vertex_input(struct tu_cs *cs, const struct ir3_shader_variant *vs, const VkPipelineVertexInputStateCreateInfo *info, - uint8_t bindings[MAX_VERTEX_ATTRIBS], - uint32_t *count) + uint32_t *bindings_used) { - uint32_t vfd_fetch_idx = 0; uint32_t vfd_decode_idx = 0; uint32_t binding_instanced = 0; /* bitmask of instanced bindings */ @@ -1633,13 +1631,12 @@ tu6_emit_vertex_input(struct tu_cs *cs, &info->pVertexBindingDescriptions[i]; tu_cs_emit_regs(cs, - A6XX_VFD_FETCH_STRIDE(vfd_fetch_idx, binding->stride)); + A6XX_VFD_FETCH_STRIDE(binding->binding, binding->stride)); if (binding->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) binding_instanced |= 1 << binding->binding; - bindings[vfd_fetch_idx] = binding->binding; - vfd_fetch_idx++; + *bindings_used |= 1 << binding->binding; } /* TODO: emit all VFD_DECODE/VFD_DEST_CNTL in same (two) pkt4 */ @@ -1647,13 +1644,7 @@ tu6_emit_vertex_input(struct tu_cs *cs, for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) { const VkVertexInputAttributeDescription *attr = &info->pVertexAttributeDescriptions[i]; - uint32_t binding_idx, input_idx; - - for (binding_idx = 0; binding_idx < vfd_fetch_idx; binding_idx++) { - if (bindings[binding_idx] == attr->binding) - break; - } - assert(binding_idx < vfd_fetch_idx); + uint32_t input_idx; for (input_idx = 0; input_idx < vs->inputs_count; input_idx++) { if ((vs->inputs[input_idx].slot - VERT_ATTRIB_GENERIC0) == attr->location) @@ -1667,7 +1658,7 @@ tu6_emit_vertex_input(struct tu_cs *cs, const struct tu_native_format format = tu6_format_vtx(attr->format); tu_cs_emit_regs(cs, A6XX_VFD_DECODE_INSTR(vfd_decode_idx, - .idx = binding_idx, + .idx = attr->binding, .offset = attr->offset, .instanced = binding_instanced & (1 << attr->binding), .format = format.fmt, @@ -1686,10 +1677,8 @@ tu6_emit_vertex_input(struct tu_cs *cs, tu_cs_emit_regs(cs, A6XX_VFD_CONTROL_0( - .fetch_cnt = vfd_fetch_idx, + .fetch_cnt = info->vertexBindingDescriptionCount, .decode_cnt = vfd_decode_idx)); - - *count = vfd_fetch_idx; } static uint32_t @@ -2317,15 +2306,14 @@ tu_pipeline_builder_parse_vertex_input(struct tu_pipeline_builder *builder, tu_cs_begin_sub_stream(&pipeline->cs, MAX_VERTEX_ATTRIBS * 7 + 2, &vi_cs); tu6_emit_vertex_input(&vi_cs, &vs->variants[0], vi_info, - pipeline->vi.bindings, &pipeline->vi.count); + &pipeline->vi.bindings_used); pipeline->vi.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &vi_cs); if (vs->has_binning_pass) { tu_cs_begin_sub_stream(&pipeline->cs, MAX_VERTEX_ATTRIBS * 7 + 2, &vi_cs); tu6_emit_vertex_input( - &vi_cs, &vs->variants[1], vi_info, pipeline->vi.binning_bindings, - &pipeline->vi.binning_count); + &vi_cs, &vs->variants[1], vi_info, &pipeline->vi.bindings_used); pipeline->vi.binning_state_ib = tu_cs_end_sub_stream(&pipeline->cs, &vi_cs); } diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index eabc4a335bd..4d70bdc9e36 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -878,6 +878,7 @@ enum tu_cmd_dirty_bits TU_CMD_DIRTY_PIPELINE = 1 << 0, TU_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 1, TU_CMD_DIRTY_VERTEX_BUFFERS = 1 << 2, + TU_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 3, TU_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 4, TU_CMD_DIRTY_PUSH_CONSTANTS = 1 << 5, @@ -1027,6 +1028,7 @@ struct tu_cmd_buffer struct tu_cmd_state state; struct tu_vertex_binding vertex_bindings[MAX_VBS]; + uint32_t vertex_bindings_set; uint32_t queue_family_index; uint32_t push_constants[MAX_PUSH_CONSTANTS_SIZE / 4]; @@ -1242,14 +1244,9 @@ struct tu_pipeline struct { - uint8_t bindings[MAX_VERTEX_ATTRIBS]; - uint32_t count; - - uint8_t binning_bindings[MAX_VERTEX_ATTRIBS]; - uint32_t binning_count; - struct tu_cs_entry state_ib; struct tu_cs_entry binning_state_ib; + uint32_t bindings_used; } vi; struct