[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