Most applications never use performance counters, so allow drivers to
skip potentially expensive initialization steps.
A driver that wants to use this must enable the appropriate extension(s)
at context initialization and set the InitPerfMonitorGroups driver function
which will be called the first time information about the performance monitor
groups is actually used.
The init_groups helper is called for API functions that can be called before
a monitor object exists. Functions that require an existing monitor object
can rely on init_groups having been called before.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
* \name Performance monitors
*/
/*@{*/
* \name Performance monitors
*/
/*@{*/
+ void (*InitPerfMonitorGroups)(struct gl_context *ctx);
struct gl_perf_monitor_object * (*NewPerfMonitor)(struct gl_context *ctx);
void (*DeletePerfMonitor)(struct gl_context *ctx,
struct gl_perf_monitor_object *m);
struct gl_perf_monitor_object * (*NewPerfMonitor)(struct gl_context *ctx);
void (*DeletePerfMonitor)(struct gl_context *ctx,
struct gl_perf_monitor_object *m);
ctx->PerfMonitor.Groups = NULL;
}
ctx->PerfMonitor.Groups = NULL;
}
+static inline void
+init_groups(struct gl_context *ctx)
+{
+ if (unlikely(!ctx->PerfMonitor.Groups))
+ ctx->Driver.InitPerfMonitorGroups(ctx);
+}
+
static struct gl_perf_monitor_object *
new_performance_monitor(struct gl_context *ctx, GLuint index)
{
static struct gl_perf_monitor_object *
new_performance_monitor(struct gl_context *ctx, GLuint index)
{
GLuint *groups)
{
GET_CURRENT_CONTEXT(ctx);
GLuint *groups)
{
GET_CURRENT_CONTEXT(ctx);
if (numGroups != NULL)
*numGroups = ctx->PerfMonitor.NumGroups;
if (numGroups != NULL)
*numGroups = ctx->PerfMonitor.NumGroups;
GLsizei countersSize, GLuint *counters)
{
GET_CURRENT_CONTEXT(ctx);
GLsizei countersSize, GLuint *counters)
{
GET_CURRENT_CONTEXT(ctx);
- const struct gl_perf_monitor_group *group_obj = get_group(ctx, group);
+ const struct gl_perf_monitor_group *group_obj;
+
+ init_groups(ctx);
+
+ group_obj = get_group(ctx, group);
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetPerfMonitorCountersAMD(invalid group)");
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetPerfMonitorCountersAMD(invalid group)");
GLsizei *length, GLchar *groupString)
{
GET_CURRENT_CONTEXT(ctx);
GLsizei *length, GLchar *groupString)
{
GET_CURRENT_CONTEXT(ctx);
+ const struct gl_perf_monitor_group *group_obj;
- const struct gl_perf_monitor_group *group_obj = get_group(ctx, group);
+ group_obj = get_group(ctx, group);
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetPerfMonitorGroupStringAMD");
return;
if (group_obj == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetPerfMonitorGroupStringAMD");
return;
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
const struct gl_perf_monitor_group *group_obj;
const struct gl_perf_monitor_counter *counter_obj;
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
group_obj = get_group(ctx, group);
if (group_obj == NULL) {
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGenPerfMonitorsAMD(%d)\n", n);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glGenPerfMonitorsAMD(%d)\n", n);
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGenPerfMonitorsAMD(n < 0)");
return;
if (n < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGenPerfMonitorsAMD(n < 0)");
return;
GET_CURRENT_CONTEXT(ctx);
unsigned numGroups;
GET_CURRENT_CONTEXT(ctx);
unsigned numGroups;
/* The GL_INTEL_performance_query spec says:
*
* "If queryId pointer is equal to 0, INVALID_VALUE error is generated."
/* The GL_INTEL_performance_query spec says:
*
* "If queryId pointer is equal to 0, INVALID_VALUE error is generated."
_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId)
{
GET_CURRENT_CONTEXT(ctx);
/* The GL_INTEL_performance_query spec says:
*
/* The GL_INTEL_performance_query spec says:
*
GET_CURRENT_CONTEXT(ctx);
unsigned i;
GET_CURRENT_CONTEXT(ctx);
unsigned i;
/* The GL_INTEL_performance_query spec says:
*
* "If queryName does not reference a valid query name, an INVALID_VALUE
/* The GL_INTEL_performance_query spec says:
*
* "If queryName does not reference a valid query name, an INVALID_VALUE
GET_CURRENT_CONTEXT(ctx);
unsigned i;
GET_CURRENT_CONTEXT(ctx);
unsigned i;
- const struct gl_perf_monitor_group *group_obj =
- get_group(ctx, queryid_to_index(queryId));
+ const struct gl_perf_monitor_group *group_obj;
+ init_groups(ctx);
+
+ group_obj = get_group(ctx, queryid_to_index(queryId));
if (group_obj == NULL) {
/* The GL_INTEL_performance_query spec says:
*
if (group_obj == NULL) {
/* The GL_INTEL_performance_query spec says:
*
unsigned counterIndex;
unsigned i;
unsigned counterIndex;
unsigned i;
group_obj = get_group(ctx, queryid_to_index(queryId));
/* The GL_INTEL_performance_query spec says:
group_obj = get_group(ctx, queryid_to_index(queryId));
/* The GL_INTEL_performance_query spec says:
struct gl_perf_monitor_object *m;
unsigned i;
struct gl_perf_monitor_object *m;
unsigned i;
/* This is not specified in the extension, but is the only sane thing to
* do.
*/
/* This is not specified in the extension, but is the only sane thing to
* do.
*/