summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorChristian Gmeiner <[email protected]>2017-10-19 23:12:46 +0200
committerChristian Gmeiner <[email protected]>2017-10-20 12:42:44 +0200
commit246243d447a081297b9e55de6f5cebcb322a98a9 (patch)
tree76bd15e160932cbb7945f882daf703b221c27a50 /src/gallium
parent282d8698ec4d792a8eeb1a4b1cd8c85b4fd8ac8d (diff)
etnaviv: add support for occlusion queries
Passes most occlusion query piglits. The following piglits are broken: - spec@arb_occlusion_query@occlusion_query_meta_fragments - spec@arb_occlusion_query@occlusion_query_meta_save - spec@arb_occlusion_query2@render v1 -> v2: - use one sample provider for all occlusion queries tyes - add comment about 'magic' value 0x1DF5E76 Signed-off-by: Christian Gmeiner <[email protected]> Reviewed-by: Wladimir J. van der Laan <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_query_hw.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_query_hw.c b/src/gallium/drivers/etnaviv/etnaviv_query_hw.c
index a1dead335c4..0f3cd7257b6 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_query_hw.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_query_hw.c
@@ -30,9 +30,73 @@
#include "util/u_memory.h"
#include "etnaviv_context.h"
+#include "etnaviv_debug.h"
+#include "etnaviv_emit.h"
#include "etnaviv_query_hw.h"
#include "etnaviv_screen.h"
+/*
+ * Occlusion Query:
+ *
+ * OCCLUSION_COUNTER and OCCLUSION_PREDICATE differ only in how they
+ * interpret results
+ */
+
+static void
+occlusion_start(struct etna_hw_query *hq, struct etna_context *ctx)
+{
+ struct etna_resource *rsc = etna_resource(hq->prsc);
+ struct etna_reloc r = {
+ .bo = rsc->bo,
+ .flags = ETNA_RELOC_WRITE
+ };
+
+ if (hq->samples > 63) {
+ hq->samples = 63;
+ BUG("samples overflow");
+ }
+
+ r.offset = hq->samples * 8; /* 64bit value */
+
+ etna_set_state_reloc(ctx->stream, VIVS_GL_OCCLUSION_QUERY_ADDR, &r);
+}
+
+static void
+occlusion_stop(struct etna_hw_query *hq, struct etna_context *ctx)
+{
+ /* 0x1DF5E76 is the value used by blob - but any random value will work */
+ etna_set_state(ctx->stream, VIVS_GL_OCCLUSION_QUERY_CONTROL, 0x1DF5E76);
+}
+
+static void
+occlusion_suspend(struct etna_hw_query *hq, struct etna_context *ctx)
+{
+ occlusion_stop(hq, ctx);
+}
+
+static void
+occlusion_resume(struct etna_hw_query *hq, struct etna_context *ctx)
+{
+ hq->samples++;
+ occlusion_start(hq, ctx);
+}
+
+static void
+occlusion_result(struct etna_hw_query *hq, void *buf,
+ union pipe_query_result *result)
+{
+ uint64_t sum = 0;
+ uint64_t *ptr = (uint64_t *)buf;
+
+ for (unsigned i = 0; i <= hq->samples; i++)
+ sum += *(ptr + i);
+
+ if (hq->base.type == PIPE_QUERY_OCCLUSION_COUNTER)
+ result->u64 = sum;
+ else
+ result->b = !!sum;
+}
+
static void
etna_hw_destroy_query(struct etna_context *ctx, struct etna_query *q)
{
@@ -44,6 +108,14 @@ etna_hw_destroy_query(struct etna_context *ctx, struct etna_query *q)
FREE(hq);
}
+static const struct etna_hw_sample_provider occlusion_provider = {
+ .start = occlusion_start,
+ .stop = occlusion_stop,
+ .suspend = occlusion_suspend,
+ .resume = occlusion_resume,
+ .result = occlusion_result,
+};
+
static void
realloc_query_bo(struct etna_context *ctx, struct etna_hw_query *hq)
{
@@ -153,6 +225,12 @@ static inline const struct etna_hw_sample_provider *
query_sample_provider(unsigned query_type)
{
switch (query_type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ /* fallthrough */
+ case PIPE_QUERY_OCCLUSION_PREDICATE:
+ /* fallthrough */
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+ return &occlusion_provider;
default:
return NULL;
}