mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 17:10:11 +01:00
freedreno: batch query support (perfcounters)
Core infrastructure for performance counters, using gallium's batch query interface (to support AMD_performance_monitor). Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
9e30e7490d
commit
33af91dc07
7 changed files with 154 additions and 4 deletions
|
|
@ -16,6 +16,7 @@ C_SOURCES := \
|
|||
freedreno_fence.h \
|
||||
freedreno_gmem.c \
|
||||
freedreno_gmem.h \
|
||||
freedreno_perfcntr.h \
|
||||
freedreno_program.c \
|
||||
freedreno_program.h \
|
||||
freedreno_query.c \
|
||||
|
|
|
|||
72
src/gallium/drivers/freedreno/freedreno_perfcntr.h
Normal file
72
src/gallium/drivers/freedreno/freedreno_perfcntr.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Rob Clark <robclark@freedesktop.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Rob Clark <robclark@freedesktop.org>
|
||||
*/
|
||||
|
||||
#ifndef FREEDRENO_PERFCNTR_H_
|
||||
#define FREEDRENO_PERFCNTR_H_
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
/*
|
||||
* Mapping very closely to the AMD_performance_monitor extension, adreno has
|
||||
* groups of performance counters where each group has N counters, which can
|
||||
* select from M different countables (things that can be counted), where
|
||||
* generally M > N.
|
||||
*/
|
||||
|
||||
/* Describes a single counter: */
|
||||
struct fd_perfcntr_counter {
|
||||
/* offset of the select register to choose what to count: */
|
||||
unsigned select_reg;
|
||||
/* offset of the lo/hi 32b to read current counter value: */
|
||||
unsigned counter_reg_lo;
|
||||
unsigned counter_reg_hi;
|
||||
/* Optional, most counters don't have enable/clear registers: */
|
||||
unsigned enable;
|
||||
unsigned clear;
|
||||
};
|
||||
|
||||
/* Describes a single countable: */
|
||||
struct fd_perfcntr_countable {
|
||||
const char *name;
|
||||
/* selector register enum value to select this countable: */
|
||||
unsigned selector;
|
||||
|
||||
/* description of the countable: */
|
||||
enum pipe_driver_query_type query_type;
|
||||
enum pipe_driver_query_result_type result_type;
|
||||
};
|
||||
|
||||
/* Describes an entire counter group: */
|
||||
struct fd_perfcntr_group {
|
||||
const char *name;
|
||||
unsigned num_counters;
|
||||
const struct fd_perfcntr_counter *counters;
|
||||
unsigned num_countables;
|
||||
const struct fd_perfcntr_countable *countables;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FREEDRENO_PERFCNTR_H_ */
|
||||
|
|
@ -150,25 +150,88 @@ static int
|
|||
fd_get_driver_query_info(struct pipe_screen *pscreen,
|
||||
unsigned index, struct pipe_driver_query_info *info)
|
||||
{
|
||||
if (!info)
|
||||
return ARRAY_SIZE(sw_query_list);
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
|
||||
if (index >= ARRAY_SIZE(sw_query_list))
|
||||
return 0;
|
||||
if (!info)
|
||||
return ARRAY_SIZE(sw_query_list) + screen->num_perfcntr_queries;
|
||||
|
||||
if (index >= ARRAY_SIZE(sw_query_list)) {
|
||||
index -= ARRAY_SIZE(sw_query_list);
|
||||
if (index >= screen->num_perfcntr_queries)
|
||||
return 0;
|
||||
*info = screen->perfcntr_queries[index];
|
||||
return 1;
|
||||
}
|
||||
|
||||
*info = sw_query_list[index];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
fd_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned index,
|
||||
struct pipe_driver_query_group_info *info)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
|
||||
if (!info)
|
||||
return screen->num_perfcntr_groups;
|
||||
|
||||
if (index >= screen->num_perfcntr_groups)
|
||||
return 0;
|
||||
|
||||
const struct fd_perfcntr_group *g = &screen->perfcntr_groups[index];
|
||||
|
||||
info->name = g->name;
|
||||
info->max_active_queries = g->num_counters;
|
||||
info->num_queries = g->num_countables;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
fd_set_active_query_state(struct pipe_context *pipe, boolean enable)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
setup_perfcntr_query_info(struct fd_screen *screen)
|
||||
{
|
||||
unsigned num_queries = 0;
|
||||
|
||||
for (unsigned i = 0; i < screen->num_perfcntr_groups; i++)
|
||||
num_queries += screen->perfcntr_groups[i].num_countables;
|
||||
|
||||
screen->perfcntr_queries =
|
||||
calloc(num_queries, sizeof(screen->perfcntr_queries[0]));
|
||||
screen->num_perfcntr_queries = num_queries;
|
||||
|
||||
unsigned idx = 0;
|
||||
for (unsigned i = 0; i < screen->num_perfcntr_groups; i++) {
|
||||
const struct fd_perfcntr_group *g = &screen->perfcntr_groups[i];
|
||||
for (unsigned j = 0; j < g->num_countables; j++) {
|
||||
struct pipe_driver_query_info *info =
|
||||
&screen->perfcntr_queries[idx];
|
||||
const struct fd_perfcntr_countable *c =
|
||||
&g->countables[j];
|
||||
|
||||
info->name = c->name;
|
||||
info->query_type = FD_QUERY_FIRST_PERFCNTR + idx;
|
||||
info->type = c->query_type;
|
||||
info->result_type = c->result_type;
|
||||
info->group_id = i;
|
||||
info->flags = PIPE_DRIVER_QUERY_FLAG_BATCH;
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fd_query_screen_init(struct pipe_screen *pscreen)
|
||||
{
|
||||
pscreen->get_driver_query_info = fd_get_driver_query_info;
|
||||
pscreen->get_driver_query_group_info = fd_get_driver_query_group_info;
|
||||
setup_perfcntr_query_info(fd_screen(pscreen));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ fd_query(struct pipe_query *pq)
|
|||
#define FD_QUERY_SHADOW_UPLOADS (PIPE_QUERY_DRIVER_SPECIFIC + 7) /* texture/buffer uploads that shadowed rsc */
|
||||
#define FD_QUERY_VS_REGS (PIPE_QUERY_DRIVER_SPECIFIC + 8) /* avg # of VS registers (scaled up by 100x) */
|
||||
#define FD_QUERY_FS_REGS (PIPE_QUERY_DRIVER_SPECIFIC + 9) /* avg # of VS registers (scaled up by 100x) */
|
||||
/* insert any new non-perfcntr queries here, the first perfcntr index
|
||||
* needs to come last!
|
||||
*/
|
||||
#define FD_QUERY_FIRST_PERFCNTR (PIPE_QUERY_DRIVER_SPECIFIC + 10)
|
||||
|
||||
void fd_query_screen_init(struct pipe_screen *pscreen);
|
||||
void fd_query_context_init(struct pipe_context *pctx);
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ fd_screen_destroy(struct pipe_screen *pscreen)
|
|||
|
||||
ralloc_free(screen->compiler);
|
||||
|
||||
free(screen->perfcntr_queries);
|
||||
free(screen);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "os/os_thread.h"
|
||||
|
||||
#include "freedreno_batch_cache.h"
|
||||
#include "freedreno_perfcntr.h"
|
||||
#include "freedreno_util.h"
|
||||
|
||||
struct fd_bo;
|
||||
|
|
@ -71,6 +72,13 @@ struct fd_screen {
|
|||
uint32_t priority_mask;
|
||||
bool has_timestamp;
|
||||
|
||||
unsigned num_perfcntr_groups;
|
||||
const struct fd_perfcntr_group *perfcntr_groups;
|
||||
|
||||
/* generated at startup from the perfcntr groups: */
|
||||
unsigned num_perfcntr_queries;
|
||||
struct pipe_driver_query_info *perfcntr_queries;
|
||||
|
||||
void *compiler; /* currently unused for a2xx */
|
||||
|
||||
struct fd_device *dev;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ files_libfreedreno = files(
|
|||
'freedreno_fence.h',
|
||||
'freedreno_gmem.c',
|
||||
'freedreno_gmem.h',
|
||||
'freedreno_perfcntr.h',
|
||||
'freedreno_program.c',
|
||||
'freedreno_program.h',
|
||||
'freedreno_query.c',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue