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++) {
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);
}
};
}
- 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,
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 */
&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 */
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)
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,
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
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);
}
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,
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];
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