aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDongwon Kim <[email protected]>2019-10-15 12:43:02 -0700
committerKenneth Graunke <[email protected]>2019-12-10 17:02:58 -0800
commit8a8534a69855fed209c1842f9e143c785809a7e3 (patch)
tree68bd033dcfb5039f29d46884edac51b0ec451334
parentca2dd99bf6ef0bb97ba50e817b3d32423484dc6c (diff)
iris: INTEL performance query implementation
low-level implementation of INTEL-performance-query APIs in Intel iris driver. Most of functions and procedures defined here are adopted from i965 driver (brw_performance_query.c) v2: - replace genX_init_performance_query with iris_init_perfquery_functions which is gen's version agnositic - general code clean-up v3: include gen_perf_gens.h as some of defines were moved to this new header file v4: - checking for kernel 4.13+ won't be needed here as Iris won't be loaded anyway without DRM_SYNCOBJ that is enabled after Kernel 4.13. - checking whether gen < 8 or is_cherryview won't be required as well because those cases are screened in iris_screen_create. v5: remove genX(init_performance_query) v6: - remove oa_metrics_kernel_support as iris works only with kernel 4.18 and newer. - use perf functions defined in separate file, iris_perf.h/c Signed-off-by: Dongwon Kim <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/gallium/drivers/iris/Makefile.sources1
-rw-r--r--src/gallium/drivers/iris/iris_context.c1
-rw-r--r--src/gallium/drivers/iris/iris_context.h1
-rw-r--r--src/gallium/drivers/iris/iris_performance_query.c236
-rw-r--r--src/gallium/drivers/iris/meson.build1
5 files changed, 240 insertions, 0 deletions
diff --git a/src/gallium/drivers/iris/Makefile.sources b/src/gallium/drivers/iris/Makefile.sources
index c203df18c65..2477d1e1369 100644
--- a/src/gallium/drivers/iris/Makefile.sources
+++ b/src/gallium/drivers/iris/Makefile.sources
@@ -45,6 +45,7 @@ IRIS_C_SOURCES = \
iris_genx_macros.h \
iris_genx_protos.h \
iris_monitor.c \
+ iris_performance_query.c \
iris_perf.c \
iris_pipe.h \
iris_pipe_control.c \
diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c
index ebbb865a150..b95ef707bf5 100644
--- a/src/gallium/drivers/iris/iris_context.c
+++ b/src/gallium/drivers/iris/iris_context.c
@@ -272,6 +272,7 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
iris_init_program_functions(ctx);
iris_init_resource_functions(ctx);
iris_init_flush_functions(ctx);
+ iris_init_perfquery_functions(ctx);
iris_init_program_cache(ice);
iris_init_border_color_pool(ice);
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index b81cd30441a..ab09d153661 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -767,6 +767,7 @@ void iris_init_blit_functions(struct pipe_context *ctx);
void iris_init_clear_functions(struct pipe_context *ctx);
void iris_init_program_functions(struct pipe_context *ctx);
void iris_init_resource_functions(struct pipe_context *ctx);
+void iris_init_perfquery_functions(struct pipe_context *ctx);
void iris_update_compiled_shaders(struct iris_context *ice);
void iris_update_compiled_compute_shader(struct iris_context *ice);
void iris_fill_cs_push_const_buffer(struct brw_cs_prog_data *cs_prog_data,
diff --git a/src/gallium/drivers/iris/iris_performance_query.c b/src/gallium/drivers/iris/iris_performance_query.c
new file mode 100644
index 00000000000..2f990762315
--- /dev/null
+++ b/src/gallium/drivers/iris/iris_performance_query.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * 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 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.
+ */
+
+#include <xf86drm.h>
+
+#include "iris_context.h"
+#include "iris_perf.h"
+
+#include "perf/gen_perf.h"
+#include "perf/gen_perf_regs.h"
+
+struct iris_perf_query {
+ struct gl_perf_query_object base;
+ struct gen_perf_query_object *query;
+};
+
+static unsigned
+iris_init_perf_query_info(struct pipe_context *pipe)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_screen *screen = (struct iris_screen *) ice->ctx.screen;
+ struct gen_perf_config *perf_cfg = NULL;
+
+ /* make sure pipe perf counter type/data-type enums are matched with gen_perf's */
+ STATIC_ASSERT(PIPE_PERF_COUNTER_TYPE_EVENT == (enum pipe_perf_counter_type)GEN_PERF_COUNTER_TYPE_EVENT);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_TYPE_DURATION_NORM == (enum pipe_perf_counter_type)GEN_PERF_COUNTER_TYPE_DURATION_NORM);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_TYPE_DURATION_RAW == (enum pipe_perf_counter_type)GEN_PERF_COUNTER_TYPE_DURATION_RAW);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_TYPE_THROUGHPUT == (enum pipe_perf_counter_type)GEN_PERF_COUNTER_TYPE_THROUGHPUT);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_TYPE_RAW == (enum pipe_perf_counter_type)GEN_PERF_COUNTER_TYPE_RAW);
+
+ STATIC_ASSERT(PIPE_PERF_COUNTER_DATA_TYPE_BOOL32 == (enum pipe_perf_counter_data_type)GEN_PERF_COUNTER_DATA_TYPE_BOOL32);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_DATA_TYPE_UINT32 == (enum pipe_perf_counter_data_type)GEN_PERF_COUNTER_DATA_TYPE_UINT32);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_DATA_TYPE_UINT64 == (enum pipe_perf_counter_data_type)GEN_PERF_COUNTER_DATA_TYPE_UINT64);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_DATA_TYPE_FLOAT == (enum pipe_perf_counter_data_type)GEN_PERF_COUNTER_DATA_TYPE_FLOAT);
+ STATIC_ASSERT(PIPE_PERF_COUNTER_DATA_TYPE_DOUBLE == (enum pipe_perf_counter_data_type)GEN_PERF_COUNTER_DATA_TYPE_DOUBLE);
+
+ if (!ice->perf_ctx)
+ ice->perf_ctx = gen_perf_new_context(ice);
+
+ if (unlikely(!ice->perf_ctx))
+ return 0;
+
+ perf_cfg = gen_perf_config(ice->perf_ctx);
+
+ if (perf_cfg)
+ return perf_cfg->n_queries;
+
+ perf_cfg = gen_perf_new(ice->perf_ctx);
+
+ iris_perf_init_vtbl(perf_cfg);
+
+ gen_perf_init_context(ice->perf_ctx,
+ perf_cfg,
+ ice,
+ screen->bufmgr,
+ &screen->devinfo,
+ ice->batches[IRIS_BATCH_RENDER].hw_ctx_id,
+ screen->fd);
+
+ gen_perf_init_metrics(perf_cfg, &screen->devinfo, screen->fd);
+
+ return perf_cfg->n_queries;
+}
+
+static struct pipe_query *
+iris_new_perf_query_obj(struct pipe_context *pipe, unsigned query_index)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+ struct gen_perf_query_object * obj = gen_perf_new_query(perf_ctx, query_index);
+ if (unlikely(!obj))
+ return NULL;
+
+ struct iris_perf_query *q = calloc(1, sizeof(struct iris_perf_query));
+ if (unlikely(!q)) {
+ gen_perf_delete_query(perf_ctx, obj);
+ return NULL;
+ }
+
+ q->query = obj;
+ return (struct pipe_query *)&q->base;
+}
+
+static void
+iris_begin_perf_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query= (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ gen_perf_begin_query(perf_ctx, obj);
+}
+
+static void
+iris_end_perf_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query = (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ gen_perf_end_query(perf_ctx, obj);
+}
+
+static void
+iris_delete_perf_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query = (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ gen_perf_delete_query(perf_ctx, obj);
+ free(q);
+}
+
+static void
+iris_get_perf_query_info(struct pipe_context *pipe,
+ unsigned query_index,
+ const char **name,
+ uint32_t *data_size,
+ uint32_t *n_counters,
+ uint32_t *n_active)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+ struct gen_perf_config *perf_cfg = gen_perf_config(perf_ctx);
+ const struct gen_perf_query_info *info = &perf_cfg->queries[query_index];
+
+ *name = info->name;
+ *data_size = info->data_size;
+ *n_counters = info->n_counters;
+ *n_active = gen_perf_active_queries(perf_ctx, info);
+}
+
+static void
+iris_get_perf_counter_info(struct pipe_context *pipe,
+ unsigned query_index,
+ unsigned counter_index,
+ const char **name,
+ const char **desc,
+ uint32_t *offset,
+ uint32_t *data_size,
+ uint32_t *type_enum,
+ uint32_t *data_type_enum,
+ uint64_t *raw_max)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+ struct gen_perf_config *perf_cfg = gen_perf_config(perf_ctx);
+ const struct gen_perf_query_info *info = &perf_cfg->queries[query_index];
+ const struct gen_perf_query_counter *counter = &info->counters[counter_index];
+
+ *name = counter->name;
+ *desc = counter->desc;
+ *offset = counter->offset;
+ *data_size = gen_perf_query_counter_get_size(counter);
+ *type_enum = counter->type;
+ *data_type_enum = counter->data_type;
+ *raw_max = counter->raw_max;
+}
+
+static void
+iris_wait_perf_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query = (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ gen_perf_wait_query(perf_ctx, obj, &ice->batches[IRIS_BATCH_RENDER]);
+}
+
+static bool
+iris_is_perf_query_ready(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query = (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ if (perf_query->base.Ready)
+ return true;
+
+ return gen_perf_is_query_ready(perf_ctx, obj, &ice->batches[IRIS_BATCH_RENDER]);
+}
+
+static void
+iris_get_perf_query_data(struct pipe_context *pipe,
+ struct pipe_query *q,
+ size_t data_size,
+ uint32_t *data,
+ uint32_t *bytes_written)
+{
+ struct iris_context *ice = (void *) pipe;
+ struct iris_perf_query *perf_query = (struct iris_perf_query *) q;
+ struct gen_perf_query_object *obj = perf_query->query;
+ struct gen_perf_context *perf_ctx = ice->perf_ctx;
+
+ gen_perf_get_query_data(perf_ctx, obj, data_size, data, bytes_written);
+}
+
+void
+iris_init_perfquery_functions(struct pipe_context *ctx)
+{
+ ctx->init_intel_perf_query_info = iris_init_perf_query_info;
+ ctx->get_intel_perf_query_info = iris_get_perf_query_info;
+ ctx->get_intel_perf_query_counter_info = iris_get_perf_counter_info;
+ ctx->new_intel_perf_query_obj = iris_new_perf_query_obj;
+ ctx->begin_intel_perf_query = iris_begin_perf_query;
+ ctx->end_intel_perf_query = iris_end_perf_query;
+ ctx->delete_intel_perf_query = iris_delete_perf_query;
+ ctx->wait_intel_perf_query = iris_wait_perf_query;
+ ctx->is_intel_perf_query_ready = iris_is_perf_query_ready;
+ ctx->get_intel_perf_query_data = iris_get_perf_query_data;
+}
diff --git a/src/gallium/drivers/iris/meson.build b/src/gallium/drivers/iris/meson.build
index f175b84fc1f..1ed507bc104 100644
--- a/src/gallium/drivers/iris/meson.build
+++ b/src/gallium/drivers/iris/meson.build
@@ -40,6 +40,7 @@ files_libiris = files(
'iris_perf.h',
'iris_perf.c',
'iris_monitor.c',
+ 'iris_performance_query.c',
'iris_pipe.h',
'iris_pipe_control.c',
'iris_program.c',