mesa: remove redudant check
[mesa.git] / src / mesa / main / performance_monitor.c
index 06c5c2f133bf0de5448b7180ddcecead75d95244..3273f156368ed6468c2c2b9db8c50f9b8418a47f 100644 (file)
@@ -42,8 +42,8 @@
 #include "macros.h"
 #include "mtypes.h"
 #include "performance_monitor.h"
-#include "bitset.h"
-#include "ralloc.h"
+#include "util/bitset.h"
+#include "util/ralloc.h"
 
 void
 _mesa_init_performance_monitors(struct gl_context *ctx)
@@ -53,6 +53,13 @@ _mesa_init_performance_monitors(struct gl_context *ctx)
    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)
 {
@@ -64,6 +71,8 @@ new_performance_monitor(struct gl_context *ctx, GLuint index)
 
    m->Name = index;
 
+   m->Active = false;
+
    m->ActiveGroups =
       rzalloc_array(NULL, unsigned, ctx->PerfMonitor.NumGroups);
 
@@ -91,6 +100,25 @@ fail:
    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)
 {
@@ -123,6 +151,7 @@ _mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize,
                               GLuint *groups)
 {
    GET_CURRENT_CONTEXT(ctx);
+   init_groups(ctx);
 
    if (numGroups != NULL)
       *numGroups = ctx->PerfMonitor.NumGroups;
@@ -143,7 +172,11 @@ _mesa_GetPerfMonitorCountersAMD(GLuint group, GLint *numCounters,
                                 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)");
@@ -171,9 +204,11 @@ _mesa_GetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize,
                                    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);
+   init_groups(ctx);
 
+   group_obj = get_group(ctx, group);
    if (group_obj == NULL) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glGetPerfMonitorGroupStringAMD");
       return;
@@ -203,6 +238,8 @@ _mesa_GetPerfMonitorCounterStringAMD(GLuint group, GLuint counter,
    const struct gl_perf_monitor_group *group_obj;
    const struct gl_perf_monitor_counter *counter_obj;
 
+   init_groups(ctx);
+
    group_obj = get_group(ctx, group);
 
    if (group_obj == NULL) {
@@ -242,6 +279,8 @@ _mesa_GetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname,
    const struct gl_perf_monitor_group *group_obj;
    const struct gl_perf_monitor_counter *counter_obj;
 
+   init_groups(ctx);
+
    group_obj = get_group(ctx, group);
 
    if (group_obj == NULL) {
@@ -305,6 +344,8 @@ _mesa_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors)
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glGenPerfMonitorsAMD(%d)\n", n);
 
+   init_groups(ctx);
+
    if (n < 0) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glGenPerfMonitorsAMD(n < 0)");
       return;
@@ -357,8 +398,10 @@ _mesa_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors)
 
       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);
@@ -437,14 +480,18 @@ _mesa_SelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable,
    if (enable) {
       /* Enable the counters */
       for (i = 0; i < numCounters; i++) {
-         ++m->ActiveGroups[group];
-         BITSET_SET(m->ActiveCounters[group], counterList[i]);
+         if (!BITSET_TEST(m->ActiveCounters[group], counterList[i])) {
+            ++m->ActiveGroups[group];
+            BITSET_SET(m->ActiveCounters[group], counterList[i]);
+         }
       }
    } else {
       /* Disable the counters */
       for (i = 0; i < numCounters; i++) {
-         --m->ActiveGroups[group];
-         BITSET_CLEAR(m->ActiveCounters[group], counterList[i]);
+         if (BITSET_TEST(m->ActiveCounters[group], counterList[i])) {
+            --m->ActiveGroups[group];
+            BITSET_CLEAR(m->ActiveCounters[group], counterList[i]);
+         }
       }
    }
 }
@@ -476,6 +523,7 @@ _mesa_BeginPerfMonitorAMD(GLuint monitor)
     */
    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)");
@@ -498,13 +546,14 @@ _mesa_EndPerfMonitorAMD(GLuint monitor)
     *  when a performance monitor is not currently started."
     */
    if (!m->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginPerfMonitor(not active)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndPerfMonitor(not active)");
       return;
    }
 
    ctx->Driver.EndPerfMonitor(ctx, m);
 
    m->Active = false;
+   m->Ended = true;
 }
 
 /**
@@ -519,11 +568,9 @@ perf_monitor_result_size(const struct gl_context *ctx,
 
    for (group = 0; group < ctx->PerfMonitor.NumGroups; group++) {
       const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[group];
-      for (counter = 0; counter < g->NumCounters; counter++) {
-         const struct gl_perf_monitor_counter *c = &g->Counters[counter];
 
-         if (!BITSET_TEST(m->ActiveCounters[group], counter))
-            continue;
+      BITSET_FOREACH_SET(counter, m->ActiveCounters[group], g->NumCounters) {
+         const struct gl_perf_monitor_counter *c = &g->Counters[counter];
 
          size += sizeof(uint32_t); /* Group ID */
          size += sizeof(uint32_t); /* Counter ID */
@@ -541,6 +588,7 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname,
    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,
@@ -562,8 +610,12 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname,
       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);