> 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?
pgppvQk3AVwnK.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev