diff --git a/docs/features.txt b/docs/features.txt index 9a3ab83b154..483b8f3a2eb 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -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) diff --git a/src/gallium/drivers/virgl/virgl_query.c b/src/gallium/drivers/virgl/virgl_query.c index c660cd26ebd..96a62a524af 100644 --- a/src/gallium/drivers/virgl/virgl_query.c +++ b/src/gallium/drivers/virgl/virgl_query.c @@ -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; } diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index 679b6dfe6d5..6b0f2c417af 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -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; diff --git a/src/virtio/virtio-gpu/virgl_hw.h b/src/virtio/virtio-gpu/virgl_hw.h index 4007fa1677a..d894e744978 100644 --- a/src/virtio/virtio-gpu/virgl_hw.h +++ b/src/virtio/virtio-gpu/virgl_hw.h @@ -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: */