On 04/03/2014 02:20 AM, Petri Latvala wrote: > Like AMD_performance_monitor, this extension provides an interface for > applications (and OpenGL-based tools) to access GPU performance > counters. Since the exact performance counters available vary between > vendors and hardware generations, the extension provides an API the > application can use to get the names, types, and minimum/maximum > values of all available counters. > > Applications create performance queries based on available query > types, and begin/end measurement collection. Multiple queries can be > measuring simultaneously. > > v2: Whitespace changes. > v3: src/mapi/glapi/gen/gl_API.xml: Also expose the functions to GLES2. > > Signed-off-by: Petri Latvala <petri.latv...@intel.com>
There are a few nits below and one substantive change for INTEL_performance_query.xml. With those fixed, this patch is Reviewed-by: Ian Romanick <ian.d.roman...@intel.com> > --- > src/mapi/glapi/gen/INTEL_performance_query.xml | 93 ++++++++++++ > src/mapi/glapi/gen/Makefile.am | 1 + > src/mapi/glapi/gen/gl_API.xml | 2 + > src/mesa/main/config.h | 8 + > src/mesa/main/extensions.c | 1 + > src/mesa/main/get.c | 1 + > src/mesa/main/get_hash_params.py | 6 + > src/mesa/main/mtypes.h | 1 + > src/mesa/main/performance_monitor.c | 195 > +++++++++++++++++++++++++ > src/mesa/main/performance_monitor.h | 43 +++++- > src/mesa/main/tests/dispatch_sanity.cpp | 12 ++ > 11 files changed, 362 insertions(+), 1 deletion(-) > create mode 100644 src/mapi/glapi/gen/INTEL_performance_query.xml > > diff --git a/src/mapi/glapi/gen/INTEL_performance_query.xml > b/src/mapi/glapi/gen/INTEL_performance_query.xml > new file mode 100644 > index 0000000..0f4d687 > --- /dev/null > +++ b/src/mapi/glapi/gen/INTEL_performance_query.xml > @@ -0,0 +1,93 @@ > +<?xml version="1.0"?> > +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> > + > +<OpenGLAPI> > + > +<category name="GL_INTEL_performance_query" number="443"> > + > + <function name="GetFirstPerfQueryIdINTEL" offset="assign" es2="2.0"> These should also all have static_dispatch="false". This prevents the functions from being statically exposed by libGL or libGLES_v2. Instead, applications have to use glXGetProcAddress or eglGetProcAddress. > + <param name="queryId" type="GLuint *"/> > + </function> > + > + <function name="GetNextPerfQueryIdINTEL" offset="assign" es2="2.0"> > + <param name="queryId" type="GLuint"/> > + <param name="nextQueryId" type="GLuint *"/> > + </function> > + > + <function name="GetPerfQueryIdByNameINTEL" offset="assign" es2="2.0"> > + <param name="queryName" type="GLchar *"/> > + <param name="queryId" type="GLuint *"/> > + </function> > + > + <function name="GetPerfQueryInfoINTEL" offset="assign" es2="2.0"> > + <param name="queryId" type="GLuint"/> > + <param name="queryNameLength" type="GLuint"/> > + <param name="queryName" type="GLchar *"/> > + <param name="dataSize" type="GLuint *"/> > + <param name="noCounters" type="GLuint *"/> > + <param name="noInstances" type="GLuint *"/> > + <param name="capsMask" type="GLuint *"/> > + </function> > + > + <function name="GetPerfCounterInfoINTEL" offset="assign" es2="2.0"> > + <param name="queryId" type="GLuint"/> > + <param name="counterId" type="GLuint"/> > + <param name="counterNameLength" type="GLuint"/> > + <param name="counterName" type="GLchar *"/> > + <param name="counterDescLength" type="GLuint"/> > + <param name="counterDesc" type="GLchar *"/> > + <param name="counterOffset" type="GLuint *"/> > + <param name="counterDataSize" type="GLuint *"/> > + <param name="counterTypeEnum" type="GLuint *"/> > + <param name="counterDataTypeEnum" type="GLuint *"/> > + <param name="rawCounterMaxValue" type="GLuint64 *"/> > + </function> > + > + <function name="CreatePerfQueryINTEL" offset="assign" es2="2.0"> > + <param name="queryId" type="GLuint"/> > + <param name="queryHandle" type="GLuint *"/> > + </function> > + > + <function name="DeletePerfQueryINTEL" offset="assign" es2="2.0"> > + <param name="queryHandle" type="GLuint"/> > + </function> > + > + <function name="BeginPerfQueryINTEL" offset="assign" es2="2.0"> > + <param name="queryHandle" type="GLuint"/> > + </function> > + > + <function name="EndPerfQueryINTEL" offset="assign" es2="2.0"> > + <param name="queryHandle" type="GLuint"/> > + </function> > + > + <function name="GetPerfQueryDataINTEL" offset="assign" es2="2.0"> > + <param name="queryHandle" type="GLuint"/> > + <param name="flags" type="GLuint"/> > + <param name="dataSize" type="GLsizei"/> > + <param name="data" type="GLvoid *"/> > + <param name="bytesWritten" type="GLuint *"/> > + </function> > + > + <enum name="PERFQUERY_SINGLE_CONTEXT_INTEL" value="0x0000"/> > + <enum name="PERFQUERY_GLOBAL_CONTEXT_INTEL" value="0x0001"/> > + <enum name="PERFQUERY_WAIT_INTEL" value="0x83FB"/> > + <enum name="PERFQUERY_FLUSH_INTEL" value="0x83FA"/> > + <enum name="PERFQUERY_DONOT_FLUSH_INTEL" value="0x83F9"/> > + <enum name="PERFQUERY_COUNTER_EVENT_INTEL" value="0x94F0"/> > + <enum name="PERFQUERY_COUNTER_DURATION_NORM_INTEL" value="0x94F1"/> > + <enum name="PERFQUERY_COUNTER_DURATION_RAW_INTEL" value="0x94F2"/> > + <enum name="PERFQUERY_COUNTER_THROUGHPUT_INTEL" value="0x94F3"/> > + <enum name="PERFQUERY_COUNTER_RAW_INTEL" value="0x94F4"/> > + <enum name="PERFQUERY_COUNTER_TIMESTAMP_INTEL" value="0x94F5"/> > + <enum name="PERFQUERY_COUNTER_DATA_UINT32_INTEL" value="0x94F8"/> > + <enum name="PERFQUERY_COUNTER_DATA_UINT64_INTEL" value="0x94F9"/> > + <enum name="PERFQUERY_COUNTER_DATA_FLOAT_INTEL" value="0x94FA"/> > + <enum name="PERFQUERY_COUNTER_DATA_DOUBLE_INTEL" value="0x94FB"/> > + <enum name="PERFQUERY_COUNTER_DATA_BOOL32_INTEL" value="0x94FC"/> > + <enum name="PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL" value="0x94FD"/> > + <enum name="PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL" value="0x94FE"/> > + <enum name="PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL" value="0x94FF"/> > + <enum name="PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL" value="0x9500"/> > +</category> > + > +</OpenGLAPI> > diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am > index 7b3c118..1c5b61c 100644 > --- a/src/mapi/glapi/gen/Makefile.am > +++ b/src/mapi/glapi/gen/Makefile.am > @@ -147,6 +147,7 @@ API_XML = \ > EXT_texture_array.xml \ > EXT_texture_integer.xml \ > EXT_transform_feedback.xml \ > + INTEL_performance_query.xml \ > NV_conditional_render.xml \ > NV_primitive_restart.xml \ > NV_texture_barrier.xml \ > diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml > index 9129d57..8fbf700 100644 > --- a/src/mapi/glapi/gen/gl_API.xml > +++ b/src/mapi/glapi/gen/gl_API.xml > @@ -12840,6 +12840,8 @@ > <enum name="SKIP_DECODE_EXT" value="0x8A4A"/> > </category> > > +<xi:include href="INTEL_performance_query.xml" > xmlns:xi="http://www.w3.org/2001/XInclude"/> > + > <!-- Unnumbered extensions sorted by name. --> > > <category name="GL_ATI_blend_equation_separate"> > diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h > index 30da5d4..c96502a 100644 > --- a/src/mesa/main/config.h > +++ b/src/mesa/main/config.h > @@ -281,6 +281,14 @@ > #define MAX_VERTEX_STREAMS 4 > /*@}*/ > > +/** For GL_INTEL_performance_query */ > +/*@{*/ > +#define MAX_PERFQUERY_QUERY_NAME_LENGTH 256 > +#define MAX_PERFQUERY_COUNTER_NAME_LENGTH 256 > +#define MAX_PERFQUERY_COUNTER_DESC_LENGTH 1024 > +#define PERFQUERY_HAVE_GPA_EXTENDED_COUNTERS 0 > +/*@}*/ > + > /* > * Color channel component order > * > diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c > index a72284c..e8f125d 100644 > --- a/src/mesa/main/extensions.c > +++ b/src/mesa/main/extensions.c > @@ -330,6 +330,7 @@ static const struct extension extension_table[] = { > { "GL_IBM_rasterpos_clip", o(dummy_true), > GLL, 1996 }, > { "GL_IBM_texture_mirrored_repeat", o(dummy_true), > GLL, 1998 }, > { "GL_INGR_blend_func_separate", > o(EXT_blend_func_separate), GLL, 1999 }, > + { "GL_INTEL_performance_query", > o(INTEL_performance_query), GL | ES2, 2013 }, The ES2 should line up with the other ES2s. > { "GL_MESA_pack_invert", o(MESA_pack_invert), > GL, 2002 }, > { "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), > GL, 2009 }, > { "GL_MESA_window_pos", o(dummy_true), > GLL, 2000 }, > diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c > index 88cf202..8c4ac08 100644 > --- a/src/mesa/main/get.c > +++ b/src/mesa/main/get.c > @@ -394,6 +394,7 @@ EXTRA_EXT(ARB_viewport_array); > EXTRA_EXT(ARB_compute_shader); > EXTRA_EXT(ARB_gpu_shader5); > EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5); > +EXTRA_EXT(INTEL_performance_query); > > static const int > extra_ARB_color_buffer_float_or_glcore[] = { > diff --git a/src/mesa/main/get_hash_params.py > b/src/mesa/main/get_hash_params.py > index 674d003..4c0838e 100644 > --- a/src/mesa/main/get_hash_params.py > +++ b/src/mesa/main/get_hash_params.py > @@ -311,6 +311,12 @@ descriptor=[ > # GL_ARB_get_program_binary / GL_OES_get_program_binary > [ "NUM_PROGRAM_BINARY_FORMATS", "CONST(0), NO_EXTRA" ], > [ "PROGRAM_BINARY_FORMATS", "LOC_CUSTOM, TYPE_INVALID, 0, NO_EXTRA" ], > + > +# GL_INTEL_performance_query > + [ "PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL", > "CONST(MAX_PERFQUERY_QUERY_NAME_LENGTH), extra_INTEL_performance_query" ], > + [ "PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL", > "CONST(MAX_PERFQUERY_COUNTER_NAME_LENGTH), extra_INTEL_performance_query" ], > + [ "PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL", > "CONST(MAX_PERFQUERY_COUNTER_DESC_LENGTH), extra_INTEL_performance_query" ], > + [ "PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL", > "CONST(PERFQUERY_HAVE_GPA_EXTENDED_COUNTERS), extra_INTEL_performance_query" > ], > ]}, > > # GLES3 is not a typo. > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h > index c6d90c5..aa39f79 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -3598,6 +3598,7 @@ struct gl_extensions > GLboolean ATI_texture_env_combine3; > GLboolean ATI_fragment_shader; > GLboolean ATI_separate_stencil; > + GLboolean INTEL_performance_query; > GLboolean MESA_pack_invert; > GLboolean MESA_ycbcr_texture; > GLboolean NV_conditional_render; > diff --git a/src/mesa/main/performance_monitor.c > b/src/mesa/main/performance_monitor.c > index e62f770..dd22fef 100644 > --- a/src/mesa/main/performance_monitor.c > +++ b/src/mesa/main/performance_monitor.c > @@ -639,3 +639,198 @@ _mesa_perf_monitor_counter_size(const struct > gl_perf_monitor_counter *c) > return 0; > } > } > + > +extern void GLAPIENTRY > +_mesa_GetFirstPerfQueryIdINTEL(GLuint *queryId) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If queryId pointer is equal to 0, INVALID_VALUE error is generated." > + */ These all should be formatted like other spec references in Mesa: /* The GL_INTEL_performance_query spec says: * * "If queryId pointer is equal to 0, INVALID_VALUE error is generated." */ > + if (!queryId) { > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetFirstPerfQueryIdINTEL(queryId == NULL)"); > + return; > + } > + > + /* "If the given hardware platform doesn't support any performance > queries, > + * then the value of 0 is returned and INVALID_OPERATION error is raised." > + */ > + > + *queryId = 0; > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "glGetFirstPerfQueryIdINTEL(no queries supported)"); > +} > + > +extern void GLAPIENTRY > +_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If nextQueryId pointer is equal to 0, an INVALID_VALUE error is > + * generated." > + */ > + if (!nextQueryId) { > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetNextPerfQueryIdINTEL(nextQueryId == NULL)"); > + return; > + } > + > + /* "If the specified performance > + * query identifier is invalid then INVALID_VALUE error is generated." > + * > + * No queries are supported, so all queries are invalid. > + * > + * "Whenever error is generated, the value of 0 is returned." > + */ > + *nextQueryId = 0; > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetNextPerfQueryIdINTEL(invalid query)"); > +} > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If queryName does not reference a valid query name, an INVALID_VALUE > + * error is generated." > + * > + * No queries are supported, so all query names are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetPerfQueryIdByNameINTEL(invalid query name)"); > +} > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryInfoINTEL(GLuint queryId, > + GLuint queryNameLength, char *queryName, > + GLuint *dataSize, GLuint *noCounters, > + GLuint *noActiveInstances, > + GLuint *capsMask) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If queryId does not reference a valid query type, an INVALID_VALUE > + * error is generated." > + * > + * No queries are supported, so all queries are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetPerfQueryInfoINTEL(invalid query)"); > +} > + > +extern void GLAPIENTRY > +_mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, > + GLuint counterNameLength, char *counterName, > + GLuint counterDescLength, char *counterDesc, > + GLuint *counterOffset, GLuint > *counterDataSize, GLuint *counterTypeEnum, > + GLuint *counterDataTypeEnum, GLuint64 > *rawCounterMaxValue) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If the pair of queryId and counterId does not reference a valid > counter, > + * an INVALID_VALUE error is generated." > + * > + * No queries are supported, so all queries are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetPerfCounterInfoINTEL(invalid counterId)"); > +} > + > +extern void GLAPIENTRY > +_mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If queryId does not reference a valid query type, > + * an INVALID_VALUE error is generated." > + * > + * No queries are supported, so all queries are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glCreatePerfQueryINTEL(invalid queryId)"); > +} > + > +extern void GLAPIENTRY > +_mesa_DeletePerfQueryINTEL(GLuint queryHandle) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If a query handle doesn't reference a previously created performance > + * query instance, an INVALID_VALUE error is generated." > + * > + * No queries are supported, so all queries are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glDeletePerfQueryINTEL(invalid queryHandle)"); > +} > + > +extern void GLAPIENTRY > +_mesa_BeginPerfQueryINTEL(GLuint queryHandle) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If a query handle doesn't reference a previously created performance > + * query instance, an INVALID_VALUE error is generated." > + * > + * No queries are supported, so all queries are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glBeginPerfQueryINTEL(invalid queryHandle)"); > +} > + > +extern void GLAPIENTRY > +_mesa_EndPerfQueryINTEL(GLuint queryHandle) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If a performance query is not currently started, an INVALID_OPERATION > + * error will be generated." > + * > + * The specification doesn't state that an invalid handle would be an > + * INVALID_VALUE error. Regardless, query for such a handle will not be > + * started, so we generate an INVALID_OPERATION in that case. > + * > + * No queries are supported, so all handles are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "glEndPerfQueryINTEL(query not started)"); > +} > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryDataINTEL(GLuint queryHandle, GLuint flags, > + GLsizei dataSize, void *data, GLuint > *bytesWritten) > +{ > + GET_CURRENT_CONTEXT(ctx); > + > + /* "If bytesWritten or data pointers are NULL then an INVALID_VALUE error > + * is generated." > + */ > + if (!bytesWritten || !data) { > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetPerfQueryDataINTEL(bytesWritten or data is NULL)"); > + return; > + } > + > + /* The specification doesn't state that an invalid handle generates an > + * error. We could interpret that to mean the case should be handled as > + * "measurement not ready for this query", but what should be done if > + * `flags' equals PERFQUERY_WAIT_INTEL? > + * > + * To resolve this, we just generate an INVALID_VALUE from an invalid > query > + * handle. > + * > + * No queries are supported, so all handles are invalid. > + */ > + > + _mesa_error(ctx, GL_INVALID_VALUE, > + "glGetPerfQueryDataINTEL(invalid queryHandle)"); > +} > diff --git a/src/mesa/main/performance_monitor.h > b/src/mesa/main/performance_monitor.h > index 76234e5..7b311e4 100644 > --- a/src/mesa/main/performance_monitor.h > +++ b/src/mesa/main/performance_monitor.h > @@ -23,7 +23,8 @@ > > /** > * \file performance_monitor.h > - * Core Mesa support for the AMD_performance_monitor extension. > + * Core Mesa support for the AMD_performance_monitor extension and the > + * INTEL_performance_query extension. > */ > > #pragma once > @@ -85,4 +86,44 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum > pname, > unsigned > _mesa_perf_monitor_counter_size(const struct gl_perf_monitor_counter *); > > + > +extern void GLAPIENTRY > +_mesa_GetFirstPerfQueryIdINTEL(GLuint *queryId); > + > +extern void GLAPIENTRY > +_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId); > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId); > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryInfoINTEL(GLuint queryId, > + GLuint queryNameLength, char *queryName, > + GLuint *dataSize, GLuint *noCounters, > + GLuint *noActiveInstances, > + GLuint *capsMask); > + > +extern void GLAPIENTRY > +_mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, > + GLuint counterNameLength, char *counterName, > + GLuint counterDescLength, char *counterDesc, > + GLuint *counterOffset, GLuint > *counterDataSize, GLuint *counterTypeEnum, > + GLuint *counterDataTypeEnum, GLuint64 > *rawCounterMaxValue); > + > +extern void GLAPIENTRY > +_mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle); > + > +extern void GLAPIENTRY > +_mesa_DeletePerfQueryINTEL(GLuint queryHandle); > + > +extern void GLAPIENTRY > +_mesa_BeginPerfQueryINTEL(GLuint queryHandle); > + > +extern void GLAPIENTRY > +_mesa_EndPerfQueryINTEL(GLuint queryHandle); > + > +extern void GLAPIENTRY > +_mesa_GetPerfQueryDataINTEL(GLuint queryHandle, GLuint flags, > + GLsizei dataSize, void *data, GLuint > *bytesWritten); > + > #endif > diff --git a/src/mesa/main/tests/dispatch_sanity.cpp > b/src/mesa/main/tests/dispatch_sanity.cpp > index 8ff975f..672302f 100644 > --- a/src/mesa/main/tests/dispatch_sanity.cpp > +++ b/src/mesa/main/tests/dispatch_sanity.cpp > @@ -912,6 +912,18 @@ const struct function gl_core_functions_possible[] = { > { "glEndPerfMonitorAMD", 11, -1 }, > { "glGetPerfMonitorCounterDataAMD", 11, -1 }, > > + /* GL_INTEL_performance_query */ > + { "glGetFirstPerfQueryIdINTEL", 30, -1 }, > + { "glGetNextPerfQueryIdINTEL", 30, -1 }, > + { "glGetPerfQueryIdByNameINTEL", 30, -1 }, > + { "glGetPerfQueryInfoINTEL", 30, -1 }, > + { "glGetPerfCounterInfoINTEL", 30, -1 }, > + { "glCreatePerfQueryINTEL", 30, -1 }, > + { "glDeletePerfQueryINTEL", 30, -1 }, > + { "glBeginPerfQueryINTEL", 30, -1 }, > + { "glEndPerfQueryINTEL", 30, -1 }, > + { "glGetPerfQueryDataINTEL", 30, -1 }, > + > /* GL_NV_vdpau_interop */ > { "glVDPAUInitNV", 11, -1 }, > { "glVDPAUFiniNV", 11, -1 }, > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev