.result = timestamp_accumulate_result,
};
+struct PACKED fd6_primitives_sample {
+ struct {
+ uint64_t generated, emitted;
+ } start[4], stop[4], result;
+};
+
+
+#define primitives_relocw(ring, aq, field) \
+ OUT_RELOCW(ring, fd_resource((aq)->prsc)->bo, offsetof(struct fd6_primitives_sample, field), 0, 0);
+#define primitives_reloc(ring, aq, field) \
+ OUT_RELOC(ring, fd_resource((aq)->prsc)->bo, offsetof(struct fd6_primitives_sample, field), 0, 0);
+
+static void
+primitive_counts_resume(struct fd_acc_query *aq, struct fd_batch *batch)
+{
+ struct fd_ringbuffer *ring = batch->draw;
+
+ OUT_PKT4(ring, REG_A6XX_VPC_SO_STREAM_COUNTS_LO, 2);
+ primitives_relocw(ring, aq, start[0]);
+
+ fd6_event_write(batch, ring, WRITE_PRIMITIVE_COUNTS, false);
+}
+
+static void
+primitive_counts_pause(struct fd_acc_query *aq, struct fd_batch *batch)
+{
+ struct fd_ringbuffer *ring = batch->draw;
+
+ OUT_PKT4(ring, REG_A6XX_VPC_SO_STREAM_COUNTS_LO, 2);
+ primitives_relocw(ring, aq, stop[0]);
+
+ fd6_event_write(batch, ring, WRITE_PRIMITIVE_COUNTS, false);
+
+ fd6_event_write(batch, batch->draw, CACHE_FLUSH_TS, true);
+
+ /* result += stop - start: */
+ OUT_PKT7(ring, CP_MEM_TO_MEM, 9);
+ OUT_RING(ring, CP_MEM_TO_MEM_0_DOUBLE |
+ CP_MEM_TO_MEM_0_NEG_C | 0x80000000);
+ primitives_relocw(ring, aq, result.emitted);
+ primitives_reloc(ring, aq, result.emitted);
+ primitives_reloc(ring, aq, stop[aq->base.index].emitted);
+ primitives_reloc(ring, aq, start[aq->base.index].emitted);
+
+ /* result += stop - start: */
+ OUT_PKT7(ring, CP_MEM_TO_MEM, 9);
+ OUT_RING(ring, CP_MEM_TO_MEM_0_DOUBLE |
+ CP_MEM_TO_MEM_0_NEG_C | 0x80000000);
+ primitives_relocw(ring, aq, result.generated);
+ primitives_reloc(ring, aq, result.generated);
+ primitives_reloc(ring, aq, stop[aq->base.index].generated);
+ primitives_reloc(ring, aq, start[aq->base.index].generated);
+}
+
+static void
+primitives_generated_result(struct fd_acc_query *aq, void *buf,
+ union pipe_query_result *result)
+{
+ struct fd6_primitives_sample *ps = buf;
+
+ result->u64 = ps->result.generated;
+}
+
+static const struct fd_acc_sample_provider primitives_generated = {
+ .query_type = PIPE_QUERY_PRIMITIVES_GENERATED,
+ .active = FD_STAGE_DRAW,
+ .size = sizeof(struct fd6_primitives_sample),
+ .resume = primitive_counts_resume,
+ .pause = primitive_counts_pause,
+ .result = primitives_generated_result,
+};
+
+static void
+primitives_emitted_result(struct fd_acc_query *aq, void *buf,
+ union pipe_query_result *result)
+{
+ struct fd6_primitives_sample *ps = buf;
+
+ result->u64 = ps->result.emitted;
+}
+
+static const struct fd_acc_sample_provider primitives_emitted = {
+ .query_type = PIPE_QUERY_PRIMITIVES_EMITTED,
+ .active = FD_STAGE_DRAW,
+ .size = sizeof(struct fd6_primitives_sample),
+ .resume = primitive_counts_resume,
+ .pause = primitive_counts_pause,
+ .result = primitives_emitted_result,
+};
+
/*
* Performance Counter (batch) queries:
*
counters_per_group[entry->gid]++;
}
- q = fd_acc_create_query2(ctx, 0, &perfcntr);
+ q = fd_acc_create_query2(ctx, 0, 0, &perfcntr);
aq = fd_acc_query(q);
/* sample buffer size is based on # of queries: */
fd_acc_query_register_provider(pctx, &time_elapsed);
fd_acc_query_register_provider(pctx, ×tamp);
+
+ fd_acc_query_register_provider(pctx, &primitives_generated);
+ fd_acc_query_register_provider(pctx, &primitives_emitted);
}