mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-04 19:20:38 +01:00
pan/trace: Add wrappers for Mesa CPU scope traces
Add the PAN_TRACE_SCOPE() and PAN_TRACE_FUNC() wrappers based on
MESA_TRACE_SCOPE_IF() in order to associate a category to each trace
and let users select the set of tracing categories to enable at
run-time through the PAN_CPU_TRACE environment variable. This makes
Panfrost tracing an opt-in and avoids to CPU cost of tracing by
default.
There are 3 categories for now:
- "lib" for the shared utilities
- "gl" for the Gallium driver
- "vk" for the Vulkan driver
Each of these categories are divided into subcategories so that
subsystems can easily be traced ("gl.csf" or "lib.kmod" for instance).
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Reviewed-by: Ashley Smith <ashley.smith@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39407>
This commit is contained in:
parent
c9097e2e13
commit
1bca181580
3 changed files with 196 additions and 0 deletions
|
|
@ -48,6 +48,7 @@ libpanfrost_lib_files = files(
|
|||
'pan_tiler.c',
|
||||
'pan_layout.c',
|
||||
'pan_scratch.c',
|
||||
'pan_trace.c',
|
||||
'pan_props.c',
|
||||
'pan_util.c',
|
||||
'pan_afbc.c',
|
||||
|
|
|
|||
102
src/panfrost/lib/pan_trace.c
Normal file
102
src/panfrost/lib/pan_trace.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright © 2026 Amazon.com, Inc. or its affiliates.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "pan_trace.h"
|
||||
|
||||
#include "util/os_misc.h"
|
||||
|
||||
#define PAN_TRACE_ENV_VAR "PAN_CPU_TRACE"
|
||||
|
||||
#define CATEGORY(str, flag) { str, ARRAY_SIZE(str) - 1, (uint64_t) (flag) }
|
||||
|
||||
/* To be kept in sync with the pan_trace_category enum in pan_trace.h. */
|
||||
/* clang-format off */
|
||||
static struct {
|
||||
const char *str;
|
||||
size_t len;
|
||||
uint64_t flag;
|
||||
} categories_table[] = {
|
||||
/* Library categories. */
|
||||
CATEGORY("lib.afbc", PAN_TRACE_LIB_AFBC),
|
||||
CATEGORY("lib.desc", PAN_TRACE_LIB_DESC),
|
||||
CATEGORY("lib.kmod", PAN_TRACE_LIB_KMOD),
|
||||
|
||||
CATEGORY("lib", PAN_TRACE_LIB_AFBC |
|
||||
PAN_TRACE_LIB_DESC |
|
||||
PAN_TRACE_LIB_KMOD),
|
||||
|
||||
/* Gallium categories. */
|
||||
CATEGORY("gl.blit", PAN_TRACE_GL_BLIT),
|
||||
CATEGORY("gl.bo", PAN_TRACE_GL_BO),
|
||||
CATEGORY("gl.cmdstream", PAN_TRACE_GL_CMDSTREAM),
|
||||
CATEGORY("gl.context", PAN_TRACE_GL_CONTEXT),
|
||||
CATEGORY("gl.csf", PAN_TRACE_GL_CSF),
|
||||
CATEGORY("gl.disk_cache", PAN_TRACE_GL_DISK_CACHE),
|
||||
CATEGORY("gl.fb_preload", PAN_TRACE_GL_FB_PRELOAD),
|
||||
CATEGORY("gl.jm", PAN_TRACE_GL_JM),
|
||||
CATEGORY("gl.job", PAN_TRACE_GL_JOB),
|
||||
CATEGORY("gl.mempool", PAN_TRACE_GL_MEMPOOL),
|
||||
CATEGORY("gl.resource", PAN_TRACE_GL_RESOURCE),
|
||||
CATEGORY("gl.shader", PAN_TRACE_GL_SHADER),
|
||||
|
||||
CATEGORY("gl", PAN_TRACE_GL_BLIT |
|
||||
PAN_TRACE_GL_BO |
|
||||
PAN_TRACE_GL_CMDSTREAM |
|
||||
PAN_TRACE_GL_CONTEXT |
|
||||
PAN_TRACE_GL_CSF |
|
||||
PAN_TRACE_GL_DISK_CACHE |
|
||||
PAN_TRACE_GL_FB_PRELOAD |
|
||||
PAN_TRACE_GL_JM |
|
||||
PAN_TRACE_GL_JOB |
|
||||
PAN_TRACE_GL_MEMPOOL |
|
||||
PAN_TRACE_GL_RESOURCE |
|
||||
PAN_TRACE_GL_SHADER),
|
||||
|
||||
/* Vulkan categories. */
|
||||
CATEGORY("vk.csf", PAN_TRACE_VK_CSF),
|
||||
|
||||
CATEGORY("vk", PAN_TRACE_VK_CSF),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
uint64_t pan_trace_categories = 0;
|
||||
|
||||
static bool
|
||||
is_separator(char c)
|
||||
{
|
||||
return c == ',' || c == ';' || c == ' ';
|
||||
}
|
||||
|
||||
void
|
||||
pan_trace_init(void)
|
||||
{
|
||||
const char *list = os_get_option(PAN_TRACE_ENV_VAR);
|
||||
const char *str = NULL;
|
||||
uint64_t categories = 0;
|
||||
char prev_char = ',';
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
/* Parse list and flag enabled categories. */
|
||||
for (int i = 0; prev_char; prev_char = list[i++]) {
|
||||
if (!is_separator(list[i]) && list[i]) {
|
||||
if (is_separator(prev_char))
|
||||
str = &list[i];
|
||||
} else if (!is_separator(prev_char)) {
|
||||
for (int j = 0; j < ARRAY_SIZE(categories_table); j++) {
|
||||
size_t len = &list[i] - str;
|
||||
if (categories_table[j].len == len &&
|
||||
!strncasecmp(categories_table[j].str, str, len)) {
|
||||
categories |= categories_table[j].flag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pan_trace_categories = categories;
|
||||
}
|
||||
93
src/panfrost/lib/pan_trace.h
Normal file
93
src/panfrost/lib/pan_trace.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright © 2026 Amazon.com, Inc. or its affiliates.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __PAN_TRACE_H
|
||||
#define __PAN_TRACE_H
|
||||
|
||||
#include "util/perf/cpu_trace.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Panfrost wrappers for Mesa CPU scope traces.
|
||||
*
|
||||
* CPU tracing (not to be confused with GPU command stream tracing with
|
||||
* PAN_MESA_DEBUG=trace) is often enabled in release builds. Since each trace
|
||||
* pushed down the underlying tracing backend (Perfetto, Gpuvis, sysprof, etc)
|
||||
* has a slight cost, Panfrost extends the Mesa CPU scope traces by
|
||||
* associating each trace to a category that must be enabled at run-time. This
|
||||
* allows to keep adding useful trace points into Panfrost without worrying
|
||||
* about the implied inherent latency.
|
||||
*
|
||||
* There are 3 categories ("lib" for the shared utilities, "gl" for Gallium,
|
||||
* "vk" for PanVK) divided into subcategories so that subsystems can easily be
|
||||
* traced. A list of categories can be passed to Panfrost through the
|
||||
* PAN_CPU_TRACE environment variable like that:
|
||||
*
|
||||
* $ PAN_CPU_TRACE=gl,lib program
|
||||
*
|
||||
* Passing a category enables traces for all its subcategories. Subcategories
|
||||
* can be passed instead for finer grained traces like that:
|
||||
*
|
||||
* $ PAN_CPU_TRACE=gl.blit,gl.bo,gl.job program
|
||||
*/
|
||||
|
||||
/* Panfrost trace categories.
|
||||
*
|
||||
* To be kept in sync with the categories_table array in pan_trace.c.
|
||||
*/
|
||||
/* clang-format off */
|
||||
enum pan_trace_category {
|
||||
/* Library categories. */
|
||||
PAN_TRACE_LIB_AFBC = BITFIELD_BIT(1), /* "lib.afbc" */
|
||||
PAN_TRACE_LIB_DESC = BITFIELD_BIT(2), /* "lib.desc" */
|
||||
PAN_TRACE_LIB_KMOD = BITFIELD_BIT(3), /* "lib.kmod" */
|
||||
|
||||
/* Gallium categories. */
|
||||
PAN_TRACE_GL_BLIT = BITFIELD_BIT(4), /* "gl.blit" */
|
||||
PAN_TRACE_GL_BO = BITFIELD_BIT(5), /* "gl.bo" */
|
||||
PAN_TRACE_GL_CMDSTREAM = BITFIELD_BIT(6), /* "gl.cmdstream" */
|
||||
PAN_TRACE_GL_CONTEXT = BITFIELD_BIT(7), /* "gl.context" */
|
||||
PAN_TRACE_GL_CSF = BITFIELD_BIT(8), /* "gl.csf" */
|
||||
PAN_TRACE_GL_DISK_CACHE = BITFIELD_BIT(9), /* "gl.disk_cache" */
|
||||
PAN_TRACE_GL_FB_PRELOAD = BITFIELD_BIT(10), /* "gl.fb_preload" */
|
||||
PAN_TRACE_GL_JM = BITFIELD_BIT(11), /* "gl.jm" */
|
||||
PAN_TRACE_GL_JOB = BITFIELD_BIT(12), /* "gl.job" */
|
||||
PAN_TRACE_GL_MEMPOOL = BITFIELD_BIT(13), /* "gl.mempool" */
|
||||
PAN_TRACE_GL_RESOURCE = BITFIELD_BIT(14), /* "gl.resource" */
|
||||
PAN_TRACE_GL_SHADER = BITFIELD_BIT(15), /* "gl.shader" */
|
||||
|
||||
/* Vulkan categories. */
|
||||
PAN_TRACE_VK_CSF = BITFIELD_BIT(16), /* "vk.csf" */
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
extern uint64_t pan_trace_categories;
|
||||
|
||||
/* Add a Mesa CPU scope trace for a given Panfrost category using printf like
|
||||
* formatting.
|
||||
*/
|
||||
#define PAN_TRACE_SCOPE(category, format, ...) \
|
||||
MESA_TRACE_SCOPE_IF(category & pan_trace_categories, format, ##__VA_ARGS__)
|
||||
|
||||
/* Add a Mesa CPU scope trace for a given Panfrost category using current
|
||||
* function name.
|
||||
*/
|
||||
#define PAN_TRACE_FUNC(category) \
|
||||
MESA_TRACE_FUNC_IF(category & pan_trace_categories)
|
||||
|
||||
/* Parse the PAN_CPU_TRACE environment variable and initialize CPU tracing.
|
||||
* The PAN_CPU_TRACE environment variable stores a list of categories (see
|
||||
* enum pan_trace_category) separated by a comma, a semicolon or a space.
|
||||
*/
|
||||
void pan_trace_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif /* __PAN_TRACE_H */
|
||||
Loading…
Add table
Reference in a new issue