mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
cogl: Add GPU timestamp querying utilities
Add utilities that allow getting the current GPU timestamp and creating a query which completes upon completion of all operations currently submitted on a framebuffer. Combined, these two allow measuring how long it took the GPU to finish rendering something to a framebuffer. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
This commit is contained in:
parent
cc08af48f6
commit
fbe6740df1
@ -62,6 +62,11 @@ typedef struct
|
|||||||
GLubyte c[4];
|
GLubyte c[4];
|
||||||
} CoglTextureGLVertex;
|
} CoglTextureGLVertex;
|
||||||
|
|
||||||
|
struct _CoglTimestampQuery
|
||||||
|
{
|
||||||
|
unsigned int id;
|
||||||
|
};
|
||||||
|
|
||||||
struct _CoglContext
|
struct _CoglContext
|
||||||
{
|
{
|
||||||
CoglObject _parent;
|
CoglObject _parent;
|
||||||
|
@ -491,3 +491,27 @@ cogl_context_get_named_pipeline (CoglContext *context,
|
|||||||
{
|
{
|
||||||
return g_hash_table_lookup (context->named_pipelines, key);
|
return g_hash_table_lookup (context->named_pipelines, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_context_free_timestamp_query (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query)
|
||||||
|
{
|
||||||
|
context->driver_vtable->free_timestamp_query (context, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_context_timestamp_query_get_time_ns (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query)
|
||||||
|
{
|
||||||
|
return context->driver_vtable->timestamp_query_get_time_ns (context, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_context_get_gpu_time_ns (CoglContext *context)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (cogl_has_feature (context,
|
||||||
|
COGL_FEATURE_ID_GET_GPU_TIME),
|
||||||
|
0);
|
||||||
|
|
||||||
|
return context->driver_vtable->get_gpu_time_ns (context);
|
||||||
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
* dependency issues with the following headers.
|
* dependency issues with the following headers.
|
||||||
*/
|
*/
|
||||||
typedef struct _CoglContext CoglContext;
|
typedef struct _CoglContext CoglContext;
|
||||||
|
typedef struct _CoglTimestampQuery CoglTimestampQuery;
|
||||||
|
|
||||||
#include <cogl/cogl-defines.h>
|
#include <cogl/cogl-defines.h>
|
||||||
#include <cogl/cogl-display.h>
|
#include <cogl/cogl-display.h>
|
||||||
@ -208,6 +209,8 @@ typedef enum _CoglFeatureID
|
|||||||
COGL_FEATURE_ID_BUFFER_AGE,
|
COGL_FEATURE_ID_BUFFER_AGE,
|
||||||
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
|
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
|
||||||
COGL_FEATURE_ID_BLIT_FRAMEBUFFER,
|
COGL_FEATURE_ID_BLIT_FRAMEBUFFER,
|
||||||
|
COGL_FEATURE_ID_TIMESTAMP_QUERY,
|
||||||
|
COGL_FEATURE_ID_GET_GPU_TIME,
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
_COGL_N_FEATURE_IDS /*< skip >*/
|
_COGL_N_FEATURE_IDS /*< skip >*/
|
||||||
@ -370,6 +373,26 @@ COGL_EXPORT CoglPipeline *
|
|||||||
cogl_context_get_named_pipeline (CoglContext *context,
|
cogl_context_get_named_pipeline (CoglContext *context,
|
||||||
CoglPipelineKey *key);
|
CoglPipelineKey *key);
|
||||||
|
|
||||||
|
COGL_EXPORT void
|
||||||
|
cogl_context_free_timestamp_query (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
COGL_EXPORT int64_t
|
||||||
|
cogl_context_timestamp_query_get_time_ns (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_context_get_gpu_time_ns:
|
||||||
|
* @context: a #CoglContext pointer
|
||||||
|
*
|
||||||
|
* This function should only be called if the COGL_FEATURE_ID_GET_GPU_TIME
|
||||||
|
* feature is advertised.
|
||||||
|
*
|
||||||
|
* Return value: Current GPU time in nanoseconds
|
||||||
|
*/
|
||||||
|
COGL_EXPORT int64_t
|
||||||
|
cogl_context_get_gpu_time_ns (CoglContext *context);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_CONTEXT_H__ */
|
#endif /* __COGL_CONTEXT_H__ */
|
||||||
|
@ -231,6 +231,20 @@ struct _CoglDriverVtable
|
|||||||
(* set_uniform) (CoglContext *ctx,
|
(* set_uniform) (CoglContext *ctx,
|
||||||
GLint location,
|
GLint location,
|
||||||
const CoglBoxedValue *value);
|
const CoglBoxedValue *value);
|
||||||
|
|
||||||
|
CoglTimestampQuery *
|
||||||
|
(* create_timestamp_query) (CoglContext *context);
|
||||||
|
|
||||||
|
void
|
||||||
|
(* free_timestamp_query) (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
(* timestamp_query_get_time_ns) (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
(* get_gpu_time_ns) (CoglContext *context);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
|
#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ())
|
||||||
|
@ -2656,3 +2656,28 @@ cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer)
|
|||||||
|
|
||||||
return priv->driver;
|
return priv->driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoglTimestampQuery *
|
||||||
|
cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer)
|
||||||
|
{
|
||||||
|
CoglFramebufferPrivate *priv =
|
||||||
|
cogl_framebuffer_get_instance_private (framebuffer);
|
||||||
|
const CoglDriverVtable *driver_vtable = priv->context->driver_vtable;
|
||||||
|
|
||||||
|
g_return_val_if_fail (cogl_has_feature (priv->context,
|
||||||
|
COGL_FEATURE_ID_TIMESTAMP_QUERY),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* The timestamp query completes upon completion of all previously submitted
|
||||||
|
* GL commands. So make sure those commands are indeed submitted by flushing
|
||||||
|
* the journal.
|
||||||
|
*/
|
||||||
|
_cogl_framebuffer_flush_journal (framebuffer);
|
||||||
|
|
||||||
|
cogl_context_flush_framebuffer_state (priv->context,
|
||||||
|
framebuffer,
|
||||||
|
framebuffer,
|
||||||
|
COGL_FRAMEBUFFER_STATE_BIND);
|
||||||
|
|
||||||
|
return driver_vtable->create_timestamp_query (priv->context);
|
||||||
|
}
|
||||||
|
@ -1564,6 +1564,19 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
|
|||||||
COGL_EXPORT void
|
COGL_EXPORT void
|
||||||
cogl_framebuffer_flush (CoglFramebuffer *framebuffer);
|
cogl_framebuffer_flush (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_framebuffer_create_timestamp_query: (skip)
|
||||||
|
*
|
||||||
|
* Creates a query for the GPU timestamp that will complete upon completion of
|
||||||
|
* all previously submitted GL commands related to this framebuffer. E.g. when
|
||||||
|
* the rendering is finished on this framebuffer.
|
||||||
|
*
|
||||||
|
* This function should only be called if the COGL_FEATURE_ID_TIMESTAMP_QUERY
|
||||||
|
* feature is advertised.
|
||||||
|
*/
|
||||||
|
COGL_EXPORT CoglTimestampQuery *
|
||||||
|
cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_FRAMEBUFFER_H */
|
#endif /* __COGL_FRAMEBUFFER_H */
|
||||||
|
@ -146,6 +146,20 @@ _cogl_gl_util_parse_gl_version (const char *version_string,
|
|||||||
CoglGraphicsResetStatus
|
CoglGraphicsResetStatus
|
||||||
_cogl_gl_get_graphics_reset_status (CoglContext *context);
|
_cogl_gl_get_graphics_reset_status (CoglContext *context);
|
||||||
|
|
||||||
|
CoglTimestampQuery *
|
||||||
|
cogl_gl_create_timestamp_query (CoglContext *context);
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_gl_free_timestamp_query (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_gl_timestamp_query_get_time_ns (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query);
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_gl_get_gpu_time_ns (CoglContext *context);
|
||||||
|
|
||||||
#ifndef GL_FRAMEBUFFER
|
#ifndef GL_FRAMEBUFFER
|
||||||
#define GL_FRAMEBUFFER 0x8D40
|
#define GL_FRAMEBUFFER 0x8D40
|
||||||
#endif
|
#endif
|
||||||
@ -229,4 +243,11 @@ _cogl_gl_get_graphics_reset_status (CoglContext *context);
|
|||||||
#define GL_STENCIL 0x1802
|
#define GL_STENCIL 0x1802
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL_TIMESTAMP
|
||||||
|
#define GL_TIMESTAMP 0x8E28
|
||||||
|
#endif
|
||||||
|
#ifndef GL_QUERY_RESULT
|
||||||
|
#define GL_QUERY_RESULT 0x8866
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _COGL_UTIL_GL_PRIVATE_H_ */
|
#endif /* _COGL_UTIL_GL_PRIVATE_H_ */
|
||||||
|
@ -493,3 +493,63 @@ _cogl_gl_get_graphics_reset_status (CoglContext *context)
|
|||||||
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoglTimestampQuery *
|
||||||
|
cogl_gl_create_timestamp_query (CoglContext *context)
|
||||||
|
{
|
||||||
|
CoglTimestampQuery *query;
|
||||||
|
|
||||||
|
g_return_val_if_fail (cogl_has_feature (context,
|
||||||
|
COGL_FEATURE_ID_TIMESTAMP_QUERY),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
query = g_new0 (CoglTimestampQuery, 1);
|
||||||
|
|
||||||
|
GE (context, glGenQueries (1, &query->id));
|
||||||
|
GE (context, glQueryCounter (query->id, GL_TIMESTAMP));
|
||||||
|
|
||||||
|
/* Flush right away so GL knows about our timestamp query.
|
||||||
|
*
|
||||||
|
* E.g. the direct scanout path doesn't call SwapBuffers or any other
|
||||||
|
* glFlush-inducing operation, and skipping explicit glFlush here results in
|
||||||
|
* the timestamp query being placed at the point of glGetQueryObject much
|
||||||
|
* later, resulting in a GPU timestamp much later on in time.
|
||||||
|
*/
|
||||||
|
GE (context, glFlush ());
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_gl_free_timestamp_query (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query)
|
||||||
|
{
|
||||||
|
GE (context, glDeleteQueries (1, &query->id));
|
||||||
|
g_free (query);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_gl_timestamp_query_get_time_ns (CoglContext *context,
|
||||||
|
CoglTimestampQuery *query)
|
||||||
|
{
|
||||||
|
int64_t query_time_ns;
|
||||||
|
|
||||||
|
GE (context, glGetQueryObjecti64v (query->id,
|
||||||
|
GL_QUERY_RESULT,
|
||||||
|
&query_time_ns));
|
||||||
|
|
||||||
|
return query_time_ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_gl_get_gpu_time_ns (CoglContext *context)
|
||||||
|
{
|
||||||
|
int64_t gpu_time_ns;
|
||||||
|
|
||||||
|
g_return_val_if_fail (cogl_has_feature (context,
|
||||||
|
COGL_FEATURE_ID_GET_GPU_TIME),
|
||||||
|
0);
|
||||||
|
|
||||||
|
GE (context, glGetInteger64v (GL_TIMESTAMP, &gpu_time_ns));
|
||||||
|
return gpu_time_ns;
|
||||||
|
}
|
||||||
|
@ -539,6 +539,12 @@ _cogl_driver_update_features (CoglContext *ctx,
|
|||||||
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT,
|
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
if (ctx->glGenQueries && ctx->glQueryCounter)
|
||||||
|
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE);
|
||||||
|
|
||||||
|
if (ctx->glGetInteger64v)
|
||||||
|
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GET_GPU_TIME, TRUE);
|
||||||
|
|
||||||
/* Cache features */
|
/* Cache features */
|
||||||
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
|
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
|
||||||
ctx->private_features[i] |= private_features[i];
|
ctx->private_features[i] |= private_features[i];
|
||||||
@ -591,4 +597,8 @@ _cogl_driver_gl =
|
|||||||
_cogl_sampler_gl_init,
|
_cogl_sampler_gl_init,
|
||||||
_cogl_sampler_gl_free,
|
_cogl_sampler_gl_free,
|
||||||
_cogl_gl_set_uniform, /* XXX name is weird... */
|
_cogl_gl_set_uniform, /* XXX name is weird... */
|
||||||
|
cogl_gl_create_timestamp_query,
|
||||||
|
cogl_gl_free_timestamp_query,
|
||||||
|
cogl_gl_timestamp_query_get_time_ns,
|
||||||
|
cogl_gl_get_gpu_time_ns,
|
||||||
};
|
};
|
||||||
|
@ -432,6 +432,12 @@ _cogl_driver_update_features (CoglContext *context,
|
|||||||
COGL_FEATURE_ID_TEXTURE_RG,
|
COGL_FEATURE_ID_TEXTURE_RG,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
if (context->glGenQueries && context->glQueryCounter)
|
||||||
|
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE);
|
||||||
|
|
||||||
|
if (context->glGetInteger64v)
|
||||||
|
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GET_GPU_TIME, TRUE);
|
||||||
|
|
||||||
/* Cache features */
|
/* Cache features */
|
||||||
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
|
for (i = 0; i < G_N_ELEMENTS (private_features); i++)
|
||||||
context->private_features[i] |= private_features[i];
|
context->private_features[i] |= private_features[i];
|
||||||
@ -479,4 +485,8 @@ _cogl_driver_gles =
|
|||||||
_cogl_sampler_gl_init,
|
_cogl_sampler_gl_init,
|
||||||
_cogl_sampler_gl_free,
|
_cogl_sampler_gl_free,
|
||||||
_cogl_gl_set_uniform,
|
_cogl_gl_set_uniform,
|
||||||
|
cogl_gl_create_timestamp_query,
|
||||||
|
cogl_gl_free_timestamp_query,
|
||||||
|
cogl_gl_timestamp_query_get_time_ns,
|
||||||
|
cogl_gl_get_gpu_time_ns,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user