if (m == NULL)
return NULL;
+ m->Name = index;
+
+ m->Active = false;
+
m->ActiveGroups =
rzalloc_array(NULL, unsigned, ctx->PerfMonitor.NumGroups);
return NULL;
}
+static void
+free_performance_monitor(GLuint key, void *data, void *user)
+{
+ struct gl_perf_monitor_object *m = data;
+ struct gl_context *ctx = user;
+
+ ralloc_free(m->ActiveGroups);
+ ralloc_free(m->ActiveCounters);
+ ctx->Driver.DeletePerfMonitor(ctx, m);
+}
+
+void
+_mesa_free_performance_monitors(struct gl_context *ctx)
+{
+ _mesa_HashDeleteAll(ctx->PerfMonitor.Monitors,
+ free_performance_monitor, ctx);
+ _mesa_DeleteHashTable(ctx->PerfMonitor.Monitors);
+}
+
static inline struct gl_perf_monitor_object *
lookup_monitor(struct gl_context *ctx, GLuint id)
{
if (m) {
/* Give the driver a chance to stop the monitor if it's active. */
- if (m->Active)
+ if (m->Active) {
ctx->Driver.ResetPerfMonitor(ctx, m);
+ m->Ended = false;
+ }
_mesa_HashRemove(ctx->PerfMonitor.Monitors, monitors[i]);
ralloc_free(m->ActiveGroups);
*/
if (ctx->Driver.BeginPerfMonitor(ctx, m)) {
m->Active = true;
+ m->Ended = false;
} else {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBeginPerfMonitor(driver unable to begin monitoring)");
ctx->Driver.EndPerfMonitor(ctx, m);
m->Active = false;
+ m->Ended = true;
}
/**
GET_CURRENT_CONTEXT(ctx);
struct gl_perf_monitor_object *m = lookup_monitor(ctx, monitor);
+ bool result_available;
if (m == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE,
return;
}
+ /* If the monitor has never ended, there is no result. */
+ result_available = m->Ended &&
+ ctx->Driver.IsPerfMonitorResultAvailable(ctx, m);
+
/* AMD appears to return 0 for all queries unless a result is available. */
- if (!ctx->Driver.IsPerfMonitorResultAvailable(ctx, m)) {
+ if (!result_available) {
*data = 0;
if (bytesWritten != NULL)
*bytesWritten = sizeof(GLuint);