util: remove LIST_DEL macro
[mesa.git] / src / gallium / drivers / svga / svga_pipe_query.c
index 65e58fe0e68d76fb68f69bedef4ec4a88171f68a..8922ef56e590c2b390c48f0a3c1b4772bf5521f4 100644 (file)
@@ -81,10 +81,10 @@ svga_query(struct pipe_query *q)
  * VGPU9
  */
 
-static boolean
+static bool
 svga_get_query_result(struct pipe_context *pipe,
                       struct pipe_query *q,
-                      boolean wait,
+                      bool wait,
                       union pipe_query_result *result);
 
 static enum pipe_error
@@ -164,9 +164,9 @@ end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
    return ret;
 }
 
-static boolean
+static bool
 get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
-                       boolean wait, uint64_t *result)
+                       bool wait, uint64_t *result)
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    enum pipe_error ret;
@@ -190,8 +190,9 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
    state = sq->queryResult->state;
    if (state == SVGA3D_QUERYSTATE_PENDING) {
       if (!wait)
-         return FALSE;
-      sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+         return false;
+      sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+                        SVGA_FENCE_FLAG_QUERY);
       state = sq->queryResult->state;
    }
 
@@ -199,7 +200,7 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
           state == SVGA3D_QUERYSTATE_FAILED);
 
    *result = (uint64_t)sq->queryResult->result32;
-   return TRUE;
+   return true;
 }
 
 
@@ -265,7 +266,7 @@ allocate_query_block(struct svga_context *svga)
        * any empty memory block around that can be freed up.
        */
       index = -1;
-      for (i = 0; i < SVGA_QUERY_MAX && index == -1; i++) {
+      for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) {
          struct svga_qmem_alloc_entry *alloc_entry;
          struct svga_qmem_alloc_entry *prev_alloc_entry = NULL;
 
@@ -380,7 +381,7 @@ allocate_query(struct svga_context *svga,
    int slot_index = -1;
    unsigned offset;
 
-   assert(type < SVGA_QUERY_MAX);
+   assert(type < SVGA3D_QUERYTYPE_MAX);
 
    alloc_entry = svga->gb_query_map[type];
 
@@ -453,7 +454,7 @@ destroy_gb_query_obj(struct svga_context *svga)
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    unsigned i;
 
-   for (i = 0; i < SVGA_QUERY_MAX; i++) {
+   for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) {
       struct svga_qmem_alloc_entry *alloc_entry, *next;
       alloc_entry = svga->gb_query_map[i];
       while (alloc_entry) {
@@ -610,7 +611,6 @@ begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 static enum pipe_error
 end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 {
-   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    enum pipe_error ret = PIPE_OK;
 
    if (svga->rebind.flags.query) {
@@ -623,21 +623,12 @@ end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
       ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
    }
 
-   /* Finish fence is copied here from get_query_result_vgpu10. This helps
-    * with cases where svga_begin_query might be called again before
-    * svga_get_query_result, such as GL_TIME_ELAPSED.
-    */
-   if (!sq->fence) {
-      svga_context_flush(svga, &sq->fence);
-   }
-   sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
-
    return ret;
 }
 
-static boolean
+static bool
 get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
-                        boolean wait, void *result, int resultLen)
+                        bool wait, void *result, int resultLen)
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    SVGA3dQueryState queryState;
@@ -648,17 +639,28 @@ get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
 
    sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
 
-   if (queryState == SVGA3D_QUERYSTATE_PENDING) {
+   if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) {
+      /* We don't have the query result yet, and the query hasn't been
+       * submitted.  We need to submit it now since the GL spec says
+       * "Querying the state for a given occlusion query forces that
+       * occlusion query to complete within a finite amount of time."
+       */
+      svga_context_flush(svga, &sq->fence);
+   }
+
+   if (queryState == SVGA3D_QUERYSTATE_PENDING ||
+       queryState == SVGA3D_QUERYSTATE_NEW) {
       if (!wait)
-         return FALSE;
-      sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+         return false;
+      sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+                        SVGA_FENCE_FLAG_QUERY);
       sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
    }
 
    assert(queryState == SVGA3D_QUERYSTATE_SUCCEEDED ||
           queryState == SVGA3D_QUERYSTATE_FAILED);
 
-   return TRUE;
+   return true;
 }
 
 static struct pipe_query *
@@ -705,6 +707,7 @@ svga_create_query(struct pipe_context *pipe,
       }
       break;
    case PIPE_QUERY_OCCLUSION_PREDICATE:
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
       if (svga_have_vgpu10(svga)) {
          sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE;
          define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult));
@@ -731,11 +734,10 @@ svga_create_query(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_FALLBACKS:
    case SVGA_QUERY_NUM_FLUSHES:
    case SVGA_QUERY_NUM_VALIDATIONS:
-   case SVGA_QUERY_MAP_BUFFER_TIME:
-   case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
-   case SVGA_QUERY_FLUSH_TIME:
    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
    case SVGA_QUERY_MEMORY_USED:
    case SVGA_QUERY_NUM_SHADERS:
@@ -748,6 +750,13 @@ svga_create_query(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    case SVGA_QUERY_NUM_CONST_UPDATES:
+   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+   case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+      break;
+   case SVGA_QUERY_FLUSH_TIME:
+   case SVGA_QUERY_MAP_BUFFER_TIME:
+      /* These queries need os_time_get() */
+      svga->hud.uses_time = TRUE;
       break;
    default:
       assert(!"unexpected query type in svga_create_query()");
@@ -782,6 +791,7 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    switch (sq->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_OCCLUSION_PREDICATE:
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
       if (svga_have_vgpu10(svga)) {
          /* make sure to also destroy any associated predicate query */
          if (sq->predicate)
@@ -805,7 +815,8 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_FLUSHES:
    case SVGA_QUERY_NUM_VALIDATIONS:
    case SVGA_QUERY_MAP_BUFFER_TIME:
-   case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    case SVGA_QUERY_FLUSH_TIME:
@@ -821,6 +832,8 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    case SVGA_QUERY_NUM_CONST_UPDATES:
+   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+   case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
       /* nothing */
       break;
    default:
@@ -834,7 +847,7 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
 }
 
 
-static boolean
+static bool
 svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct svga_context *svga = svga_context(pipe);
@@ -855,6 +868,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    switch (sq->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_OCCLUSION_PREDICATE:
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
       if (svga_have_vgpu10(svga)) {
          ret = begin_query_vgpu10(svga, sq);
          /* also need to start the associated occlusion predicate query */
@@ -893,8 +907,11 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_MAP_BUFFER_TIME:
       sq->begin_count = svga->hud.map_buffer_time;
       break;
-   case SVGA_QUERY_NUM_RESOURCES_MAPPED:
-      sq->begin_count = svga->hud.num_resources_mapped;
+   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+      sq->begin_count = svga->hud.num_buffers_mapped;
+      break;
+   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
+      sq->begin_count = svga->hud.num_textures_mapped;
       break;
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
       sq->begin_count = svga->hud.num_bytes_uploaded;
@@ -929,6 +946,8 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_STATE_OBJECTS:
    case SVGA_QUERY_NUM_SURFACE_VIEWS:
    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
+   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+   case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
       /* nothing */
       break;
    default:
@@ -964,6 +983,7 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    switch (sq->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_OCCLUSION_PREDICATE:
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
       if (svga_have_vgpu10(svga)) {
          ret = end_query_vgpu10(svga, sq);
          /* also need to end the associated occlusion predicate query */
@@ -978,11 +998,6 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
       }
       assert(ret == PIPE_OK);
       (void) ret;
-      /* TODO: Delay flushing. We don't really need to flush here, just ensure
-       * that there is one flush before svga_get_query_result attempts to get
-       * the result.
-       */
-      svga_context_flush(svga, NULL);
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
    case PIPE_QUERY_PRIMITIVES_EMITTED:
@@ -1007,8 +1022,11 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_MAP_BUFFER_TIME:
       sq->end_count = svga->hud.map_buffer_time;
       break;
-   case SVGA_QUERY_NUM_RESOURCES_MAPPED:
-      sq->end_count = svga->hud.num_resources_mapped;
+   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+      sq->end_count = svga->hud.num_buffers_mapped;
+      break;
+   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
+      sq->end_count = svga->hud.num_textures_mapped;
       break;
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
       sq->end_count = svga->hud.num_bytes_uploaded;
@@ -1043,6 +1061,8 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_STATE_OBJECTS:
    case SVGA_QUERY_NUM_SURFACE_VIEWS:
    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
+   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+   case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
       /* nothing */
       break;
    default:
@@ -1053,17 +1073,17 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
 }
 
 
-static boolean
+static bool
 svga_get_query_result(struct pipe_context *pipe,
                       struct pipe_query *q,
-                      boolean wait,
+                      bool wait,
                       union pipe_query_result *vresult)
 {
    struct svga_screen *svgascreen = svga_screen(pipe->screen);
    struct svga_context *svga = svga_context(pipe);
    struct svga_query *sq = svga_query(q);
    uint64_t *result = (uint64_t *)vresult;
-   boolean ret = TRUE;
+   bool ret = true;
 
    assert(sq);
 
@@ -1081,14 +1101,15 @@ svga_get_query_result(struct pipe_context *pipe,
          ret = get_query_result_vgpu9(svga, sq, wait, result);
       }
       break;
-   case PIPE_QUERY_OCCLUSION_PREDICATE: {
+   case PIPE_QUERY_OCCLUSION_PREDICATE:
+   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
       if (svga_have_vgpu10(svga)) {
          SVGADXOcclusionPredicateQueryResult occResult;
          ret = get_query_result_vgpu10(svga, sq, wait,
                                        (void *)&occResult, sizeof(occResult));
          vresult->b = occResult.anySamplesRendered != 0;
       } else {
-         uint64_t count;
+         uint64_t count = 0;
          ret = get_query_result_vgpu9(svga, sq, wait, &count);
          vresult->b = count != 0;
       }
@@ -1139,7 +1160,8 @@ svga_get_query_result(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_FLUSHES:
    case SVGA_QUERY_NUM_VALIDATIONS:
    case SVGA_QUERY_MAP_BUFFER_TIME:
-   case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    case SVGA_QUERY_FLUSH_TIME:
@@ -1175,6 +1197,13 @@ svga_get_query_result(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
       vresult->u64 = svga->hud.num_generate_mipmap;
       break;
+   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+      vresult->u64 = svgascreen->hud.num_failed_allocations;
+      break;
+   case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+      vresult->f = (float) svga->swc->num_commands
+         / (float) svga->swc->num_draw_commands;
+      break;
    default:
       assert(!"unexpected query type in svga_get_query_result");
    }
@@ -1186,7 +1215,7 @@ svga_get_query_result(struct pipe_context *pipe,
 
 static void
 svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
-                      boolean condition, uint mode)
+                      bool condition, enum pipe_render_cond_flag mode)
 {
    struct svga_context *svga = svga_context(pipe);
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
@@ -1216,7 +1245,8 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
 
       if ((mode == PIPE_RENDER_COND_WAIT ||
            mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) {
-         sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+         sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+                           SVGA_FENCE_FLAG_QUERY);
       }
    }
    /*
@@ -1232,7 +1262,11 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
          ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
                                             (uint32) condition);
       }
+      svga->pred.query_id = queryId;
+      svga->pred.cond = condition;
    }
+
+   svga->render_condition = (sq != NULL);
 }
 
 
@@ -1256,8 +1290,48 @@ svga_get_timestamp(struct pipe_context *pipe)
 
 
 static void
-svga_set_active_query_state(struct pipe_context *pipe, boolean enable)
+svga_set_active_query_state(struct pipe_context *pipe, bool enable)
+{
+}
+
+
+/**
+ * \brief Toggle conditional rendering if already enabled
+ *
+ * \param svga[in]  The svga context
+ * \param render_condition_enabled[in]  Whether to ignore requests to turn
+ * conditional rendering off
+ * \param on[in]  Whether to turn conditional rendering on or off
+ */
+void
+svga_toggle_render_condition(struct svga_context *svga,
+                             boolean render_condition_enabled,
+                             boolean on)
 {
+   SVGA3dQueryId query_id;
+   enum pipe_error ret;
+
+   if (render_condition_enabled ||
+       svga->pred.query_id == SVGA3D_INVALID_ID) {
+      return;
+   }
+
+   /*
+    * If we get here, it means that the system supports
+    * conditional rendering since svga->pred.query_id has already been
+    * modified for this context and thus support has already been
+    * verified.
+    */
+   query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;
+
+   ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
+                                      (uint32) svga->pred.cond);
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
+      svga_context_flush(svga, NULL);
+      ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
+                                         (uint32) svga->pred.cond);
+      assert(ret == PIPE_OK);
+   }
 }