mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
broadcom: Add perfetto data source
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31751>
This commit is contained in:
parent
27fb3c549a
commit
3d2d3b2c10
4 changed files with 268 additions and 0 deletions
42
src/broadcom/ds/meson.build
Normal file
42
src/broadcom/ds/meson.build
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright © 2024 Raspberry Pi Ltd
|
||||
# Copyright © 2021 Collabora, Ltd.
|
||||
# Copyright © 2021 Google, Inc
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
pps_broadcom_lib = static_library(
|
||||
'broadcom-dds',
|
||||
sources: [
|
||||
'v3d_pps_driver.cc',
|
||||
'v3d_pps_driver.h',
|
||||
],
|
||||
include_directories: [
|
||||
inc_tool,
|
||||
inc_broadcom,
|
||||
inc_include,
|
||||
],
|
||||
dependencies: [
|
||||
dep_libdrm,
|
||||
dep_perfetto,
|
||||
idep_broadcom_perfcntrs,
|
||||
],
|
||||
c_args: [no_override_init_args],
|
||||
)
|
||||
|
||||
pps_broadcom_dep = declare_dependency(
|
||||
link_with: [
|
||||
pps_broadcom_lib,
|
||||
libbroadcom_v3d,
|
||||
],
|
||||
include_directories: [
|
||||
inc_tool,
|
||||
],
|
||||
compile_args: [
|
||||
'-DPPS_V3D',
|
||||
],
|
||||
)
|
||||
|
||||
pps_datasources += pps_broadcom_dep
|
||||
pps_includes += [
|
||||
inc_include,
|
||||
inc_broadcom,
|
||||
]
|
||||
181
src/broadcom/ds/v3d_pps_driver.cc
Normal file
181
src/broadcom/ds/v3d_pps_driver.cc
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright © 2024 Raspberry Pi Ltd
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "v3d_pps_driver.h"
|
||||
|
||||
#include <perfetto.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "perfcntrs/v3d_perfcntrs.h"
|
||||
#include <xf86drm.h>
|
||||
|
||||
namespace pps
|
||||
{
|
||||
|
||||
uint64_t
|
||||
V3DDriver::get_min_sampling_period_ns()
|
||||
{
|
||||
return 100000;
|
||||
}
|
||||
|
||||
bool
|
||||
V3DDriver::init_perfcnt()
|
||||
{
|
||||
const char *v3d_ds_counter_env = getenv("V3D_DS_COUNTER");
|
||||
if (!v3d_ds_counter_env || v3d_ds_counter_env[0] == '\0')
|
||||
return false;
|
||||
|
||||
bool success = v3d_get_device_info(drm_device.fd, &devinfo, &drmIoctl);
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
perfcntrs = v3d_perfcntrs_init(&devinfo, drm_device.fd);
|
||||
if (!perfcntrs)
|
||||
return false;
|
||||
|
||||
groups.clear();
|
||||
counters.clear();
|
||||
enabled_counters.clear();
|
||||
|
||||
struct drm_v3d_perfmon_create createreq = { 0 };
|
||||
CounterGroup group = {};
|
||||
|
||||
char *dup = strdup(v3d_ds_counter_env);
|
||||
char *name = strtok(dup, ",");
|
||||
while (name != NULL && createreq.ncounters < DRM_V3D_MAX_PERF_COUNTERS) {
|
||||
const struct v3d_perfcntr_desc *desc = v3d_perfcntrs_get_by_name(perfcntrs, name);
|
||||
if (desc) {
|
||||
Counter counter_desc = {};
|
||||
|
||||
counter_desc.units = Counter::Units::None;
|
||||
counter_desc.id = createreq.ncounters;
|
||||
counter_desc.name = desc->name;
|
||||
counter_desc.group = group.id;
|
||||
counter_desc.getter = [this](
|
||||
const Counter &c, const Driver &dri) -> Counter::Value {
|
||||
return static_cast<int64_t>(values[c.id]);
|
||||
};
|
||||
|
||||
counters.emplace_back(std::move(counter_desc));
|
||||
createreq.counters[createreq.ncounters++] = desc->index;
|
||||
} else {
|
||||
PERFETTO_ELOG("Unkown performance counter name: %s", name);
|
||||
}
|
||||
|
||||
name = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
free(dup);
|
||||
|
||||
if (createreq.ncounters == 0)
|
||||
return false;
|
||||
|
||||
int ret = drmIoctl(drm_device.fd, DRM_IOCTL_V3D_PERFMON_CREATE, &createreq);
|
||||
if (ret != 0)
|
||||
PERFETTO_FATAL("Failed to create perfmon %s", strerror(errno));
|
||||
|
||||
perfmon_id = createreq.id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
V3DDriver::enable_counter(uint32_t counter_id)
|
||||
{
|
||||
enabled_counters.push_back(counters[counter_id]);
|
||||
}
|
||||
|
||||
void
|
||||
V3DDriver::enable_all_counters()
|
||||
{
|
||||
enabled_counters.reserve(counters.size());
|
||||
enabled_counters.insert(enabled_counters.end(), counters.begin(), counters.end());
|
||||
}
|
||||
|
||||
void
|
||||
V3DDriver::enable_perfcnt(uint64_t sampling_period_ns)
|
||||
{
|
||||
struct drm_v3d_perfmon_set_global globalreq = {
|
||||
.id = perfmon_id,
|
||||
};
|
||||
|
||||
int ret = drmIoctl(drm_device.fd, DRM_IOCTL_V3D_PERFMON_SET_GLOBAL, &globalreq);
|
||||
if (ret != 0) {
|
||||
if (errno == ENOTTY)
|
||||
PERFETTO_FATAL("Failed to set global perfmon. Feature not available - update your kernel");
|
||||
else
|
||||
PERFETTO_FATAL("Failed to set global perfmon %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V3DDriver::disable_perfcnt()
|
||||
{
|
||||
struct drm_v3d_perfmon_set_global globalreq = {
|
||||
.flags = DRM_V3D_PERFMON_CLEAR_GLOBAL,
|
||||
.id = perfmon_id,
|
||||
};
|
||||
|
||||
int ret = drmIoctl(drm_device.fd, DRM_IOCTL_V3D_PERFMON_SET_GLOBAL, &globalreq);
|
||||
if (ret != 0)
|
||||
PERFETTO_FATAL("Failed to clear global perfmon %s", strerror(errno));
|
||||
|
||||
struct drm_v3d_perfmon_destroy destroyreq = {
|
||||
.id = perfmon_id,
|
||||
};
|
||||
|
||||
ret = drmIoctl(drm_device.fd, DRM_IOCTL_V3D_PERFMON_DESTROY, &destroyreq);
|
||||
if (ret != 0)
|
||||
PERFETTO_FATAL("Failed to destroy perfmon %s", strerror(errno));
|
||||
}
|
||||
|
||||
bool
|
||||
V3DDriver::dump_perfcnt()
|
||||
{
|
||||
last_dump_ts = perfetto::base::GetBootTimeNs().count();
|
||||
|
||||
struct drm_v3d_perfmon_get_values req = {
|
||||
.id = perfmon_id,
|
||||
.values_ptr = (uintptr_t)values,
|
||||
};
|
||||
|
||||
int ret = drmIoctl(drm_device.fd, DRM_IOCTL_V3D_PERFMON_GET_VALUES, &req);
|
||||
if (ret != 0) {
|
||||
PERFETTO_FATAL("Can't request perfmon counters values\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
V3DDriver::next()
|
||||
{
|
||||
auto ret = last_dump_ts;
|
||||
last_dump_ts = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
V3DDriver::gpu_clock_id() const
|
||||
{
|
||||
return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
V3DDriver::gpu_timestamp() const
|
||||
{
|
||||
return perfetto::base::GetBootTimeNs().count();
|
||||
}
|
||||
|
||||
bool
|
||||
V3DDriver::cpu_gpu_timestamp(uint64_t &, uint64_t &) const
|
||||
{
|
||||
/* Not supported */
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace pps
|
||||
41
src/broadcom/ds/v3d_pps_driver.h
Normal file
41
src/broadcom/ds/v3d_pps_driver.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright © 2024 Raspberry Pi Ltd
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/v3d_device_info.h"
|
||||
#include "drm-uapi/v3d_drm.h"
|
||||
#include "perfcntrs/v3d_perfcntrs.h"
|
||||
#include "pps/pps_driver.h"
|
||||
|
||||
namespace pps
|
||||
{
|
||||
|
||||
class V3DDriver : public Driver
|
||||
{
|
||||
public:
|
||||
uint64_t get_min_sampling_period_ns() override;
|
||||
bool init_perfcnt() override;
|
||||
void enable_counter(uint32_t counter_id) override;
|
||||
void enable_all_counters() override;
|
||||
void enable_perfcnt(uint64_t sampling_period_ns) override;
|
||||
void disable_perfcnt() override;
|
||||
bool dump_perfcnt() override;
|
||||
uint64_t next() override;
|
||||
uint32_t gpu_clock_id() const override;
|
||||
uint64_t gpu_timestamp() const override;
|
||||
bool cpu_gpu_timestamp(uint64_t &cpu_timestamp,
|
||||
uint64_t &gpu_timestamp) const override;
|
||||
|
||||
private:
|
||||
struct v3d_device_info devinfo;
|
||||
struct v3d_perfcntrs *perfcntrs;
|
||||
uint64_t last_dump_ts = 0;
|
||||
|
||||
unsigned int perfmon_id;
|
||||
uint64_t values[DRM_V3D_MAX_PERF_COUNTERS];
|
||||
};
|
||||
|
||||
} // namespace pps
|
||||
|
|
@ -75,6 +75,10 @@ libbroadcom_v3d = static_library(
|
|||
|
||||
subdir('perfcntrs')
|
||||
|
||||
if with_perfetto and (with_datasources.contains('v3d') or with_datasources.contains('auto'))
|
||||
subdir('ds')
|
||||
endif
|
||||
|
||||
if with_broadcom_vk
|
||||
subdir('vulkan')
|
||||
endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue