On Sun, Aug 12, 2012 at 11:54 AM, Marek Olšák <mar...@gmail.com> wrote: > --- > src/gallium/drivers/r600/r600_pipe.c | 13 ++++++++++++- > src/gallium/drivers/r600/r600_query.c | 17 ++++++++++++++++- > src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 21 > +++++++++++++++++++++ > src/gallium/winsys/radeon/drm/radeon_winsys.h | 7 +++++++ > 4 files changed, 56 insertions(+), 2 deletions(-)
Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> > > diff --git a/src/gallium/drivers/r600/r600_pipe.c > b/src/gallium/drivers/r600/r600_pipe.c > index 76a019d..edeca2a 100644 > --- a/src/gallium/drivers/r600/r600_pipe.c > +++ b/src/gallium/drivers/r600/r600_pipe.c > @@ -416,7 +416,6 @@ static int r600_get_param(struct pipe_screen* pscreen, > enum pipe_cap param) > case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: > case PIPE_CAP_VERTEX_COLOR_CLAMPED: > case PIPE_CAP_USER_VERTEX_BUFFERS: > - case PIPE_CAP_QUERY_TIMESTAMP: > return 0; > > /* Stream output. */ > @@ -450,6 +449,9 @@ static int r600_get_param(struct pipe_screen* pscreen, > enum pipe_cap param) > /* Timer queries, present when the clock frequency is non zero. */ > case PIPE_CAP_TIMER_QUERY: > return rscreen->info.r600_clock_crystal_freq != 0; > + case PIPE_CAP_QUERY_TIMESTAMP: > + return rscreen->info.drm_minor >= 20 && > + rscreen->info.r600_clock_crystal_freq != 0; > > case PIPE_CAP_MIN_TEXEL_OFFSET: > return -8; > @@ -873,6 +875,14 @@ static unsigned radeon_family_from_device(unsigned > device) > } > } > > +static uint64_t r600_get_timestamp(struct pipe_screen *screen) > +{ > + struct r600_screen *rscreen = (struct r600_screen*)screen; > + > + return 1000000 * rscreen->ws->query_timestamp(rscreen->ws) / > + rscreen->info.r600_clock_crystal_freq; > +} > + > struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) > { > struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen); > @@ -929,6 +939,7 @@ struct pipe_screen *r600_screen_create(struct > radeon_winsys *ws) > rscreen->screen.get_paramf = r600_get_paramf; > rscreen->screen.get_video_param = r600_get_video_param; > rscreen->screen.get_compute_param = r600_get_compute_param; > + rscreen->screen.get_timestamp = r600_get_timestamp; > > if (rscreen->chip_class >= EVERGREEN) { > rscreen->screen.is_format_supported = > evergreen_is_format_supported; > diff --git a/src/gallium/drivers/r600/r600_query.c > b/src/gallium/drivers/r600/r600_query.c > index 90b7a66..440b8c9 100644 > --- a/src/gallium/drivers/r600/r600_query.c > +++ b/src/gallium/drivers/r600/r600_query.c > @@ -69,6 +69,7 @@ static struct r600_resource *r600_new_query_buffer(struct > r600_context *ctx, uns > ctx->ws->buffer_unmap(buf->cs_buf); > break; > case PIPE_QUERY_TIME_ELAPSED: > + case PIPE_QUERY_TIMESTAMP: > break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > @@ -174,6 +175,8 @@ static void r600_emit_query_end(struct r600_context *ctx, > struct r600_query *que > break; > case PIPE_QUERY_TIME_ELAPSED: > va += query->buffer.results_end + query->result_size/2; > + /* fall through */ > + case PIPE_QUERY_TIMESTAMP: > cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0); > cs->buf[cs->cdw++] = > EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5); > cs->buf[cs->cdw++] = va; > @@ -267,6 +270,10 @@ static struct pipe_query *r600_create_query(struct > pipe_context *ctx, unsigned q > query->result_size = 16; > query->num_cs_dw = 8; > break; > + case PIPE_QUERY_TIMESTAMP: > + query->result_size = 8; > + query->num_cs_dw = 8; > + break; > case PIPE_QUERY_PRIMITIVES_EMITTED: > case PIPE_QUERY_PRIMITIVES_GENERATED: > case PIPE_QUERY_SO_STATISTICS: > @@ -435,6 +442,13 @@ static boolean r600_get_query_buffer_result(struct > r600_context *ctx, > results_base += query->result_size; > } > break; > + case PIPE_QUERY_TIMESTAMP: > + { > + uint32_t *current_result = (uint32_t*)map; > + result->u64 = (uint64_t)current_result[0] | > + (uint64_t)current_result[1] << 32; > + break; > + } > case PIPE_QUERY_PRIMITIVES_EMITTED: > /* SAMPLE_STREAMOUTSTATS stores this structure: > * { > @@ -498,7 +512,8 @@ static boolean r600_get_query_result(struct pipe_context > *ctx, > } > > /* Convert the time to expected units. */ > - if (rquery->type == PIPE_QUERY_TIME_ELAPSED) { > + if (rquery->type == PIPE_QUERY_TIME_ELAPSED || > + rquery->type == PIPE_QUERY_TIMESTAMP) { > result->u64 = (1000000 * result->u64) / > rctx->screen->info.r600_clock_crystal_freq; > } > return TRUE; > diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c > b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c > index c9c6932..c03dd04 100644 > --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c > +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c > @@ -85,6 +85,10 @@ > #define RADEON_INFO_MAX_PIPES 0x10 > #endif > > +#ifndef RADEON_INFO_TIMESTAMP > +#define RADEON_INFO_TIMESTAMP 0x11 > +#endif > + > > /* Enable/disable feature access for one command stream. > * If enable == TRUE, return TRUE on success. > @@ -375,6 +379,22 @@ static int radeon_drm_winsys_surface_best(struct > radeon_winsys *rws, > return radeon_surface_best(ws->surf_man, surf); > } > > +static uint64_t radeon_query_timestamp(struct radeon_winsys *rws) > +{ > + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; > + uint64_t ts = 0; > + > + if (ws->info.drm_minor < 20 || > + ws->gen < R600) { > + assert(0); > + return 0; > + } > + > + radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp", > + (uint32_t*)&ts); > + return ts; > +} > + > struct radeon_winsys *radeon_drm_winsys_create(int fd) > { > struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); > @@ -407,6 +427,7 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd) > ws->base.cs_request_feature = radeon_cs_request_feature; > ws->base.surface_init = radeon_drm_winsys_surface_init; > ws->base.surface_best = radeon_drm_winsys_surface_best; > + ws->base.query_timestamp = radeon_query_timestamp; > > radeon_bomgr_init_functions(ws); > radeon_drm_cs_init_functions(ws); > diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h > b/src/gallium/winsys/radeon/drm/radeon_winsys.h > index 6039910..4eb57fb 100644 > --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h > +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h > @@ -375,6 +375,13 @@ struct radeon_winsys { > */ > int (*surface_best)(struct radeon_winsys *ws, > struct radeon_surface *surf); > + > + /** > + * Return the current timestamp (gpu clock) on r600 and later GPUs. > + * > + * \param ws The winsys this function is called from. > + */ > + uint64_t (*query_timestamp)(struct radeon_winsys *ws); > }; > > #endif > -- > 1.7.9.5 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev