[2/3] st/mesa: Pass index to pipe->create_query() for statistics queries.

Submitted by Kenneth Graunke on Dec. 15, 2018, 9:44 a.m.

Details

Message ID 20181215094456.15435-2-kenneth@whitecape.org
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Kenneth Graunke Dec. 15, 2018, 9:44 a.m.
GL exposes separate queries for each pipeline statistics counter,
each of which return a single value.  Gallium (and D3D) treats them
as a single query, PIPE_QUERY_PIPELINE_STATISTICS, which returns 11
values.  Radeon hardware appears to query them all as a group, and
the CPU-side hook, pipe->get_query_result() simply writes them all,
so st/mesa can return whichever one GL actually desired.  The GPU-side
hook, pipe->get_query_result_resource(), takes an index so it knows
which value to write to the buffer.

On Intel hardware, each individual pipeline statistics value is handled
as a separate counter and query.  We can query each individually, and
that is more efficient than querying all 11 counters each time.  But,
we need pipe->get_query_result() to know which one to return.

To handle this, we pass the index into pipe->create_query(), which
was previously always 0 for these queries.  Drivers which return all
of the counters as a group can simply ignore it; drivers querying one
at a time can use it to distinguish between the counters.

v2: Use an enum instead of hardcoding numbers (suggested by Roland).

Cc: Roland Scheidegger <sroland@vmware.com>
---
 src/mesa/state_tracker/st_cb_queryobj.c | 75 ++++++++++++-------------
 1 file changed, 35 insertions(+), 40 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index 82f53243336..a0ed309c2b3 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -88,6 +88,39 @@  st_DeleteQuery(struct gl_context *ctx, struct gl_query_object *q)
    free(stq);
 }
 
+static int
+target_to_index(const struct gl_query_object *q)
+{
+   switch (q->Target) {
+   case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+   case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+      return q->Stream;
+   case GL_VERTICES_SUBMITTED_ARB:
+      return PIPE_STAT_QUERY_IA_VERTICES;
+   case GL_PRIMITIVES_SUBMITTED_ARB:
+      return PIPE_STAT_QUERY_IA_PRIMITIVES;
+   case GL_VERTEX_SHADER_INVOCATIONS_ARB:
+      return PIPE_STAT_QUERY_VS_INVOCATIONS;
+   case GL_GEOMETRY_SHADER_INVOCATIONS:
+      return PIPE_STAT_QUERY_GS_INVOCATIONS;
+   case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
+      return PIPE_STAT_QUERY_GS_PRIMITIVES;
+   case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
+      return PIPE_STAT_QUERY_C_INVOCATIONS;
+   case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
+      return PIPE_STAT_QUERY_C_PRIMITIVES;
+   case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
+      return PIPE_STAT_QUERY_PS_INVOCATIONS;
+   case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
+      return PIPE_STAT_QUERY_HS_INVOCATIONS;
+   case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
+      return PIPE_STAT_QUERY_DS_INVOCATIONS;
+   case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
+      return PIPE_STAT_QUERY_CS_INVOCATIONS;
+   default:
+      return 0;
+   }
+}
 
 static void
 st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q)
@@ -164,7 +197,7 @@  st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q)
          ret = pipe->end_query(pipe, stq->pq_begin);
    } else {
       if (!stq->pq) {
-         stq->pq = pipe->create_query(pipe, type, q->Stream);
+         stq->pq = pipe->create_query(pipe, type, target_to_index(q));
          stq->type = type;
       }
       if (stq->pq)
@@ -383,46 +416,8 @@  st_StoreQueryResult(struct gl_context *ctx, struct gl_query_object *q,
 
    if (pname == GL_QUERY_RESULT_AVAILABLE) {
       index = -1;
-   } else if (stq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
-      switch (q->Target) {
-      case GL_VERTICES_SUBMITTED_ARB:
-         index = PIPE_STAT_QUERY_IA_VERTICES;
-         break;
-      case GL_PRIMITIVES_SUBMITTED_ARB:
-         index = PIPE_STAT_QUERY_IA_PRIMITIVES;
-         break;
-      case GL_VERTEX_SHADER_INVOCATIONS_ARB:
-         index = PIPE_STAT_QUERY_VS_INVOCATIONS;
-         break;
-      case GL_GEOMETRY_SHADER_INVOCATIONS:
-         index = PIPE_STAT_QUERY_GS_INVOCATIONS;
-         break;
-      case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB:
-         index = PIPE_STAT_QUERY_GS_PRIMITIVES;
-         break;
-      case GL_CLIPPING_INPUT_PRIMITIVES_ARB:
-         index = PIPE_STAT_QUERY_C_INVOCATIONS;
-         break;
-      case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB:
-         index = PIPE_STAT_QUERY_C_PRIMITIVES;
-         break;
-      case GL_FRAGMENT_SHADER_INVOCATIONS_ARB:
-         index = PIPE_STAT_QUERY_PS_INVOCATIONS;
-         break;
-      case GL_TESS_CONTROL_SHADER_PATCHES_ARB:
-         index = PIPE_STAT_QUERY_HS_INVOCATIONS;
-         break;
-      case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB:
-         index = PIPE_STAT_QUERY_DS_INVOCATIONS;
-         break;
-      case GL_COMPUTE_SHADER_INVOCATIONS_ARB:
-         index = PIPE_STAT_QUERY_CS_INVOCATIONS;
-         break;
-      default:
-         unreachable("Unexpected target");
-      }
    } else {
-      index = 0;
+      index = target_to_index(q);
    }
 
    pipe->get_query_result_resource(pipe, stq->pq, wait, result_type, index,