virgl: Add support for ARB_pipeline_statistics
authorGert Wollny <gert.wollny@collabora.com>
Fri, 19 May 2023 05:44:31 +0000 (07:44 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 23 May 2023 14:01:43 +0000 (14:01 +0000)
v2: make sure the PIPE enums map corretly to the VIRGL enums (Tintou)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23121>

docs/features.txt
src/gallium/drivers/virgl/virgl_query.c
src/gallium/drivers/virgl/virgl_screen.c
src/virtio/virtio-gpu/virgl_hw.h

index 9a3ab83..483b8f3 100644 (file)
@@ -229,7 +229,8 @@ GL 4.6, GLSL 4.60 -- all DONE: radeonsi, zink
 
   GL_ARB_gl_spirv                                       DONE (freedreno, i965/gen7+, llvmpipe)
   GL_ARB_indirect_parameters                            DONE (freedreno/a6xx+, i965/gen7+, nvc0, llvmpipe, virgl, d3d12)
-  GL_ARB_pipeline_statistics_query                      DONE (i965, nvc0, r600, llvmpipe, softpipe, )
+
+  GL_ARB_pipeline_statistics_query                      DONE (i965, nvc0, r600, llvmpipe, softpipe, virgl)
   GL_ARB_polygon_offset_clamp                           DONE (freedreno, i965, nv50, nvc0, r600, llvmpipe, v3d, virgl, panfrost)
   GL_ARB_shader_atomic_counter_ops                      DONE (freedreno/a5xx+, i965/gen7+, nvc0, r600, llvmpipe, softpipe, virgl, v3d)
   GL_ARB_shader_draw_parameters                         DONE (freedreno/a6xx+, i965, llvmpipe, nvc0, d3d12)
index c660cd2..96a62a5 100644 (file)
@@ -33,6 +33,7 @@ struct virgl_query {
    struct virgl_resource *buf;
    uint32_t handle;
    uint32_t result_size;
+   uint32_t pipeline_stats;
 
    bool ready;
    uint64_t result;
@@ -74,6 +75,26 @@ static int pipe_to_virgl_query(enum pipe_query_type ptype)
    return pquery_map[ptype];
 }
 
+static const enum virgl_statistics_query_index stats_index_map[] = {
+   [PIPE_STAT_QUERY_IA_VERTICES] = VIRGL_STAT_QUERY_IA_VERTICES,
+   [PIPE_STAT_QUERY_IA_PRIMITIVES] = VIRGL_STAT_QUERY_IA_PRIMITIVES,
+   [PIPE_STAT_QUERY_VS_INVOCATIONS] = VIRGL_STAT_QUERY_VS_INVOCATIONS,
+   [PIPE_STAT_QUERY_GS_INVOCATIONS] = VIRGL_STAT_QUERY_GS_INVOCATIONS,
+   [PIPE_STAT_QUERY_GS_PRIMITIVES] = VIRGL_STAT_QUERY_GS_PRIMITIVES,
+   [PIPE_STAT_QUERY_C_INVOCATIONS] = VIRGL_STAT_QUERY_C_INVOCATIONS,
+   [PIPE_STAT_QUERY_C_PRIMITIVES] = VIRGL_STAT_QUERY_C_PRIMITIVES,
+   [PIPE_STAT_QUERY_PS_INVOCATIONS] = VIRGL_STAT_QUERY_PS_INVOCATIONS,
+   [PIPE_STAT_QUERY_HS_INVOCATIONS] = VIRGL_STAT_QUERY_HS_INVOCATIONS,
+   [PIPE_STAT_QUERY_DS_INVOCATIONS] = VIRGL_STAT_QUERY_DS_INVOCATIONS,
+   [PIPE_STAT_QUERY_CS_INVOCATIONS] = VIRGL_STAT_QUERY_CS_INVOCATIONS,
+};
+
+static enum virgl_statistics_query_index
+pipe_stats_query_to_virgl(enum pipe_statistics_query_index index)
+{
+   return stats_index_map[index];
+}
+
 static inline struct virgl_query *virgl_query(struct pipe_query *q)
 {
    return (struct virgl_query *)q;
@@ -114,6 +135,14 @@ static struct pipe_query *virgl_create_query(struct pipe_context *ctx,
    query->result_size = (query_type == PIPE_QUERY_TIMESTAMP ||
                          query_type == PIPE_QUERY_TIME_ELAPSED) ? 8 : 4;
 
+   if (query_type == PIPE_QUERY_PIPELINE_STATISTICS) {
+      query->pipeline_stats = index;
+
+      index = pipe_stats_query_to_virgl(index);
+   } else {
+      query->pipeline_stats = ~0;
+   }
+
    util_range_add(&query->buf->b, &query->buf->valid_buffer_range, 0,
                   sizeof(struct virgl_host_query_state));
    virgl_resource_dirty(query->buf, 0);
@@ -224,7 +253,21 @@ static bool virgl_get_query_result(struct pipe_context *ctx,
       query->ready = true;
    }
 
-   result->u64 = query->result;
+   switch (query->pipeline_stats) {
+   case PIPE_STAT_QUERY_IA_VERTICES: result->pipeline_statistics.ia_vertices = query->result; break;
+   case PIPE_STAT_QUERY_IA_PRIMITIVES: result->pipeline_statistics.ia_primitives = query->result; break;
+   case PIPE_STAT_QUERY_VS_INVOCATIONS: result->pipeline_statistics.vs_invocations = query->result; break;
+   case PIPE_STAT_QUERY_GS_INVOCATIONS: result->pipeline_statistics.gs_invocations = query->result; break;
+   case PIPE_STAT_QUERY_GS_PRIMITIVES: result->pipeline_statistics.gs_primitives = query->result; break;
+   case PIPE_STAT_QUERY_PS_INVOCATIONS: result->pipeline_statistics.ps_invocations = query->result; break;
+   case PIPE_STAT_QUERY_HS_INVOCATIONS: result->pipeline_statistics.hs_invocations = query->result; break;
+   case PIPE_STAT_QUERY_CS_INVOCATIONS: result->pipeline_statistics.cs_invocations = query->result; break;
+   case PIPE_STAT_QUERY_C_INVOCATIONS: result->pipeline_statistics.c_invocations = query->result; break;
+   case PIPE_STAT_QUERY_C_PRIMITIVES: result->pipeline_statistics.c_primitives = query->result; break;
+   case PIPE_STAT_QUERY_DS_INVOCATIONS: result->pipeline_statistics.ds_invocations = query->result; break;
+   default:
+      result->u64 = query->result;
+   }
 
    return true;
 }
index 679b6df..6b0f2c4 100644 (file)
@@ -223,9 +223,10 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
       return vscreen->caps.caps.v1.max_tbo_size;
    case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
-   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
    case PIPE_CAP_ENDIANNESS:
       return 0;
+   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
+      return !!(vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_PIPELINE_STATISTICS_QUERY);
    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
    case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
       return 1;
index 4007fa1..d894e74 100644 (file)
@@ -468,6 +468,8 @@ enum virgl_formats {
 #define VIRGL_CAP_V2_TEXTURE_SHADOW_LOD   (1 << 10)
 #define VIRGL_CAP_V2_VS_VERTEX_LAYER      (1 << 11)
 #define VIRGL_CAP_V2_VS_VIEWPORT_INDEX    (1 << 12)
+#define VIRGL_CAP_V2_PIPELINE_STATISTICS_QUERY (1 << 13)
+
 /* virgl bind flags - these are compatible with mesa 10.5 gallium.
  * but are fixed, no other should be passed to virgl either.
  */
@@ -679,6 +681,20 @@ enum virgl_ctx_errors {
         VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND
 };
 
+enum virgl_statistics_query_index {
+   VIRGL_STAT_QUERY_IA_VERTICES = 0,
+   VIRGL_STAT_QUERY_IA_PRIMITIVES = 1,
+   VIRGL_STAT_QUERY_VS_INVOCATIONS = 2,
+   VIRGL_STAT_QUERY_GS_INVOCATIONS = 3,
+   VIRGL_STAT_QUERY_GS_PRIMITIVES = 4,
+   VIRGL_STAT_QUERY_C_INVOCATIONS = 5,
+   VIRGL_STAT_QUERY_C_PRIMITIVES = 6,
+   VIRGL_STAT_QUERY_PS_INVOCATIONS = 7,
+   VIRGL_STAT_QUERY_HS_INVOCATIONS = 8,
+   VIRGL_STAT_QUERY_DS_INVOCATIONS = 9,
+   VIRGL_STAT_QUERY_CS_INVOCATIONS = 10,
+};
+
 /**
  * Flags for the driver about resource behaviour:
  */