util: move os_time.[ch] to src/util
[mesa.git] / src / gallium / drivers / swr / swr_query.cpp
index 5c599654ba90ac99bd89777bd5f2878cfefbddc3..ea31de630b3075199d9f1a9f4cce8ceddf42c3be 100644 (file)
 
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
 #include "swr_context.h"
 #include "swr_fence.h"
 #include "swr_query.h"
 #include "swr_screen.h"
 #include "swr_state.h"
-
+#include "common/os.h"
 
 static struct swr_query *
 swr_query(struct pipe_query *p)
@@ -45,7 +45,8 @@ swr_create_query(struct pipe_context *pipe, unsigned type, unsigned index)
    assert(type < PIPE_QUERY_TYPES);
    assert(index < MAX_SO_STREAMS);
 
-   pq = CALLOC_STRUCT(swr_query);
+   pq = (struct swr_query *) AlignedMalloc(sizeof(struct swr_query), 64);
+   memset(pq, 0, sizeof(*pq));
 
    if (pq) {
       pq->type = type;
@@ -63,53 +64,11 @@ swr_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
 
    if (pq->fence) {
       if (swr_is_fence_pending(pq->fence))
-         swr_fence_finish(pipe->screen, pq->fence, 0);
+         swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
       swr_fence_reference(pipe->screen, &pq->fence, NULL);
    }
 
-   FREE(pq);
-}
-
-
-static void
-swr_gather_stats(struct pipe_context *pipe, struct swr_query *pq)
-{
-   struct swr_context *ctx = swr_context(pipe);
-
-   assert(pq->result);
-   struct swr_query_result *result = pq->result;
-   boolean enable_stats = pq->enable_stats;
-
-   /* A few results don't require the core, so don't involve it */
-   switch (pq->type) {
-   case PIPE_QUERY_TIMESTAMP:
-   case PIPE_QUERY_TIME_ELAPSED:
-      result->timestamp = swr_get_timestamp(pipe->screen);
-      break;
-   case PIPE_QUERY_TIMESTAMP_DISJOINT:
-   case PIPE_QUERY_GPU_FINISHED:
-      /* nothing to do here */
-      break;
-   default:
-      /*
-       * All other results are collected from SwrCore counters via
-       * SwrGetStats. This returns immediately, but results are later filled
-       * in by the backend.  Fence status is the only indication of
-       * completion.  */
-      SwrGetStats(ctx->swrContext, &result->core);
-
-      if (!pq->fence) {
-         struct swr_screen *screen = swr_screen(pipe->screen);
-         swr_fence_reference(pipe->screen, &pq->fence, screen->flush_fence);
-      }
-      swr_fence_submit(ctx, pq->fence);
-
-      /* Only change stat collection if there are no active queries */
-      if (ctx->active_queries == 0)
-         SwrEnableStats(ctx->swrContext, enable_stats);
-
-      break;
-   }
+   AlignedFree(pq);
 }
 
 
@@ -120,51 +79,48 @@ swr_get_query_result(struct pipe_context *pipe,
                      union pipe_query_result *result)
 {
    struct swr_query *pq = swr_query(q);
-   struct swr_query_result *start = &pq->start;
-   struct swr_query_result *end = &pq->end;
    unsigned index = pq->index;
 
    if (pq->fence) {
       if (!wait && !swr_is_fence_done(pq->fence))
          return FALSE;
 
-      swr_fence_finish(pipe->screen, pq->fence, 0);
+      swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
       swr_fence_reference(pipe->screen, &pq->fence, NULL);
    }
 
-   /* XXX: Need to handle counter rollover */
-
+   /* All values are reset to 0 at swr_begin_query, except starting timestamp.
+    * Counters become simply end values.  */
    switch (pq->type) {
    /* Booleans */
    case PIPE_QUERY_OCCLUSION_PREDICATE:
-      result->b = end->core.DepthPassCount != start->core.DepthPassCount;
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+      result->b = pq->result.core.DepthPassCount != 0;
       break;
    case PIPE_QUERY_GPU_FINISHED:
       result->b = TRUE;
       break;
    /* Counters */
    case PIPE_QUERY_OCCLUSION_COUNTER:
-      result->u64 = end->core.DepthPassCount - start->core.DepthPassCount;
+      result->u64 = pq->result.core.DepthPassCount;
       break;
    case PIPE_QUERY_TIMESTAMP:
    case PIPE_QUERY_TIME_ELAPSED:
-      result->u64 = end->timestamp - start->timestamp;
+      result->u64 = pq->result.timestamp_end - pq->result.timestamp_start;
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
-      result->u64 = end->core.IaPrimitives - start->core.IaPrimitives;
+      result->u64 = pq->result.coreFE.IaPrimitives;
+      break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
-      result->u64 = end->core.SoNumPrimsWritten[index]
-         - start->core.SoNumPrimsWritten[index];
+      result->u64 = pq->result.coreFE.SoNumPrimsWritten[index];
       break;
    /* Structures */
    case PIPE_QUERY_SO_STATISTICS: {
       struct pipe_query_data_so_statistics *so_stats = &result->so_statistics;
-      struct SWR_STATS *start = &pq->start.core;
-      struct SWR_STATS *end = &pq->end.core;
       so_stats->num_primitives_written =
-         end->SoNumPrimsWritten[index] - start->SoNumPrimsWritten[index];
+         pq->result.coreFE.SoNumPrimsWritten[index];
       so_stats->primitives_storage_needed =
-         end->SoPrimStorageNeeded[index] - start->SoPrimStorageNeeded[index];
+         pq->result.coreFE.SoPrimStorageNeeded[index];
    } break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
       /* os_get_time_nano returns nanoseconds */
@@ -174,27 +130,23 @@ swr_get_query_result(struct pipe_context *pipe,
    case PIPE_QUERY_PIPELINE_STATISTICS: {
       struct pipe_query_data_pipeline_statistics *p_stats =
          &result->pipeline_statistics;
-      struct SWR_STATS *start = &pq->start.core;
-      struct SWR_STATS *end = &pq->end.core;
-      p_stats->ia_vertices = end->IaVertices - start->IaVertices;
-      p_stats->ia_primitives = end->IaPrimitives - start->IaPrimitives;
-      p_stats->vs_invocations = end->VsInvocations - start->VsInvocations;
-      p_stats->gs_invocations = end->GsInvocations - start->GsInvocations;
-      p_stats->gs_primitives = end->GsPrimitives - start->GsPrimitives;
-      p_stats->c_invocations = end->CPrimitives - start->CPrimitives;
-      p_stats->c_primitives = end->CPrimitives - start->CPrimitives;
-      p_stats->ps_invocations = end->PsInvocations - start->PsInvocations;
-      p_stats->hs_invocations = end->HsInvocations - start->HsInvocations;
-      p_stats->ds_invocations = end->DsInvocations - start->DsInvocations;
-      p_stats->cs_invocations = end->CsInvocations - start->CsInvocations;
+      p_stats->ia_vertices = pq->result.coreFE.IaVertices;
+      p_stats->ia_primitives = pq->result.coreFE.IaPrimitives;
+      p_stats->vs_invocations = pq->result.coreFE.VsInvocations;
+      p_stats->gs_invocations = pq->result.coreFE.GsInvocations;
+      p_stats->gs_primitives = pq->result.coreFE.GsPrimitives;
+      p_stats->c_invocations = pq->result.coreFE.CPrimitives;
+      p_stats->c_primitives = pq->result.coreFE.CPrimitives;
+      p_stats->ps_invocations = pq->result.core.PsInvocations;
+      p_stats->hs_invocations = pq->result.coreFE.HsInvocations;
+      p_stats->ds_invocations = pq->result.coreFE.DsInvocations;
+      p_stats->cs_invocations = pq->result.core.CsInvocations;
     } break;
    case PIPE_QUERY_SO_OVERFLOW_PREDICATE: {
-      struct SWR_STATS *start = &pq->start.core;
-      struct SWR_STATS *end = &pq->end.core;
       uint64_t num_primitives_written =
-         end->SoNumPrimsWritten[index] - start->SoNumPrimsWritten[index];
+         pq->result.coreFE.SoNumPrimsWritten[index];
       uint64_t primitives_storage_needed =
-         end->SoPrimStorageNeeded[index] - start->SoPrimStorageNeeded[index];
+         pq->result.coreFE.SoPrimStorageNeeded[index];
       result->b = num_primitives_written > primitives_storage_needed;
    }
       break;
@@ -212,21 +164,30 @@ swr_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    struct swr_context *ctx = swr_context(pipe);
    struct swr_query *pq = swr_query(q);
 
-   assert(!pq->enable_stats && "swr_begin_query: Query is already active!");
-
    /* Initialize Results */
-   memset(&pq->start, 0, sizeof(pq->start));
-   memset(&pq->end, 0, sizeof(pq->end));
+   memset(&pq->result, 0, sizeof(pq->result));
+   switch (pq->type) {
+   case PIPE_QUERY_GPU_FINISHED:
+   case PIPE_QUERY_TIMESTAMP:
+      /* nothing to do, but don't want the default */
+      break;
+   case PIPE_QUERY_TIME_ELAPSED:
+      pq->result.timestamp_start = swr_get_timestamp(pipe->screen);
+      break;
+   default:
+      /* Core counters required.  Update draw context with location to
+       * store results. */
+      swr_update_draw_context(ctx, &pq->result);
 
-   /* Gather start stats and enable SwrCore counters */
-   pq->result = &pq->start;
-   pq->enable_stats = TRUE;
-   swr_gather_stats(pipe, pq);
-   ctx->active_queries++;
+      /* Only change stat collection if there are no active queries */
+      if (ctx->active_queries == 0) {
+         ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, TRUE);
+         ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, TRUE);
+      }
+      ctx->active_queries++;
+      break;
+   }
 
-   /* override start timestamp to 0 for TIMESTAMP query */
-   if (pq->type == PIPE_QUERY_TIMESTAMP)
-      pq->start.timestamp = 0;
 
    return true;
 }
@@ -237,14 +198,33 @@ swr_end_query(struct pipe_context *pipe, struct pipe_query *q)
    struct swr_context *ctx = swr_context(pipe);
    struct swr_query *pq = swr_query(q);
 
-   assert(ctx->active_queries
-          && "swr_end_query, there are no active queries!");
-   ctx->active_queries--;
+   switch (pq->type) {
+   case PIPE_QUERY_GPU_FINISHED:
+      /* nothing to do, but don't want the default */
+      break;
+   case PIPE_QUERY_TIMESTAMP:
+   case PIPE_QUERY_TIME_ELAPSED:
+      pq->result.timestamp_end = swr_get_timestamp(pipe->screen);
+      break;
+   default:
+      /* Stats are updated asynchronously, a fence is used to signal
+       * completion. */
+      if (!pq->fence) {
+         struct swr_screen *screen = swr_screen(pipe->screen);
+         swr_fence_reference(pipe->screen, &pq->fence, screen->flush_fence);
+      }
+      swr_fence_submit(ctx, pq->fence);
+
+      /* Only change stat collection if there are no active queries */
+      ctx->active_queries--;
+      if (ctx->active_queries == 0) {
+         ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, FALSE);
+         ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, FALSE);
+      }
+
+      break;
+   }
 
-   /* Gather end stats and disable SwrCore counters */
-   pq->result = &pq->end;
-   pq->enable_stats = FALSE;
-   swr_gather_stats(pipe, pq);
    return true;
 }