[Mesa-dev] [PATCH resend] mesa: Add core support for the GL_AMD_performance_monitor extension.

Eric Anholt eric at anholt.net
Fri Apr 12 13:20:31 PDT 2013


> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
> index 8f3cd3d..60e7653 100644
> --- a/src/mesa/main/dd.h
> +++ b/src/mesa/main/dd.h
> @@ -646,6 +646,28 @@ struct dd_function_table {
>     void (*WaitQuery)(struct gl_context *ctx, struct gl_query_object *q);
>     /*@}*/
>  
> +   /**
> +    * \name Performance monitors
> +    */
> +   /*@{*/
> +   struct gl_perf_monitor_object * (*NewPerfMonitor)(void);
> +   void (*DeletePerfMonitor)(struct gl_perf_monitor_object *m);
> +   void (*BeginPerfMonitor)(struct gl_context *ctx,
> +                            struct gl_perf_monitor_object *m);
> +
> +   /** Stop an active performance monitor, discarding results. */
> +   void (*ResetPerfMonitor)(struct gl_context *ctx,
> +                            struct gl_perf_monitor_object *m);
> +   void (*EndPerfMonitor)(struct gl_context *ctx,
> +                          struct gl_perf_monitor_object *m);
> +   GLboolean (*IsPerfMonitorResultAvailable)(struct gl_perf_monitor_object *m);
> +   void (*GetPerfMonitorResult)(struct gl_context *ctx,
> +                                struct gl_perf_monitor_object *m,
> +                                GLsizei dataSize,
> +                                GLuint *data,
> +                                GLint *bytesWritten);
> +   /*@}*/
> +
>  
>     /**
>      * \name Vertex Array objects
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index e46fa39..892f8e8 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -1774,6 +1774,87 @@ struct gl_transform_feedback_state
>  
>  
>  /**
> + * A "performance monitor" as described in AMD_performance_monitor.
> + */
> +struct gl_perf_monitor_object
> +{
> +   GLboolean Active;
> +
> +   /* Actually BITSET_WORD but we can't #include that here. */
> +   GLuint *ActiveCounters;

This should probably be void * instead of something you might
acidentally do the wrong bitfield manipulation on.

> +void GLAPIENTRY
> +_mesa_GetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize,
> +                                   GLsizei *length, GLchar *groupString)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   const struct gl_perf_monitor_group *group_obj = get_group(ctx, group);
> +
> +   if (group_obj == NULL) {
> +      _mesa_error(ctx, GL_INVALID_VALUE, "glGetPerfMonitorGroupStringAMD");
> +      return;
> +   }
> +
> +   if (bufSize == 0) {
> +      /* Return the number of characters that would be required to hold the
> +       * group string, excluding the null terminator.
> +       */
> +      if (length != NULL)
> +         *length = strlen(group_obj->Name);
> +   } else {
> +      if (length != NULL)
> +         *length = MIN2(strlen(group_obj->Name), bufSize);
> +      if (groupString != NULL)
> +         strncpy(groupString, group_obj->Name, bufSize);

I think you could use the usual _mesa_copy_string() here (and
elsewhere).  It enforces null termination, which seems like a really
good idea.

> +void GLAPIENTRY
> +_mesa_GetPerfMonitorCounterStringAMD(GLuint group, GLuint counter,
> +                                     GLsizei bufSize, GLsizei *length,
> +                                     GLchar *counterString)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   const struct gl_perf_monitor_counter *counter_obj;
> +
> +   /* Validate the group even though we don't use it. */
> +   if (get_group(ctx, group) == NULL) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> +                  "glGetPerfMonitorCounterStringAMD(invalid group)");
> +      return;
> +   }
> +
> +   if (counter >= ctx->PerfMonitor.NumCounters) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> +                  "glGetPerfMonitorCounterStringAMD(invalid counter)");
> +      return;
> +   }
> +
> +   counter_obj = &ctx->PerfMonitor.Counters[counter];

Also check that counter_obj->GroupID == group ("or <counter> does not
reference a valid counter within the group ID")

> +void GLAPIENTRY
> +_mesa_GetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname,
> +                                   GLvoid *data)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   const struct gl_perf_monitor_counter *counter_obj;
> +
> +   /* Validate the group even though we don't use it. */
> +   if (get_group(ctx, group) == NULL) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> +                  "glGetPerfMonitorCounterInfoAMD(invalid group)");
> +      return;
> +   }
> +
> +   if (counter >= ctx->PerfMonitor.NumCounters) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> +                  "glGetPerfMonitorCounterInfoAMD(invalid counter)");
> +      return;
> +   }
> +
> +   counter_obj = &ctx->PerfMonitor.Counters[counter];

Same.

> +void GLAPIENTRY
> +_mesa_SelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable,
> +                                   GLuint group, GLint numCounters,
> +                                   GLuint *counterList)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +   int i;
> +   struct gl_perf_monitor_object *m = lookup_monitor(ctx, monitor);

> +   /* "When SelectPerfMonitorCountersAMD is called on a monitor, any outstanding 
> +    *  results for that monitor become invalidated and the result queries 
> +    *  PERFMON_RESULT_SIZE_AMD and PERFMON_RESULT_AVAILABLE_AMD are reset to 0."
> +    */
> +   ctx->Driver.ResetPerfMonitor(ctx, m);
> +
> +   if (enable) {
> +      /* Enable the counters */
> +      for (i = 0; i < numCounters; i++) {
> +         BITSET_SET(m->ActiveCounters, counterList[i]);
> +      }
> +   } else {
> +      /* Disable the counters */
> +      for (i = 0; i < numCounters; i++) {
> +         BITSET_CLEAR(m->ActiveCounters, counterList[i]);
> +      }
> +   }
> +}

No error for trying to enable/disable a counter not in "group"?  That
sounds like a mistake in the spec.

> +/*
> +void
> +_mesa_init_perf_monitors(struct gl_context *ctx,
> +                         const struct gl_perf_monitor_counter *counters,
> +                         unsigned num_counters,
> +                         const struct gl_perf_monitor_group *groups,
> +                         unsigned num_groups)
> +{
> +   ctx->PerfMonitor.Groups = groups;
> +   ctx->PerfMonitor.NumGroups = num_groups;
> +   ctx->PerfMonitor.Counters = counters;
> +   ctx->PerfMonitor.NumCounters = num_counters;
> +}
> +*/

Commented out function?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130412/6fa5be2e/attachment.pgp>


More information about the mesa-dev mailing list