etnaviv: add perfmon query implementation
Add needed infrastructure to use performance monitor requests for queries. Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> Tested-by: Chris Healy <cphealy@gmail.com>
This commit is contained in:
parent
7e3dba301e
commit
72d2043be0
|
@ -79,7 +79,7 @@ LIBDRM_INTEL_REQUIRED=2.4.75
|
|||
LIBDRM_NVVIEUX_REQUIRED=2.4.66
|
||||
LIBDRM_NOUVEAU_REQUIRED=2.4.66
|
||||
LIBDRM_FREEDRENO_REQUIRED=2.4.91
|
||||
LIBDRM_ETNAVIV_REQUIRED=2.4.82
|
||||
LIBDRM_ETNAVIV_REQUIRED=2.4.89
|
||||
|
||||
dnl Versions for external dependencies
|
||||
DRI2PROTO_REQUIRED=2.8
|
||||
|
|
|
@ -1037,7 +1037,7 @@ dep_libdrm_intel = null_dep
|
|||
_drm_amdgpu_ver = '2.4.91'
|
||||
_drm_radeon_ver = '2.4.71'
|
||||
_drm_nouveau_ver = '2.4.66'
|
||||
_drm_etnaviv_ver = '2.4.82'
|
||||
_drm_etnaviv_ver = '2.4.89'
|
||||
_drm_freedreno_ver = '2.4.91'
|
||||
_drm_intel_ver = '2.4.75'
|
||||
_drm_ver = '2.4.75'
|
||||
|
|
|
@ -35,6 +35,8 @@ C_SOURCES := \
|
|||
etnaviv_query_hw.h \
|
||||
etnaviv_query_sw.c \
|
||||
etnaviv_query_sw.h \
|
||||
etnaviv_query_pm.c \
|
||||
etnaviv_query_pm.h \
|
||||
etnaviv_rasterizer.c \
|
||||
etnaviv_rasterizer.h \
|
||||
etnaviv_resource.c \
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "etnaviv_query.h"
|
||||
#include "etnaviv_query_hw.h"
|
||||
#include "etnaviv_query_sw.h"
|
||||
#include "etnaviv_query_pm.h"
|
||||
|
||||
static struct pipe_query *
|
||||
etna_create_query(struct pipe_context *pctx, unsigned query_type,
|
||||
|
@ -43,6 +44,8 @@ etna_create_query(struct pipe_context *pctx, unsigned query_type,
|
|||
q = etna_sw_create_query(ctx, query_type);
|
||||
if (!q)
|
||||
q = etna_hw_create_query(ctx, query_type);
|
||||
if (!q)
|
||||
q = etna_pm_create_query(ctx, query_type);
|
||||
|
||||
return (struct pipe_query *)q;
|
||||
}
|
||||
|
@ -103,11 +106,15 @@ etna_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
|
|||
struct pipe_driver_query_info *info)
|
||||
{
|
||||
int nr_sw_queries = etna_sw_get_driver_query_info(pscreen, 0, NULL);
|
||||
int nr_pm_queries = etna_pm_get_driver_query_info(pscreen, 0, NULL);
|
||||
|
||||
if (!info)
|
||||
return nr_sw_queries;
|
||||
return nr_sw_queries + nr_pm_queries;
|
||||
|
||||
return etna_sw_get_driver_query_info(pscreen, index, info);
|
||||
if (index < nr_sw_queries)
|
||||
return etna_sw_get_driver_query_info(pscreen, index, info);
|
||||
|
||||
return etna_pm_get_driver_query_info(pscreen, index - nr_sw_queries, info);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -54,6 +54,7 @@ etna_query(struct pipe_query *pq)
|
|||
}
|
||||
|
||||
#define ETNA_SW_QUERY_BASE (PIPE_QUERY_DRIVER_SPECIFIC + 0)
|
||||
#define ETNA_PM_QUERY_BASE (PIPE_QUERY_DRIVER_SPECIFIC + 32)
|
||||
|
||||
void
|
||||
etna_query_screen_init(struct pipe_screen *pscreen);
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Etnaviv Project
|
||||
* Copyright (C) 2017 Zodiac Inflight Innovations
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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:
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "etnaviv_context.h"
|
||||
#include "etnaviv_query_pm.h"
|
||||
#include "etnaviv_screen.h"
|
||||
|
||||
struct etna_perfmon_source
|
||||
{
|
||||
const char *domain;
|
||||
const char *signal;
|
||||
};
|
||||
|
||||
struct etna_perfmon_config
|
||||
{
|
||||
const char *name;
|
||||
unsigned type;
|
||||
const struct etna_perfmon_source *source;
|
||||
};
|
||||
|
||||
static const struct etna_perfmon_config query_config[] = {
|
||||
};
|
||||
|
||||
static const struct etna_perfmon_config *
|
||||
etna_pm_query_config(unsigned type)
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++)
|
||||
if (query_config[i].type == type)
|
||||
return &query_config[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct etna_perfmon_signal *
|
||||
etna_pm_query_signal(struct etna_perfmon *perfmon,
|
||||
const struct etna_perfmon_source *source)
|
||||
{
|
||||
struct etna_perfmon_domain *domain;
|
||||
|
||||
domain = etna_perfmon_get_dom_by_name(perfmon, source->domain);
|
||||
if (!domain)
|
||||
return NULL;
|
||||
|
||||
return etna_perfmon_get_sig_by_name(domain, source->signal);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
etna_pm_cfg_supported(struct etna_perfmon *perfmon,
|
||||
const struct etna_perfmon_config *cfg)
|
||||
{
|
||||
struct etna_perfmon_signal *signal = etna_pm_query_signal(perfmon, cfg->source);
|
||||
|
||||
return !!signal;
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_pm_add_signal(struct etna_pm_query *pq, struct etna_perfmon *perfmon,
|
||||
const struct etna_perfmon_config *cfg)
|
||||
{
|
||||
struct etna_perfmon_signal *signal = etna_pm_query_signal(perfmon, cfg->source);
|
||||
|
||||
pq->signal = signal;
|
||||
}
|
||||
|
||||
static bool
|
||||
realloc_query_bo(struct etna_context *ctx, struct etna_pm_query *pq)
|
||||
{
|
||||
if (pq->bo)
|
||||
etna_bo_del(pq->bo);
|
||||
|
||||
pq->bo = etna_bo_new(ctx->screen->dev, 64, DRM_ETNA_GEM_CACHE_WC);
|
||||
if (unlikely(!pq->bo))
|
||||
return false;
|
||||
|
||||
pq->data = etna_bo_map(pq->bo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_pm_query_get(struct etna_cmd_stream *stream, struct etna_query *q,
|
||||
unsigned flags)
|
||||
{
|
||||
struct etna_pm_query *pq = etna_pm_query(q);
|
||||
unsigned offset;
|
||||
assert(flags);
|
||||
|
||||
if (flags == ETNA_PM_PROCESS_PRE)
|
||||
offset = 2;
|
||||
else
|
||||
offset = 3;
|
||||
|
||||
struct etna_perf p = {
|
||||
.flags = flags,
|
||||
.sequence = pq->sequence,
|
||||
.bo = pq->bo,
|
||||
.signal = pq->signal,
|
||||
.offset = offset
|
||||
};
|
||||
|
||||
etna_cmd_stream_perf(stream, &p);
|
||||
}
|
||||
|
||||
static inline void
|
||||
etna_pm_query_update(struct etna_query *q)
|
||||
{
|
||||
struct etna_pm_query *pq = etna_pm_query(q);
|
||||
|
||||
if (pq->data[0] == pq->sequence)
|
||||
pq->ready = true;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_pm_destroy_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
struct etna_pm_query *pq = etna_pm_query(q);
|
||||
|
||||
etna_bo_del(pq->bo);
|
||||
FREE(pq);
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_pm_begin_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
struct etna_pm_query *pq = etna_pm_query(q);
|
||||
|
||||
pq->ready = false;
|
||||
pq->sequence++;
|
||||
|
||||
etna_pm_query_get(ctx->stream, q, ETNA_PM_PROCESS_PRE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_pm_end_query(struct etna_context *ctx, struct etna_query *q)
|
||||
{
|
||||
etna_pm_query_get(ctx->stream, q, ETNA_PM_PROCESS_POST);
|
||||
}
|
||||
|
||||
static boolean
|
||||
etna_pm_get_query_result(struct etna_context *ctx, struct etna_query *q,
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct etna_pm_query *pq = etna_pm_query(q);
|
||||
|
||||
etna_pm_query_update(q);
|
||||
|
||||
if (!pq->ready) {
|
||||
if (!wait)
|
||||
return false;
|
||||
|
||||
if (!etna_bo_cpu_prep(pq->bo, DRM_ETNA_PREP_READ))
|
||||
return false;
|
||||
|
||||
pq->ready = true;
|
||||
etna_bo_cpu_fini(pq->bo);
|
||||
}
|
||||
|
||||
result->u32 = pq->data[2] - pq->data[1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct etna_query_funcs hw_query_funcs = {
|
||||
.destroy_query = etna_pm_destroy_query,
|
||||
.begin_query = etna_pm_begin_query,
|
||||
.end_query = etna_pm_end_query,
|
||||
.get_query_result = etna_pm_get_query_result,
|
||||
};
|
||||
|
||||
struct etna_query *
|
||||
etna_pm_create_query(struct etna_context *ctx, unsigned query_type)
|
||||
{
|
||||
struct etna_perfmon *perfmon = ctx->screen->perfmon;
|
||||
const struct etna_perfmon_config *cfg;
|
||||
struct etna_pm_query *pq;
|
||||
struct etna_query *q;
|
||||
|
||||
cfg = etna_pm_query_config(query_type);
|
||||
if (!cfg)
|
||||
return NULL;
|
||||
|
||||
if (!etna_pm_cfg_supported(perfmon, cfg))
|
||||
return NULL;
|
||||
|
||||
pq = CALLOC_STRUCT(etna_pm_query);
|
||||
if (!pq)
|
||||
return NULL;
|
||||
|
||||
if (!realloc_query_bo(ctx, pq)) {
|
||||
FREE(pq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
q = &pq->base;
|
||||
q->funcs = &hw_query_funcs;
|
||||
q->type = query_type;
|
||||
|
||||
etna_pm_add_signal(pq, perfmon, cfg);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
void
|
||||
etna_pm_query_setup(struct etna_screen *screen)
|
||||
{
|
||||
screen->perfmon = etna_perfmon_create(screen->pipe);
|
||||
|
||||
if (!screen->perfmon)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(query_config); i++) {
|
||||
const struct etna_perfmon_config *cfg = &query_config[i];
|
||||
|
||||
if (!etna_pm_cfg_supported(screen->perfmon, cfg))
|
||||
continue;
|
||||
|
||||
util_dynarray_append(&screen->supported_pm_queries, unsigned, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
etna_pm_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
|
||||
struct pipe_driver_query_info *info)
|
||||
{
|
||||
const struct etna_screen *screen = etna_screen(pscreen);
|
||||
const unsigned num = screen->supported_pm_queries.size / sizeof(unsigned);
|
||||
unsigned i;
|
||||
|
||||
if (!info)
|
||||
return num;
|
||||
|
||||
if (index >= num)
|
||||
return 0;
|
||||
|
||||
i = *util_dynarray_element(&screen->supported_pm_queries, unsigned, index);
|
||||
assert(i < ARRAY_SIZE(query_config));
|
||||
|
||||
info->name = query_config[i].name;
|
||||
info->query_type = query_config[i].type;
|
||||
info->group_id = 0;
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Etnaviv Project
|
||||
* Copyright (C) 2017 Zodiac Inflight Innovations
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. 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>
|
||||
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef H_ETNAVIV_QUERY_PM
|
||||
#define H_ETNAVIV_QUERY_PM
|
||||
|
||||
#include "etnaviv_query.h"
|
||||
|
||||
struct etna_screen;
|
||||
|
||||
struct etna_pm_query {
|
||||
struct etna_query base;
|
||||
struct etna_perfmon_signal *signal;
|
||||
struct etna_bo *bo;
|
||||
uint32_t *data;
|
||||
uint32_t sequence;
|
||||
bool ready;
|
||||
};
|
||||
|
||||
static inline struct etna_pm_query *
|
||||
etna_pm_query(struct etna_query *q)
|
||||
{
|
||||
return (struct etna_pm_query *)q;
|
||||
}
|
||||
|
||||
void
|
||||
etna_pm_query_setup(struct etna_screen *screen);
|
||||
|
||||
struct etna_query *
|
||||
etna_pm_create_query(struct etna_context *ctx, unsigned query_type);
|
||||
|
||||
int
|
||||
etna_pm_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
|
||||
struct pipe_driver_query_info *info);
|
||||
|
||||
#endif
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#define ETNA_DRM_VERSION(major, minor) ((major) << 16 | (minor))
|
||||
#define ETNA_DRM_VERSION_FENCE_FD ETNA_DRM_VERSION(1, 1)
|
||||
#define ETNA_DRM_VERSION_PERFMON ETNA_DRM_VERSION(1, 2)
|
||||
|
||||
static const struct debug_named_value debug_options[] = {
|
||||
{"dbg_msgs", ETNA_DBG_MSGS, "Print debug messages"},
|
||||
|
@ -80,6 +81,9 @@ etna_screen_destroy(struct pipe_screen *pscreen)
|
|||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
if (screen->perfmon)
|
||||
etna_perfmon_del(screen->perfmon);
|
||||
|
||||
if (screen->pipe)
|
||||
etna_pipe_del(screen->pipe);
|
||||
|
||||
|
@ -986,8 +990,12 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
|
|||
etna_query_screen_init(pscreen);
|
||||
etna_resource_screen_init(pscreen);
|
||||
|
||||
util_dynarray_init(&screen->supported_pm_queries, NULL);
|
||||
slab_create_parent(&screen->transfer_pool, sizeof(struct etna_transfer), 16);
|
||||
|
||||
if (screen->drm_version >= ETNA_DRM_VERSION_PERFMON)
|
||||
etna_pm_query_setup(screen);
|
||||
|
||||
return pscreen;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
#define H_ETNAVIV_SCREEN
|
||||
|
||||
#include "etnaviv_internal.h"
|
||||
#include "etnaviv_query_pm.h"
|
||||
|
||||
#include "os/os_thread.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "renderonly/renderonly.h"
|
||||
#include "util/slab.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
struct etna_bo;
|
||||
|
||||
|
@ -65,8 +67,10 @@ struct etna_screen {
|
|||
struct etna_device *dev;
|
||||
struct etna_gpu *gpu;
|
||||
struct etna_pipe *pipe;
|
||||
struct etna_perfmon *perfmon;
|
||||
struct renderonly *ro;
|
||||
|
||||
struct util_dynarray supported_pm_queries;
|
||||
struct slab_parent_pool transfer_pool;
|
||||
|
||||
uint32_t model;
|
||||
|
|
Loading…
Reference in New Issue