diff options
-rw-r--r-- | src/freedreno/vulkan/tu_cmd_buffer.c | 20 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_pipeline.c | 28 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_private.h | 9 |
3 files changed, 25 insertions, 32 deletions
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 |