[Mesa-dev] [PATCH v2] panfrost: Take into account a index_bias for glDrawElementsBaseVertex calls

Rohan Garg rohan.garg at collabora.com
Mon Aug 5 14:52:13 UTC 2019


Bifrost does not accept a index_bias and relies instead on a bias correction
offset ( offset_bias_correction ) in order to calculate the unbiased vertex
index.

We need to make sure we adjust offset_start and vertex_count in order to
take into account the index_bias as required by a glDrawElementsBaseVertex
call and then supply a additional offset_bias_correction to the hardware.

Changes for v2:
  * Renamed the draw_start and negative_start variables to something
    more appropriate.

Signed-off-by: Rohan Garg <rohan.garg at collabora.com>
---
 src/gallium/drivers/panfrost/pan_context.c | 17 ++++++++---------
 src/panfrost/include/panfrost-job.h        | 19 ++++++++++++++++---
 src/panfrost/pandecode/decode.c            |  8 ++++----
 3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index 929ffd16605..a2274bf206a 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -694,7 +694,7 @@ panfrost_stage_attributes(struct panfrost_context *ctx)
          * QED.
          */
 
-        unsigned start = ctx->payload_vertex.draw_start;
+        unsigned start = ctx->payload_vertex.offset_start;
 
         for (unsigned i = 0; i < so->num_elements; ++i) {
                 unsigned vbi = so->pipe[i].vertex_buffer_index;
@@ -1633,8 +1633,8 @@ panfrost_draw_vbo(
         if (panfrost_scissor_culls_everything(ctx))
                 return;
 
-        ctx->payload_vertex.draw_start = info->start;
-        ctx->payload_tiler.draw_start = info->start;
+        ctx->payload_vertex.offset_start = info->start;
+        ctx->payload_tiler.offset_start = info->start;
 
         int mode = info->mode;
 
@@ -1671,7 +1671,7 @@ panfrost_draw_vbo(
 
         ctx->payload_tiler.prefix.draw_mode = g2m_draw_mode(mode);
 
-        ctx->vertex_count = info->count;
+        ctx->vertex_count = info->count + info->index_bias;
         ctx->instance_count = info->instance_count;
 
         /* For non-indexed draws, they're the same */
@@ -1720,14 +1720,13 @@ panfrost_draw_vbo(
 
                 /* Use the corresponding values */
                 vertex_count = max_index - min_index + 1;
-                ctx->payload_vertex.draw_start = min_index;
-                ctx->payload_tiler.draw_start = min_index;
+                ctx->payload_vertex.offset_start = min_index + info->index_bias;
+                ctx->payload_tiler.offset_start = min_index + info->index_bias;
 
-                ctx->payload_tiler.prefix.negative_start = -min_index;
+                ctx->payload_tiler.prefix.offset_bias_correction = -min_index;
                 ctx->payload_tiler.prefix.index_count = MALI_POSITIVE(info->count);
 
                 //assert(!info->restart_index); /* TODO: Research */
-                assert(!info->index_bias);
 
                 draw_flags |= panfrost_translate_index_size(info->index_size);
                 ctx->payload_tiler.prefix.indices = panfrost_get_index_buffer_mapped(ctx, info);
@@ -1735,7 +1734,7 @@ panfrost_draw_vbo(
                 /* Index count == vertex count, if no indexing is applied, as
                  * if it is internally indexed in the expected order */
 
-                ctx->payload_tiler.prefix.negative_start = 0;
+                ctx->payload_tiler.prefix.offset_bias_correction = 0;
                 ctx->payload_tiler.prefix.index_count = MALI_POSITIVE(ctx->vertex_count);
 
                 /* Reverse index state */
diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h
index 297d0806adc..35577366bc3 100644
--- a/src/panfrost/include/panfrost-job.h
+++ b/src/panfrost/include/panfrost-job.h
@@ -917,8 +917,21 @@ struct mali_vertex_tiler_prefix {
         u32 workgroups_x_shift_3 : 6;
 
 
-        /* Negative of draw_start for TILER jobs from what I've seen */
-        int32_t negative_start;
+        /* Negative of min_index. This is done in order to identify each vertex
+           in vertex shader runs.
+
+           The hardware adds negative_start in each run, so that absent an
+           index bias, the first vertex processed is genuinely the first
+           vertex (0). But with an index bias, the first vertex process
+           is numbered the same as the bias.
+
+           To represent this more conviniently:
+           current_vertex_index = min_index + index_bias + negative_start
+
+           This is done since the hardware doesn't accept a index_bias
+           and this allows it to recover the unbiased index.
+         */
+        int32_t offset_bias_correction;
         u32 zero1;
 
         /* Like many other strictly nonzero quantities, index_count is
@@ -1062,7 +1075,7 @@ struct midgard_payload_vertex_tiler {
         u8 zero4;
 
         /* Offset for first vertex in buffer */
-        u32 draw_start;
+        u32 offset_start;
 
 	u64 zero5;
 
diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c
index 4eaf09fd342..dd7772f2272 100644
--- a/src/panfrost/pandecode/decode.c
+++ b/src/panfrost/pandecode/decode.c
@@ -1317,8 +1317,8 @@ pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no)
         if (p->index_count)
                 pandecode_prop("index_count = MALI_POSITIVE(%" PRId32 ")", p->index_count + 1);
 
-        if (p->negative_start)
-                pandecode_prop("negative_start = %d", p->negative_start);
+        if (p->offset_bias_correction)
+                pandecode_prop("offset_bias_correction = %d", p->offset_bias_correction);
 
         DYN_MEMORY_PROP(p, job_no, indices);
 
@@ -2160,8 +2160,8 @@ pandecode_vertex_or_tiler_job_mdg(const struct mali_job_descriptor_header *h,
                 pandecode_padded_vertices(v->instance_shift, v->instance_odd);
         }
 
-        if (v->draw_start)
-                pandecode_prop("draw_start = %d", v->draw_start);
+        if (v->offset_start)
+                pandecode_prop("offset_start = %d", v->offset_start);
 
         if (v->zero5) {
                 pandecode_msg("Zero tripped\n");
-- 
2.17.1



More information about the mesa-dev mailing list