aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2020-06-03 17:07:06 -0700
committerMarge Bot <[email protected]>2020-06-04 19:42:54 +0000
commitec98cff6a9a1e1df7d5ea5a31a0341425eccd64f (patch)
tree4fc37c4d1b935c83e13df5c82ca112acce0d3747
parent5c9728d960714b1c5eb4806a80157ce95992fcfe (diff)
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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5321>
-rw-r--r--src/freedreno/vulkan/tu_cmd_buffer.c20
-rw-r--r--src/freedreno/vulkan/tu_pipeline.c28
-rw-r--r--src/freedreno/vulkan/tu_private.h9
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