diff --git a/src/broadcom/meson.build b/src/broadcom/meson.build index 444692c39f1..d92c6f9f69a 100644 --- a/src/broadcom/meson.build +++ b/src/broadcom/meson.build @@ -73,6 +73,8 @@ libbroadcom_v3d = static_library( dependencies: [dep_valgrind, dep_thread, idep_mesautil, dep_libdrm], ) +subdir('perfcntrs') + if with_broadcom_vk subdir('vulkan') endif diff --git a/src/broadcom/perfcntrs/meson.build b/src/broadcom/perfcntrs/meson.build new file mode 100644 index 00000000000..497e9e664b1 --- /dev/null +++ b/src/broadcom/perfcntrs/meson.build @@ -0,0 +1,46 @@ +# Copyright © 2024 Raspberry Pi Ltd +# SPDX-License-Identifier: MIT + +libbroadcom_perfcntrs_files = files( + 'v3d_perfcntrs.c', +) + +files_per_version = files( + 'v3dx_counter.c', +) + +per_version_libs = [] +foreach ver : v3d_versions + per_version_libs += static_library( + 'v3d-perfcntrs-v' + ver, + [files_per_version, v3d_xml_pack], + include_directories : [ + inc_src, inc_include, inc_broadcom, + ], + c_args : [v3d_simulator_arg, '-DV3D_VERSION=' + ver], + gnu_symbol_visibility: 'hidden', + dependencies : [dep_v3d_hw, dep_libdrm, dep_valgrind, idep_mesautil], +) +endforeach + +libbroadcom_perfcntrs = static_library( + 'broadcom_perfcntrs', + [libbroadcom_perfcntrs_files], + include_directories : [inc_src, inc_include, inc_broadcom], + c_args : [no_override_init_args], + gnu_symbol_visibility : 'hidden', + dependencies : [dep_v3d_hw, dep_libdrm, dep_valgrind, idep_mesautil], + link_with : [per_version_libs], + build_by_default : false, +) + +idep_broadcom_perfcntrs = declare_dependency( + link_with: [ + libbroadcom_perfcntrs, + ], + include_directories: [ + inc_src, + ], +) + +v3d_libs += libbroadcom_perfcntrs diff --git a/src/broadcom/perfcntrs/v3d_perfcntrs.c b/src/broadcom/perfcntrs/v3d_perfcntrs.c new file mode 100644 index 00000000000..d4e00728d18 --- /dev/null +++ b/src/broadcom/perfcntrs/v3d_perfcntrs.c @@ -0,0 +1,69 @@ +/* + * Copyright © 2024 Raspberry Pi Ltd + * SPDX-License-Identifier: MIT + */ + +#include +#include "common/v3d_device_info.h" +#include "common/v3d_util.h" +#include "util/ralloc.h" +#include "v3d_perfcntrs.h" + +#define v3dX(x) v3d42_##x +#include "v3dx_counter.h" +#undef v3dX + +#define v3dX(x) v3d71_##x +#include "v3dx_counter.h" +#undef v3dX + +struct v3d_perfcntrs * +v3d_perfcntrs_init(const struct v3d_device_info *devinfo, int fd) +{ + struct v3d_perfcntrs *perfcounters; + + if (!devinfo) + return NULL; + + perfcounters = rzalloc(NULL, struct v3d_perfcntrs); + if (!perfcounters) + return NULL; + + perfcounters->name_table = _mesa_hash_table_create(NULL, _mesa_hash_string, _mesa_key_string_equal); + if (!perfcounters->name_table) { + v3d_perfcntrs_fini(perfcounters); + return NULL; + } + + perfcounters->fd = fd; + perfcounters->devinfo = devinfo; + + perfcounters->max_perfcnt = v3d_X(perfcounters->devinfo, perfcounters_num)(perfcounters->devinfo); + assert(perfcounters->max_perfcnt); + + perfcounters->perfcnt = rzalloc_array(perfcounters, struct v3d_perfcntr_desc *, perfcounters->max_perfcnt); + if (!perfcounters->perfcnt) { + fprintf(stderr, "Error allocating performance counters names"); + v3d_perfcntrs_fini(perfcounters); + return NULL; + } + + /* pre-fill our array and hash_table */ + for (unsigned i = 0; i < perfcounters->max_perfcnt; i++) { + struct v3d_perfcntr_desc *desc = v3d_X(perfcounters->devinfo, perfcounters_get)(perfcounters, i); + + _mesa_hash_table_insert(perfcounters->name_table, desc->name, desc); + } + + return perfcounters; +} + +void +v3d_perfcntrs_fini(struct v3d_perfcntrs *perfcounters) +{ + if (!perfcounters) + return; + + _mesa_hash_table_destroy(perfcounters->name_table, NULL); + ralloc_free(perfcounters); +} diff --git a/src/broadcom/perfcntrs/v3d_perfcntrs.h b/src/broadcom/perfcntrs/v3d_perfcntrs.h new file mode 100644 index 00000000000..a0cdd70c7e3 --- /dev/null +++ b/src/broadcom/perfcntrs/v3d_perfcntrs.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2024 Raspberry Pi Ltd + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include "util/hash_table.h" + +struct v3d_device_info; + +struct v3d_perfcntr_desc { + unsigned index; + const char *name; + const char *category; + const char *description; +}; + +struct v3d_perfcntrs { + int fd; + unsigned max_perfcnt; + const struct v3d_device_info *devinfo; + struct v3d_perfcntr_desc **perfcnt; + struct hash_table *name_table; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +struct v3d_perfcntrs * +v3d_perfcntrs_init(const struct v3d_device_info *devinfo, int fd); + +void +v3d_perfcntrs_fini(struct v3d_perfcntrs *perfcounters); + +static inline struct v3d_perfcntr_desc * +v3d_perfcntrs_get_by_index(struct v3d_perfcntrs *perfcounters, unsigned index) +{ + if (index >= perfcounters->max_perfcnt) + return NULL; + + return perfcounters->perfcnt[index]; +} + +static inline struct v3d_perfcntr_desc * +v3d_perfcntrs_get_by_name(struct v3d_perfcntrs *perfcounters, const char *name) +{ + struct hash_entry *entry = _mesa_hash_table_search(perfcounters->name_table, name); + + return entry ? (struct v3d_perfcntr_desc *)entry->data : NULL; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/broadcom/perfcntrs/v3dx_counter.c b/src/broadcom/perfcntrs/v3dx_counter.c new file mode 100644 index 00000000000..0774bd1ae8c --- /dev/null +++ b/src/broadcom/perfcntrs/v3dx_counter.c @@ -0,0 +1,64 @@ +/* + * Copyright © 2024 Raspberry Pi Ltd + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + +#include "common/v3d_device_info.h" +#include "common/v3d_macros.h" +#include "common/v3d_performance_counters.h" +#include "common/v3d_util.h" +#include "drm-uapi/v3d_drm.h" +#include "util/log.h" +#include "util/ralloc.h" +#include "v3d_perfcntrs.h" +#include "v3dx_counter.h" + +unsigned +v3dX(perfcounters_num)(const struct v3d_device_info *devinfo) +{ + return devinfo->max_perfcnt ? devinfo->max_perfcnt + : ARRAY_SIZE(v3d_performance_counters); +} + +struct v3d_perfcntr_desc * +v3dX(perfcounters_get)(struct v3d_perfcntrs *perfcounters, unsigned index) +{ + const unsigned max_perfcnt = perfcounters->max_perfcnt; + struct v3d_perfcntr_desc *counter; + + assert(index < max_perfcnt); + assert(perfcounters->perfcnt[index] == NULL); + + counter = ralloc(perfcounters, struct v3d_perfcntr_desc); + if (!counter) + return NULL; + + if (perfcounters->devinfo->max_perfcnt) { + struct drm_v3d_perfmon_get_counter req = { + .counter = index, + }; + int ret = v3d_ioctl(perfcounters->fd, DRM_IOCTL_V3D_PERFMON_GET_COUNTER, &req); + if (ret != 0) { + mesa_loge("Failed to get performance counter %d: %s\n", index, strerror(errno)); + return NULL; + } + + counter->name = ralloc_strdup(perfcounters->perfcnt, (const char *) req.name); + counter->category = ralloc_strdup(perfcounters->perfcnt, (const char *) req.category); + counter->description = ralloc_strdup(perfcounters->perfcnt, (const char *) req.description); + } else { + counter->name = v3d_performance_counters[index][V3D_PERFCNT_NAME]; + counter->category = v3d_performance_counters[index][V3D_PERFCNT_CATEGORY]; + counter->description = v3d_performance_counters[index][V3D_PERFCNT_DESCRIPTION]; + } + + counter->index = index; + perfcounters->perfcnt[index] = counter; + + return counter; +} diff --git a/src/broadcom/perfcntrs/v3dx_counter.h b/src/broadcom/perfcntrs/v3dx_counter.h new file mode 100644 index 00000000000..a3dfac37bac --- /dev/null +++ b/src/broadcom/perfcntrs/v3dx_counter.h @@ -0,0 +1,13 @@ +/* + * Copyright © 2024 Raspberry Pi Ltd + * SPDX-License-Identifier: MIT + */ + +/* This file generates the per-v3d-version function prototypes. */ + +struct v3d_device_info; +struct v3d_perfcntr_desc; +struct v3d_perfcntrs; + +unsigned v3dX(perfcounters_num)(const struct v3d_device_info *devinfo); +struct v3d_perfcntr_desc *v3dX(perfcounters_get)(struct v3d_perfcntrs *perfcounters, unsigned index);