swr: fix build with mingw
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_query_acc.c
index a1628534d277657c42a25da5e9e6e0040c86be4c..789f1234f3204f25bae74ee4987e9160ab908419 100644 (file)
 #include "etnaviv_query_acc.h"
 #include "etnaviv_screen.h"
 
-/*
- * Occlusion Query:
- *
- * OCCLUSION_COUNTER and OCCLUSION_PREDICATE differ only in how they
- * interpret results
- */
-
-static void
-occlusion_resume(struct etna_acc_query *aq, struct etna_context *ctx)
-{
-   struct etna_resource *rsc = etna_resource(aq->prsc);
-   struct etna_reloc r = {
-      .bo = rsc->bo,
-      .flags = ETNA_RELOC_WRITE
-   };
-
-   if (aq->samples > 63) {
-      aq->samples = 63;
-      BUG("samples overflow");
-   }
 
-   r.offset = aq->samples * 8; /* 64bit value */
-
-   etna_set_state_reloc(ctx->stream, VIVS_GL_OCCLUSION_QUERY_ADDR, &r);
-   resource_written(ctx, aq->prsc);
-}
+extern const struct etna_acc_sample_provider occlusion_provider;
+extern const struct etna_acc_sample_provider perfmon_provider;
 
-static void
-occlusion_suspend(struct etna_acc_query *aq, 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);
-   resource_written(ctx, aq->prsc);
-}
-
-static void
-occlusion_result(struct etna_acc_query *aq, void *buf,
-                 union pipe_query_result *result)
+static const struct etna_acc_sample_provider *acc_sample_provider[] =
 {
-   uint64_t sum = 0;
-   uint64_t *ptr = (uint64_t *)buf;
-
-   for (unsigned i = 0; i < aq->samples; i++)
-      sum += *(ptr + i);
-
-   if (aq->base.type == PIPE_QUERY_OCCLUSION_COUNTER)
-      result->u64 = sum;
-   else
-      result->b = !!sum;
-}
+   &occlusion_provider,
+   &perfmon_provider,
+};
 
 static void
 etna_acc_destroy_query(struct etna_context *ctx, struct etna_query *q)
@@ -97,12 +56,6 @@ etna_acc_destroy_query(struct etna_context *ctx, struct etna_query *q)
    FREE(aq);
 }
 
-static const struct etna_acc_sample_provider occlusion_provider = {
-   .suspend = occlusion_suspend,
-   .resume = occlusion_resume,
-   .result = occlusion_result,
-};
-
 static void
 realloc_query_bo(struct etna_context *ctx, struct etna_acc_query *aq)
 {
@@ -125,7 +78,7 @@ realloc_query_bo(struct etna_context *ctx, struct etna_acc_query *aq)
    etna_bo_cpu_fini(rsc->bo);
 }
 
-static bool
+static void
 etna_acc_begin_query(struct etna_context *ctx, struct etna_query *q)
 {
    struct etna_acc_query *aq = etna_acc_query(q);
@@ -140,8 +93,6 @@ etna_acc_begin_query(struct etna_context *ctx, struct etna_query *q)
    /* add to active list */
    assert(list_is_empty(&aq->node));
    list_addtail(&aq->node, &ctx->active_acc_queries);
-
-   return true;
 }
 
 static void
@@ -167,10 +118,8 @@ etna_acc_get_query_result(struct etna_context *ctx, struct etna_query *q,
 
    assert(list_is_empty(&aq->node));
 
-   if (!wait) {
-      int ret;
-
-      if (rsc->status & ETNA_PENDING_WRITE) {
+   if (rsc->status & ETNA_PENDING_WRITE) {
+      if (!wait) {
          /* piglit spec@arb_occlusion_query@occlusion_query_conform
           * test, and silly apps perhaps, get stuck in a loop trying
           * to get query result forever with wait==false..  we don't
@@ -183,28 +132,26 @@ etna_acc_get_query_result(struct etna_context *ctx, struct etna_query *q,
          }
 
          return false;
+      } else {
+         /* flush that GPU executes all query related actions */
+         ctx->base.flush(&ctx->base, NULL, 0);
       }
-
-      ret = etna_bo_cpu_prep(rsc->bo, DRM_ETNA_PREP_READ | DRM_ETNA_PREP_NOSYNC);
-      if (ret)
-         return false;
-
-      etna_bo_cpu_fini(rsc->bo);
    }
 
-   /* flush that GPU executes all query related actions */
-   ctx->base.flush(&ctx->base, NULL, 0);
-
    /* get the result */
-   etna_bo_cpu_prep(rsc->bo, DRM_ETNA_PREP_READ);
+   int ret = etna_bo_cpu_prep(rsc->bo, DRM_ETNA_PREP_READ);
+   if (ret)
+      return false;
 
    void *ptr = etna_bo_map(rsc->bo);
-   p->result(aq, ptr, result);
-   aq->samples = 0;
+   bool success = p->result(aq, ptr, result);
+
+   if (success)
+      aq->samples = 0;
 
    etna_bo_cpu_fini(rsc->bo);
 
-   return true;
+   return success;
 }
 
 static const struct etna_query_funcs acc_query_funcs = {
@@ -214,33 +161,27 @@ static const struct etna_query_funcs acc_query_funcs = {
    .get_query_result = etna_acc_get_query_result,
 };
 
-static inline const struct etna_acc_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;
-   }
-}
-
 struct etna_query *
 etna_acc_create_query(struct etna_context *ctx, unsigned query_type)
 {
+   const struct etna_acc_sample_provider *p = NULL;
    struct etna_acc_query *aq;
    struct etna_query *q;
-   const struct etna_acc_sample_provider *p;
 
-   p = query_sample_provider(query_type);
+   /* find a sample provide for the requested query type */
+   for (unsigned i = 0; i < ARRAY_SIZE(acc_sample_provider); i++) {
+      p = acc_sample_provider[i];
+
+      if (p->supports(query_type))
+         break;
+      else
+         p = NULL;
+   }
+
    if (!p)
       return NULL;
 
-   aq = CALLOC_STRUCT(etna_acc_query);
+   aq = p->allocate(ctx, query_type);
    if (!aq)
       return NULL;