etnaviv: make use of a fixed size array to track of all acc query provider
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_query_acc.c
index c025ee7144a6b576e3e89a3dd620295abef1cda0..f156363e95170419e600a4772d155a875f05ae15 100644 (file)
  * interpret results
  */
 
+static bool
+occlusion_supports(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 true;
+   default:
+      return false;
+   }
+}
+
 static void
 occlusion_resume(struct etna_acc_query *aq, struct etna_context *ctx)
 {
@@ -98,11 +113,17 @@ etna_acc_destroy_query(struct etna_context *ctx, struct etna_query *q)
 }
 
 static const struct etna_acc_sample_provider occlusion_provider = {
+   .supports = occlusion_supports,
    .suspend = occlusion_suspend,
    .resume = occlusion_resume,
    .result = occlusion_result,
 };
 
+static const struct etna_acc_sample_provider *acc_sample_provider[] =
+{
+   &occlusion_provider,
+};
+
 static void
 realloc_query_bo(struct etna_context *ctx, struct etna_acc_query *aq)
 {
@@ -167,33 +188,30 @@ 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
           * wait to flush unnecessarily but we also don't want to
           * spin forever.
           */
-         if (aq->no_wait_cnt++ > 5)
+         if (aq->no_wait_cnt++ > 5) {
             ctx->base.flush(&ctx->base, NULL, 0);
-         return false;
-      }
+            aq->no_wait_cnt = 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);
+      } else {
+         /* flush that GPU executes all query related actions */
+         ctx->base.flush(&ctx->base, NULL, 0);
+      }
    }
 
-   /* 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);
@@ -211,29 +229,23 @@ 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;