/* Add special gl_VertexID/gl_InstanceID buffers */
- panfrost_vertex_id(ctx->padded_count, (union mali_attr *) &bufs[k]);
+ panfrost_vertex_id(ctx->padded_count, &bufs[k], ctx->instance_count > 1);
pan_pack(out + PAN_VERTEX_ID, ATTRIBUTE, cfg) {
cfg.buffer_index = k++;
cfg.format = so->formats[PAN_VERTEX_ID];
}
- panfrost_instance_id(ctx->padded_count, (union mali_attr *) &bufs[k]);
+ panfrost_instance_id(ctx->padded_count, &bufs[k], ctx->instance_count > 1);
pan_pack(out + PAN_INSTANCE_ID, ATTRIBUTE, cfg) {
cfg.buffer_index = k++;
void
panfrost_vertex_id(
unsigned padded_count,
- union mali_attr *attr)
+ struct mali_attribute_buffer_packed *attr,
+ bool instanced)
{
/* 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;
+ pan_pack(attr, ATTRIBUTE_BUFFER, cfg) {
+ cfg.special = MALI_ATTRIBUTE_SPECIAL_VERTEX_ID;
+ cfg.type = 0;
+
+ if (instanced) {
+ cfg.divisor_r = __builtin_ctz(padded_count);
+ cfg.divisor_p = padded_count >> (cfg.divisor_r + 1);
+ } else {
+ /* Match the blob... */
+ cfg.divisor_r = 0x1F;
+ cfg.divisor_p = 0x4;
+ }
+ }
}
void
panfrost_instance_id(
unsigned padded_count,
- union mali_attr *attr)
+ struct mali_attribute_buffer_packed *attr,
+ bool instanced)
{
- attr->elements = MALI_ATTR_INSTANCEID;
- attr->stride = 0;
- attr->extra_flags = 0;
- 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;
+ pan_pack(attr, ATTRIBUTE_BUFFER, cfg) {
+ cfg.special = MALI_ATTRIBUTE_SPECIAL_INSTANCE_ID;
+ cfg.type = 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 (!instanced || padded_count <= 1) {
+ /* Match the blob... */
+ cfg.stride = ((1u << 31) - 1);
+ cfg.divisor_r = 0x1F;
+ cfg.divisor_e = 0x1;
+ } else if(util_is_power_of_two_or_zero(padded_count)) {
+ /* By above, padded_count > 1 => padded_count >= 2 so
+ * since we're a power of two, ctz(padded_count) =
+ * log2(padded_count) >= log2(2) = 1, so
+ * ctz(padded_count) - 1 >= 0, so this can't underflow
+ * */
+
+ cfg.divisor_r = __builtin_ctz(padded_count) - 1;
+ } else {
+ cfg.stride = panfrost_compute_magic_divisor(padded_count,
+ &cfg.divisor_r, &cfg.divisor_e);
+ }
}
}
unsigned
panfrost_compute_magic_divisor(unsigned hw_divisor, unsigned *o_shift, unsigned *extra_flags);
-void panfrost_vertex_id(unsigned padded_count, union mali_attr *attr);
-void panfrost_instance_id(unsigned padded_count, union mali_attr *attr);
+void panfrost_vertex_id(unsigned padded_count, struct mali_attribute_buffer_packed *attr, bool instanced);
+void panfrost_instance_id(unsigned padded_count, struct mali_attribute_buffer_packed *attr, bool instanced);
/* Samplers */