--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Intel Performance query interface to gallium.
+ */
+
+#include "st_debug.h"
+#include "st_context.h"
+#include "st_cb_bitmap.h"
+#include "st_cb_perfquery.h"
+#include "st_util.h"
+
+#include "util/bitset.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+
+bool
+st_have_perfquery(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+
+ return pipe->init_intel_perf_query_info && pipe->get_intel_perf_query_info &&
+ pipe->get_intel_perf_query_counter_info &&
+ pipe->new_intel_perf_query_obj && pipe->begin_intel_perf_query &&
+ pipe->end_intel_perf_query && pipe->delete_intel_perf_query &&
+ pipe->wait_intel_perf_query && pipe->is_intel_perf_query_ready &&
+ pipe->get_intel_perf_query_data;
+}
+
+static unsigned
+st_InitPerfQueryInfo(struct gl_context *ctx)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ return pipe->init_intel_perf_query_info(pipe);
+}
+
+static void
+st_GetPerfQueryInfo(struct gl_context *ctx,
+ unsigned query_index,
+ const char **name,
+ GLuint *data_size,
+ GLuint *n_counters,
+ GLuint *n_active)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ pipe->get_intel_perf_query_info(pipe, query_index, name, data_size,
+ n_counters, n_active);
+}
+
+static uint32_t
+pipe_counter_type_enum_to_gl_type(enum pipe_perf_counter_type type)
+{
+ switch (type) {
+ case PIPE_PERF_COUNTER_TYPE_EVENT: return GL_PERFQUERY_COUNTER_EVENT_INTEL;
+ case PIPE_PERF_COUNTER_TYPE_DURATION_NORM: return GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL;
+ case PIPE_PERF_COUNTER_TYPE_DURATION_RAW: return GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL;
+ case PIPE_PERF_COUNTER_TYPE_THROUGHPUT: return GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL;
+ case PIPE_PERF_COUNTER_TYPE_RAW: return GL_PERFQUERY_COUNTER_RAW_INTEL;
+ case PIPE_PERF_COUNTER_TYPE_TIMESTAMP: return GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL;
+ default:
+ unreachable("Unknown counter type");
+ }
+}
+
+static uint32_t
+pipe_counter_data_type_to_gl_type(enum pipe_perf_counter_data_type type)
+{
+ switch (type) {
+ case PIPE_PERF_COUNTER_DATA_TYPE_BOOL32: return GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL;
+ case PIPE_PERF_COUNTER_DATA_TYPE_UINT32: return GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL;
+ case PIPE_PERF_COUNTER_DATA_TYPE_UINT64: return GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL;
+ case PIPE_PERF_COUNTER_DATA_TYPE_FLOAT: return GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL;
+ case PIPE_PERF_COUNTER_DATA_TYPE_DOUBLE: return GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL;
+ default:
+ unreachable("Unknown counter data type");
+ }
+}
+
+static void
+st_GetPerfCounterInfo(struct gl_context *ctx,
+ unsigned query_index,
+ unsigned counter_index,
+ const char **name,
+ const char **desc,
+ GLuint *offset,
+ GLuint *data_size,
+ GLuint *type_enum,
+ GLuint *data_type_enum,
+ GLuint64 *raw_max)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ uint32_t pipe_type_enum;
+ uint32_t pipe_data_type_enum;
+
+ pipe->get_intel_perf_query_counter_info(pipe, query_index, counter_index,
+ name, desc, offset, data_size,
+ &pipe_type_enum, &pipe_data_type_enum, raw_max);
+ *type_enum = pipe_counter_type_enum_to_gl_type(pipe_type_enum);
+ *data_type_enum = pipe_counter_data_type_to_gl_type(pipe_data_type_enum);
+}
+
+static void
+st_DeletePerfQuery(struct gl_context *ctx, struct gl_perf_query_object *o)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ /* We can assume that the frontend waits for a query to complete
+ * before ever calling into here, so we don't have to worry about
+ * deleting an in-flight query object.
+ */
+ assert(!o->Active);
+ assert(!o->Used || o->Ready);
+
+ pipe->delete_intel_perf_query(pipe, (struct pipe_query *)o);
+}
+
+static bool
+st_BeginPerfQuery(struct gl_context *ctx, struct gl_perf_query_object *o)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ /* We can assume the frontend hides mistaken attempts to Begin a
+ * query object multiple times before its End. Similarly if an
+ * application reuses a query object before results have arrived
+ * the frontend will wait for prior results so we don't need
+ * to support abandoning in-flight results.
+ */
+ assert(!o->Active);
+ assert(!o->Used || o->Ready); /* no in-flight query to worry about */
+
+ pipe->begin_intel_perf_query(pipe, (struct pipe_query *)o);
+
+ return true;
+}
+
+static void
+st_EndPerfQuery(struct gl_context *ctx, struct gl_perf_query_object *o)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ pipe->end_intel_perf_query(pipe, (struct pipe_query *)o);
+}
+
+static void
+st_WaitPerfQuery(struct gl_context *ctx, struct gl_perf_query_object *o)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ assert(!o->Ready);
+
+ pipe->wait_intel_perf_query(pipe, (struct pipe_query *)o);
+}
+
+static bool
+st_IsPerfQueryReady(struct gl_context *ctx, struct gl_perf_query_object *o)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ if (o->Ready)
+ return true;
+
+ return pipe->is_intel_perf_query_ready(pipe, (struct pipe_query *)o);
+}
+
+static void
+st_GetPerfQueryData(struct gl_context *ctx,
+ struct gl_perf_query_object *o,
+ GLsizei data_size,
+ GLuint *data,
+ GLuint *bytes_written)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+
+ assert(st_IsPerfQueryReady(ctx, o));
+
+ /* We expect that the frontend only calls this hook when it knows
+ * that results are available.
+ */
+ assert(o->Ready);
+
+ pipe->get_intel_perf_query_data(pipe, (struct pipe_query *)o, data_size, data,
+ bytes_written);
+}
+
+static struct gl_perf_query_object *
+st_NewPerfQueryObject(struct gl_context *ctx, unsigned query_index)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct pipe_query *q;
+
+ q = pipe->new_intel_perf_query_obj(pipe, query_index);
+
+ return (struct gl_perf_query_object *)q;
+}
+
+void st_init_perfquery_functions(struct dd_function_table *functions)
+{
+ functions->InitPerfQueryInfo = st_InitPerfQueryInfo;
+ functions->GetPerfQueryInfo = st_GetPerfQueryInfo;
+ functions->GetPerfCounterInfo = st_GetPerfCounterInfo;
+ functions->NewPerfQueryObject = st_NewPerfQueryObject;
+ functions->DeletePerfQuery = st_DeletePerfQuery;
+ functions->BeginPerfQuery = st_BeginPerfQuery;
+ functions->EndPerfQuery = st_EndPerfQuery;
+ functions->WaitPerfQuery = st_WaitPerfQuery;
+ functions->IsPerfQueryReady = st_IsPerfQueryReady;
+ functions->GetPerfQueryData = st_GetPerfQueryData;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef ST_CB_PERFQUERY_H
+#define ST_CB_PERFQUERY_H
+
+bool
+st_have_perfquery(struct st_context *st);
+
+extern void
+st_init_perfquery_functions(struct dd_function_table *functions);
+
+#endif