panfrost: Route gl_VertexID through cmdstream
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 19 Dec 2019 19:00:24 +0000 (14:00 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 25 Dec 2019 03:55:04 +0000 (22:55 -0500)
It shows up as a special (magic?) attribute. We could try to be clever
and only include the extra record if gl_VertexID is actually read, but
honestly that's just extra complexity for no good reason. Might as well
just always include it; this won't be a real bottleneck, I don't think.

Fixes dEQP-GLES3.functional.shaders.builtin_variable.vertex_id.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_attributes.c
src/gallium/drivers/panfrost/pan_context.c
src/panfrost/encoder/pan_attributes.c
src/panfrost/encoder/pan_encoder.h

index 68f2333d0ddd73b1d9346fdcc0bfa7593178affe..c19af9f1c5988944e8c6a93e09933928f777fc9c 100644 (file)
@@ -115,6 +115,14 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch)
                 }
         }
 
+        /* Add special gl_VertexID/gl_InstanceID buffers */
+
+        panfrost_vertex_id(ctx->padded_count, &attrs[k]);
+        so->hw[PAN_VERTEX_ID].index = k++;
+
+        panfrost_instance_id(ctx->padded_count, &attrs[k]);
+        so->hw[PAN_INSTANCE_ID].index = k++;
+
         /* Upload whatever we emitted and go */
 
         ctx->payloads[PIPE_SHADER_VERTEX].postfix.attributes =
index 27b6cd7be2f2015a9854defdb0f3ba3b41e0e2ab..4c5308c8238081534415876946e2d008973630b0 100644 (file)
@@ -440,7 +440,7 @@ panfrost_stage_attributes(struct panfrost_context *ctx)
         struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
         struct panfrost_vertex_state *so = ctx->vertex;
 
-        size_t sz = sizeof(struct mali_attr_meta) * so->num_elements;
+        size_t sz = sizeof(struct mali_attr_meta) * PAN_MAX_ATTRIBUTE;
         struct panfrost_transfer transfer = panfrost_allocate_transient(batch, sz);
         struct mali_attr_meta *target = (struct mali_attr_meta *) transfer.cpu;
 
@@ -481,12 +481,17 @@ panfrost_stage_attributes(struct panfrost_context *ctx)
                 /* Also, somewhat obscurely per-instance data needs to be
                  * offset in response to a delayed start in an indexed draw */
 
-                if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start) {
+                if (so->pipe[i].instance_divisor && ctx->instance_count > 1 && start)
                         target[i].src_offset -= buf->stride * start;
-                }
+        }
 
+        /* Let's also include vertex builtins */
 
-        }
+        target[PAN_VERTEX_ID].format = MALI_R32UI;
+        target[PAN_VERTEX_ID].swizzle = panfrost_get_default_swizzle(1);
+
+        target[PAN_INSTANCE_ID].format = MALI_R32UI;
+        target[PAN_INSTANCE_ID].swizzle = panfrost_get_default_swizzle(1);
 
         ctx->payloads[PIPE_SHADER_VERTEX].postfix.attribute_meta = transfer.gpu;
 }
index 9899bf8b169062978f3b6b420aca2f33339d0e7b..d15ed9c1ea19fd99836ca3477fcf7ac9fcfb05d6 100644 (file)
@@ -179,3 +179,43 @@ panfrost_vertex_instanced(
                 return 2;
         }
 }
+
+/* Records for gl_VertexID and gl_InstanceID use a slightly special encoding,
+ * but the idea is the same */
+
+void
+panfrost_vertex_id(
+        unsigned padded_count,
+        union mali_attr *attr)
+{
+        /* We factor the padded count as shift/odd and that's it */
+
+        attr->elements = MALI_ATTR_VERTEXID;
+        attr->shift = __builtin_ctz(padded_count);
+        attr->extra_flags = padded_count >> (attr->shift + 1);
+        attr->stride = attr->size = 0;
+}
+
+void
+panfrost_instance_id(
+        unsigned padded_count,
+        union mali_attr *attr)
+{
+        attr->elements = MALI_ATTR_INSTANCEID;
+        attr->stride = attr->extra_flags = attr->size = 0;
+        
+        /* POT records have just a shift directly with an off-by-one for
+         * unclear reasons. NPOT records have a magic divisor smushed into the
+         * stride field (which is unused for these special records) */
+
+        if (util_is_power_of_two_or_zero(padded_count)) {
+                attr->shift = __builtin_ctz(padded_count) - 1;
+        } else {
+                unsigned shift = 0, flags = 0;
+
+                attr->stride = panfrost_compute_magic_divisor(padded_count, &shift, &flags);
+                attr->shift = shift;
+                attr->extra_flags = flags;
+        }
+}
index 07033ac32c292f4f9898ae2d5630d96b09c6a9cd..1aa9b7b89327acecef495fb3dc8821b5c6e54132 100644 (file)
@@ -98,4 +98,7 @@ panfrost_vertex_instanced(
         unsigned divisor,
         union mali_attr *attrs);
 
+void panfrost_vertex_id(unsigned padded_count, union mali_attr *attr);
+void panfrost_instance_id(unsigned padded_count, union mali_attr *attr);
+
 #endif