From db6f4165f4af89b8a963c5fd5ece4fc9a94c42d0 Mon Sep 17 00:00:00 2001 From: Niels Ole Salscheider Date: Fri, 9 Aug 2013 11:59:28 +0200 Subject: [PATCH] radeonsi: Implement PIPE_QUERY_TIMESTAMP MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Niels Ole Salscheider Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/r600.h | 1 + .../drivers/radeonsi/r600_hw_context.c | 31 +++++++++++++++++++ src/gallium/drivers/radeonsi/r600_query.c | 14 ++++++++- src/gallium/drivers/radeonsi/radeonsi_pipe.c | 2 +- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeonsi/r600.h b/src/gallium/drivers/radeonsi/r600.h index 8f35cc26764..ce0468d4155 100644 --- a/src/gallium/drivers/radeonsi/r600.h +++ b/src/gallium/drivers/radeonsi/r600.h @@ -102,6 +102,7 @@ void si_context_emit_fence(struct r600_context *ctx, struct si_resource *fence, unsigned offset, unsigned value); void r600_context_draw_opaque_count(struct r600_context *ctx, struct r600_so_target *t); +bool si_query_needs_begin(unsigned type); void si_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count_draw_in); int si_context_init(struct r600_context *ctx); diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c b/src/gallium/drivers/radeonsi/r600_hw_context.c index 55daa82994e..59b2d709127 100644 --- a/src/gallium/drivers/radeonsi/r600_hw_context.c +++ b/src/gallium/drivers/radeonsi/r600_hw_context.c @@ -110,6 +110,11 @@ err: return; } +bool si_query_needs_begin(unsigned type) +{ + return type != PIPE_QUERY_TIMESTAMP; +} + /* initialize */ void si_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count_draw_in) @@ -357,6 +362,12 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu results_base = (results_base + 16) % query->buffer->b.b.width0; } break; + case PIPE_QUERY_TIMESTAMP: + { + uint32_t *current_result = (uint32_t*)map; + query->result.u64 = (uint64_t)current_result[0] | (uint64_t)current_result[1] << 32; + break; + } case PIPE_QUERY_TIME_ELAPSED: while (results_base != query->results_end) { query->result.u64 += @@ -502,6 +513,19 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query) { struct radeon_winsys_cs *cs = ctx->cs; uint64_t va; + unsigned new_results_end; + + /* The queries which need begin already called this in begin_query. */ + if (!si_query_needs_begin(query->type)) { + si_need_cs_space(ctx, query->num_cs_dw, TRUE); + + new_results_end = (query->results_end + query->result_size) % query->buffer->b.b.width0; + + /* collect current results if query buffer is full */ + if (new_results_end == query->results_start) { + r600_query_result(ctx, query, TRUE); + } + } va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer); /* emit end query */ @@ -525,6 +549,8 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query) break; case PIPE_QUERY_TIME_ELAPSED: va += query->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; @@ -602,6 +628,10 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query->result_size = 16 * ctx->max_db; query->num_cs_dw = 6; break; + case PIPE_QUERY_TIMESTAMP: + query->result_size = 8; + query->num_cs_dw = 8; + break; case PIPE_QUERY_TIME_ELAPSED: query->result_size = 16; query->num_cs_dw = 8; @@ -665,6 +695,7 @@ boolean r600_context_query_result(struct r600_context *ctx, case PIPE_QUERY_SO_OVERFLOW_PREDICATE: *result_b = query->result.b; break; + case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIME_ELAPSED: *result_u64 = (1000000 * query->result.u64) / ctx->screen->info.r600_clock_crystal_freq; break; diff --git a/src/gallium/drivers/radeonsi/r600_query.c b/src/gallium/drivers/radeonsi/r600_query.c index 0162cce894a..927577c220c 100644 --- a/src/gallium/drivers/radeonsi/r600_query.c +++ b/src/gallium/drivers/radeonsi/r600_query.c @@ -42,6 +42,11 @@ static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query) struct r600_context *rctx = (struct r600_context *)ctx; struct r600_query *rquery = (struct r600_query *)query; + if (!si_query_needs_begin(rquery->type)) { + assert(0); + return; + } + memset(&rquery->result, 0, sizeof(rquery->result)); rquery->results_start = rquery->results_end; r600_query_begin(rctx, (struct r600_query *)query); @@ -53,8 +58,15 @@ static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query) struct r600_context *rctx = (struct r600_context *)ctx; struct r600_query *rquery = (struct r600_query *)query; + if (!si_query_needs_begin(rquery->type)) { + memset(&rquery->result, 0, sizeof(rquery->result)); + } + r600_query_end(rctx, rquery); - LIST_DELINIT(&rquery->list); + + if (si_query_needs_begin(rquery->type)) { + LIST_DELINIT(&rquery->list); + } } static boolean r600_get_query_result(struct pipe_context *ctx, diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c index 4d243483952..335176802a8 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c @@ -397,7 +397,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_VERTEX_COLOR_CLAMPED: case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: case PIPE_CAP_USER_VERTEX_BUFFERS: - case PIPE_CAP_QUERY_TIMESTAMP: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: case PIPE_CAP_CUBE_MAP_ARRAY: case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: @@ -438,6 +437,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return 8; /* Timer queries, present when the clock frequency is non zero. */ + case PIPE_CAP_QUERY_TIMESTAMP: case PIPE_CAP_QUERY_TIME_ELAPSED: return rscreen->info.r600_clock_crystal_freq != 0; -- 2.30.2