virgl: Add support for ARB_pipeline_statistics

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>
This commit is contained in:
Gert Wollny 2023-05-19 07:44:31 +02:00 committed by Marge Bot
parent 330a1db016
commit cbb144c8d4
4 changed files with 64 additions and 3 deletions

View 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_gl_spirv DONE (freedreno, i965/gen7+, llvmpipe)
GL_ARB_indirect_parameters DONE (freedreno/a6xx+, i965/gen7+, nvc0, llvmpipe, virgl, d3d12) 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_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_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) GL_ARB_shader_draw_parameters DONE (freedreno/a6xx+, i965, llvmpipe, nvc0, d3d12)

View file

@ -33,6 +33,7 @@ struct virgl_query {
struct virgl_resource *buf; struct virgl_resource *buf;
uint32_t handle; uint32_t handle;
uint32_t result_size; uint32_t result_size;
uint32_t pipeline_stats;
bool ready; bool ready;
uint64_t result; uint64_t result;
@ -74,6 +75,26 @@ static int pipe_to_virgl_query(enum pipe_query_type ptype)
return pquery_map[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) static inline struct virgl_query *virgl_query(struct pipe_query *q)
{ {
return (struct virgl_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->result_size = (query_type == PIPE_QUERY_TIMESTAMP ||
query_type == PIPE_QUERY_TIME_ELAPSED) ? 8 : 4; 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, util_range_add(&query->buf->b, &query->buf->valid_buffer_range, 0,
sizeof(struct virgl_host_query_state)); sizeof(struct virgl_host_query_state));
virgl_resource_dirty(query->buf, 0); virgl_resource_dirty(query->buf, 0);
@ -224,7 +253,21 @@ static bool virgl_get_query_result(struct pipe_context *ctx,
query->ready = true; 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; return true;
} }

View file

@ -223,9 +223,10 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT: case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
return vscreen->caps.caps.v1.max_tbo_size; return vscreen->caps.caps.v1.max_tbo_size;
case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
case PIPE_CAP_ENDIANNESS: case PIPE_CAP_ENDIANNESS:
return 0; 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_FRAMEBUFFER_SIZES:
case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
return 1; return 1;

View file

@ -468,6 +468,8 @@ enum virgl_formats {
#define VIRGL_CAP_V2_TEXTURE_SHADOW_LOD (1 << 10) #define VIRGL_CAP_V2_TEXTURE_SHADOW_LOD (1 << 10)
#define VIRGL_CAP_V2_VS_VERTEX_LAYER (1 << 11) #define VIRGL_CAP_V2_VS_VERTEX_LAYER (1 << 11)
#define VIRGL_CAP_V2_VS_VIEWPORT_INDEX (1 << 12) #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. /* virgl bind flags - these are compatible with mesa 10.5 gallium.
* but are fixed, no other should be passed to virgl either. * 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 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: * Flags for the driver about resource behaviour:
*/ */