diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 458a8dc210c..64ed380fa30 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -74,6 +74,9 @@ v3d_screen_destroy(struct pipe_screen *pscreen) { struct v3d_screen *screen = v3d_screen(pscreen); + ralloc_free(screen->perfcnt_names); + screen->perfcnt_names = NULL; + _mesa_hash_table_destroy(screen->bo_handles, NULL); v3d_bufmgr_destroy(pscreen); slab_destroy_parent(&screen->transfer_pool); @@ -896,6 +899,12 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config, if (!v3d_get_device_info(screen->fd, &screen->devinfo, &v3d_ioctl)) goto fail; + screen->perfcnt_names = rzalloc_array(screen, char*, screen->devinfo.max_perfcnt); + if (!screen->perfcnt_names) { + fprintf(stderr, "Error allocating performance counters names"); + goto fail; + } + driParseConfigFiles(config->options, config->options_info, 0, "v3d", NULL, NULL, NULL, 0, NULL, 0); diff --git a/src/gallium/drivers/v3d/v3d_screen.h b/src/gallium/drivers/v3d/v3d_screen.h index 6954e473bb9..c46ac4b6907 100644 --- a/src/gallium/drivers/v3d/v3d_screen.h +++ b/src/gallium/drivers/v3d/v3d_screen.h @@ -58,6 +58,9 @@ struct v3d_screen { const char *name; + /** Stores performance counters names **/ + char **perfcnt_names; + struct slab_parent_pool transfer_pool; struct v3d_bo_cache { diff --git a/src/gallium/drivers/v3d/v3dx_query_perfcnt.c b/src/gallium/drivers/v3d/v3dx_query_perfcnt.c index 7bc708074e7..84acbb769da 100644 --- a/src/gallium/drivers/v3d/v3dx_query_perfcnt.c +++ b/src/gallium/drivers/v3d/v3dx_query_perfcnt.c @@ -55,6 +55,8 @@ int v3dX(get_driver_query_group_info_perfcnt)(struct v3d_screen *screen, unsigned index, struct pipe_driver_query_group_info *info) { + struct v3d_device_info *devinfo = &screen->devinfo; + if (!screen->has_perfmon) return 0; @@ -66,7 +68,8 @@ v3dX(get_driver_query_group_info_perfcnt)(struct v3d_screen *screen, unsigned in info->name = "V3D counters"; info->max_active_queries = DRM_V3D_MAX_PERF_COUNTERS; - info->num_queries = ARRAY_SIZE(v3d_performance_counters); + info->num_queries = devinfo->max_perfcnt ? devinfo->max_perfcnt + : ARRAY_SIZE(v3d_performance_counters); return 1; } @@ -75,17 +78,40 @@ int v3dX(get_driver_query_info_perfcnt)(struct v3d_screen *screen, unsigned index, struct pipe_driver_query_info *info) { + struct v3d_device_info *devinfo = &screen->devinfo; + unsigned max_perfcnt = devinfo->max_perfcnt ? devinfo->max_perfcnt + : ARRAY_SIZE(v3d_performance_counters); + if (!screen->has_perfmon) return 0; if (!info) - return ARRAY_SIZE(v3d_performance_counters); + return max_perfcnt; - if (index >= ARRAY_SIZE(v3d_performance_counters)) + if (index >= max_perfcnt) return 0; + if (screen->perfcnt_names[index]) { + info->name = screen->perfcnt_names[index]; + } else if (devinfo->max_perfcnt) { + struct drm_v3d_perfmon_get_counter counter = { + .counter = index, + }; + int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_PERFMON_GET_COUNTER, &counter); + if (ret != 0) { + fprintf(stderr, "Failed to get performance counter %d: %s\n", + index, strerror(errno)); + return 0; + } + + screen->perfcnt_names[index] = ralloc_strdup(screen->perfcnt_names, + (const char *) counter.name); + info->name = screen->perfcnt_names[index]; + } else { + info->name = v3d_performance_counters[index][V3D_PERFCNT_NAME]; + } + info->group_id = 0; - info->name = v3d_performance_counters[index][V3D_PERFCNT_NAME]; info->query_type = PIPE_QUERY_DRIVER_SPECIFIC + index; info->result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE; info->type = PIPE_DRIVER_QUERY_TYPE_UINT64; @@ -237,13 +263,15 @@ v3dX(create_batch_query_perfcnt)(struct v3d_context *v3d, unsigned num_queries, struct v3d_query_perfcnt *pquery = NULL; struct v3d_query *query; struct v3d_perfmon_state *perfmon = NULL; + struct v3d_device_info *devinfo = &v3d->screen->devinfo; + unsigned max_perfcnt = devinfo->max_perfcnt ? devinfo->max_perfcnt + : ARRAY_SIZE(v3d_performance_counters); int i; /* Validate queries */ for (i = 0; i < num_queries; i++) { if (query_types[i] < PIPE_QUERY_DRIVER_SPECIFIC || - query_types[i] >= PIPE_QUERY_DRIVER_SPECIFIC + - ARRAY_SIZE(v3d_performance_counters)) { + query_types[i] >= PIPE_QUERY_DRIVER_SPECIFIC + max_perfcnt) { fprintf(stderr, "Invalid query type\n"); return NULL; }