radeon: implement r600_query_hw_get_result via function pointers

We will need the clear_result override for the batch query implementation.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Nicolai Hähnle
2015-11-13 00:27:34 +01:00
parent c207c55fc0
commit 50f0f938e3
2 changed files with 94 additions and 99 deletions

View File

@@ -303,11 +303,18 @@ static void r600_query_hw_do_emit_stop(struct r600_common_context *ctx,
struct r600_query_hw *query, struct r600_query_hw *query,
struct r600_resource *buffer, struct r600_resource *buffer,
uint64_t va); uint64_t va);
static void r600_query_hw_add_result(struct r600_common_context *ctx,
struct r600_query_hw *, void *buffer,
union pipe_query_result *result);
static void r600_query_hw_clear_result(struct r600_query_hw *,
union pipe_query_result *);
static struct r600_query_hw_ops query_hw_default_hw_ops = { static struct r600_query_hw_ops query_hw_default_hw_ops = {
.prepare_buffer = r600_query_hw_prepare_buffer, .prepare_buffer = r600_query_hw_prepare_buffer,
.emit_start = r600_query_hw_do_emit_start, .emit_start = r600_query_hw_do_emit_start,
.emit_stop = r600_query_hw_do_emit_stop, .emit_stop = r600_query_hw_do_emit_stop,
.clear_result = r600_query_hw_clear_result,
.add_result = r600_query_hw_add_result,
}; };
static struct pipe_query *r600_query_hw_create(struct r600_common_context *rctx, static struct pipe_query *r600_query_hw_create(struct r600_common_context *rctx,
@@ -696,7 +703,7 @@ static void r600_query_hw_end(struct r600_common_context *rctx,
LIST_DELINIT(&query->list); LIST_DELINIT(&query->list);
} }
static unsigned r600_query_read_result(char *map, unsigned start_index, unsigned end_index, static unsigned r600_query_read_result(void *map, unsigned start_index, unsigned end_index,
bool test_status_bit) bool test_status_bit)
{ {
uint32_t *current_result = (uint32_t*)map; uint32_t *current_result = (uint32_t*)map;
@@ -714,47 +721,36 @@ static unsigned r600_query_read_result(char *map, unsigned start_index, unsigned
return 0; return 0;
} }
static boolean r600_get_query_buffer_result(struct r600_common_context *ctx, static void r600_query_hw_add_result(struct r600_common_context *ctx,
struct r600_query_hw *query, struct r600_query_hw *query,
struct r600_query_buffer *qbuf, void *buffer,
boolean wait, union pipe_query_result *result)
union pipe_query_result *result)
{ {
unsigned results_base = 0;
char *map;
map = r600_buffer_map_sync_with_rings(ctx, qbuf->buf,
PIPE_TRANSFER_READ |
(wait ? 0 : PIPE_TRANSFER_DONTBLOCK));
if (!map)
return FALSE;
/* count all results across all data blocks */
switch (query->b.type) { switch (query->b.type) {
case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_COUNTER: {
while (results_base != qbuf->results_end) { unsigned results_base = 0;
while (results_base != query->result_size) {
result->u64 += result->u64 +=
r600_query_read_result(map + results_base, 0, 2, true); r600_query_read_result(buffer + results_base, 0, 2, true);
results_base += 16; results_base += 16;
} }
break; break;
case PIPE_QUERY_OCCLUSION_PREDICATE: }
while (results_base != qbuf->results_end) { case PIPE_QUERY_OCCLUSION_PREDICATE: {
unsigned results_base = 0;
while (results_base != query->result_size) {
result->b = result->b || result->b = result->b ||
r600_query_read_result(map + results_base, 0, 2, true) != 0; r600_query_read_result(buffer + results_base, 0, 2, true) != 0;
results_base += 16; results_base += 16;
} }
break; break;
}
case PIPE_QUERY_TIME_ELAPSED: case PIPE_QUERY_TIME_ELAPSED:
while (results_base != qbuf->results_end) { result->u64 += r600_query_read_result(buffer, 0, 2, false);
result->u64 +=
r600_query_read_result(map + results_base, 0, 2, false);
results_base += query->result_size;
}
break; break;
case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIMESTAMP:
{ {
uint32_t *current_result = (uint32_t*)map; uint32_t *current_result = (uint32_t*)buffer;
result->u64 = (uint64_t)current_result[0] | result->u64 = (uint64_t)current_result[0] |
(uint64_t)current_result[1] << 32; (uint64_t)current_result[1] << 32;
break; break;
@@ -766,84 +762,64 @@ static boolean r600_get_query_buffer_result(struct r600_common_context *ctx,
* u64 PrimitiveStorageNeeded; * u64 PrimitiveStorageNeeded;
* } * }
* We only need NumPrimitivesWritten here. */ * We only need NumPrimitivesWritten here. */
while (results_base != qbuf->results_end) { result->u64 += r600_query_read_result(buffer, 2, 6, true);
result->u64 +=
r600_query_read_result(map + results_base, 2, 6, true);
results_base += query->result_size;
}
break; break;
case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_GENERATED:
/* Here we read PrimitiveStorageNeeded. */ /* Here we read PrimitiveStorageNeeded. */
while (results_base != qbuf->results_end) { result->u64 += r600_query_read_result(buffer, 0, 4, true);
result->u64 +=
r600_query_read_result(map + results_base, 0, 4, true);
results_base += query->result_size;
}
break; break;
case PIPE_QUERY_SO_STATISTICS: case PIPE_QUERY_SO_STATISTICS:
while (results_base != qbuf->results_end) { result->so_statistics.num_primitives_written +=
result->so_statistics.num_primitives_written += r600_query_read_result(buffer, 2, 6, true);
r600_query_read_result(map + results_base, 2, 6, true); result->so_statistics.primitives_storage_needed +=
result->so_statistics.primitives_storage_needed += r600_query_read_result(buffer, 0, 4, true);
r600_query_read_result(map + results_base, 0, 4, true);
results_base += query->result_size;
}
break; break;
case PIPE_QUERY_SO_OVERFLOW_PREDICATE: case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
while (results_base != qbuf->results_end) { result->b = result->b ||
result->b = result->b || r600_query_read_result(buffer, 2, 6, true) !=
r600_query_read_result(map + results_base, 2, 6, true) != r600_query_read_result(buffer, 0, 4, true);
r600_query_read_result(map + results_base, 0, 4, true);
results_base += query->result_size;
}
break; break;
case PIPE_QUERY_PIPELINE_STATISTICS: case PIPE_QUERY_PIPELINE_STATISTICS:
if (ctx->chip_class >= EVERGREEN) { if (ctx->chip_class >= EVERGREEN) {
while (results_base != qbuf->results_end) { result->pipeline_statistics.ps_invocations +=
result->pipeline_statistics.ps_invocations += r600_query_read_result(buffer, 0, 22, false);
r600_query_read_result(map + results_base, 0, 22, false); result->pipeline_statistics.c_primitives +=
result->pipeline_statistics.c_primitives += r600_query_read_result(buffer, 2, 24, false);
r600_query_read_result(map + results_base, 2, 24, false); result->pipeline_statistics.c_invocations +=
result->pipeline_statistics.c_invocations += r600_query_read_result(buffer, 4, 26, false);
r600_query_read_result(map + results_base, 4, 26, false); result->pipeline_statistics.vs_invocations +=
result->pipeline_statistics.vs_invocations += r600_query_read_result(buffer, 6, 28, false);
r600_query_read_result(map + results_base, 6, 28, false); result->pipeline_statistics.gs_invocations +=
result->pipeline_statistics.gs_invocations += r600_query_read_result(buffer, 8, 30, false);
r600_query_read_result(map + results_base, 8, 30, false); result->pipeline_statistics.gs_primitives +=
result->pipeline_statistics.gs_primitives += r600_query_read_result(buffer, 10, 32, false);
r600_query_read_result(map + results_base, 10, 32, false); result->pipeline_statistics.ia_primitives +=
result->pipeline_statistics.ia_primitives += r600_query_read_result(buffer, 12, 34, false);
r600_query_read_result(map + results_base, 12, 34, false); result->pipeline_statistics.ia_vertices +=
result->pipeline_statistics.ia_vertices += r600_query_read_result(buffer, 14, 36, false);
r600_query_read_result(map + results_base, 14, 36, false); result->pipeline_statistics.hs_invocations +=
result->pipeline_statistics.hs_invocations += r600_query_read_result(buffer, 16, 38, false);
r600_query_read_result(map + results_base, 16, 38, false); result->pipeline_statistics.ds_invocations +=
result->pipeline_statistics.ds_invocations += r600_query_read_result(buffer, 18, 40, false);
r600_query_read_result(map + results_base, 18, 40, false); result->pipeline_statistics.cs_invocations +=
result->pipeline_statistics.cs_invocations += r600_query_read_result(buffer, 20, 42, false);
r600_query_read_result(map + results_base, 20, 42, false);
results_base += query->result_size;
}
} else { } else {
while (results_base != qbuf->results_end) { result->pipeline_statistics.ps_invocations +=
result->pipeline_statistics.ps_invocations += r600_query_read_result(buffer, 0, 16, false);
r600_query_read_result(map + results_base, 0, 16, false); result->pipeline_statistics.c_primitives +=
result->pipeline_statistics.c_primitives += r600_query_read_result(buffer, 2, 18, false);
r600_query_read_result(map + results_base, 2, 18, false); result->pipeline_statistics.c_invocations +=
result->pipeline_statistics.c_invocations += r600_query_read_result(buffer, 4, 20, false);
r600_query_read_result(map + results_base, 4, 20, false); result->pipeline_statistics.vs_invocations +=
result->pipeline_statistics.vs_invocations += r600_query_read_result(buffer, 6, 22, false);
r600_query_read_result(map + results_base, 6, 22, false); result->pipeline_statistics.gs_invocations +=
result->pipeline_statistics.gs_invocations += r600_query_read_result(buffer, 8, 24, false);
r600_query_read_result(map + results_base, 8, 24, false); result->pipeline_statistics.gs_primitives +=
result->pipeline_statistics.gs_primitives += r600_query_read_result(buffer, 10, 26, false);
r600_query_read_result(map + results_base, 10, 26, false); result->pipeline_statistics.ia_primitives +=
result->pipeline_statistics.ia_primitives += r600_query_read_result(buffer, 12, 28, false);
r600_query_read_result(map + results_base, 12, 28, false); result->pipeline_statistics.ia_vertices +=
result->pipeline_statistics.ia_vertices += r600_query_read_result(buffer, 14, 30, false);
r600_query_read_result(map + results_base, 14, 30, false);
results_base += query->result_size;
}
} }
#if 0 /* for testing */ #if 0 /* for testing */
printf("Pipeline stats: IA verts=%llu, IA prims=%llu, VS=%llu, HS=%llu, " printf("Pipeline stats: IA verts=%llu, IA prims=%llu, VS=%llu, HS=%llu, "
@@ -865,8 +841,6 @@ static boolean r600_get_query_buffer_result(struct r600_common_context *ctx,
default: default:
assert(0); assert(0);
} }
return TRUE;
} }
static boolean r600_get_query_result(struct pipe_context *ctx, static boolean r600_get_query_result(struct pipe_context *ctx,
@@ -879,6 +853,12 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
return rquery->ops->get_result(rctx, rquery, wait, result); return rquery->ops->get_result(rctx, rquery, wait, result);
} }
static void r600_query_hw_clear_result(struct r600_query_hw *query,
union pipe_query_result *result)
{
util_query_clear_result(result, query->b.type);
}
static boolean r600_query_hw_get_result(struct r600_common_context *rctx, static boolean r600_query_hw_get_result(struct r600_common_context *rctx,
struct r600_query *rquery, struct r600_query *rquery,
boolean wait, union pipe_query_result *result) boolean wait, union pipe_query_result *result)
@@ -886,11 +866,22 @@ static boolean r600_query_hw_get_result(struct r600_common_context *rctx,
struct r600_query_hw *query = (struct r600_query_hw *)rquery; struct r600_query_hw *query = (struct r600_query_hw *)rquery;
struct r600_query_buffer *qbuf; struct r600_query_buffer *qbuf;
util_query_clear_result(result, rquery->type); query->ops->clear_result(query, result);
for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) { for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) {
if (!r600_get_query_buffer_result(rctx, query, qbuf, wait, result)) { unsigned results_base = 0;
void *map;
map = r600_buffer_map_sync_with_rings(rctx, qbuf->buf,
PIPE_TRANSFER_READ |
(wait ? 0 : PIPE_TRANSFER_DONTBLOCK));
if (!map)
return FALSE; return FALSE;
while (results_base != qbuf->results_end) {
query->ops->add_result(rctx, query, map + results_base,
result);
results_base += query->result_size;
} }
} }

View File

@@ -83,6 +83,10 @@ struct r600_query_hw_ops {
void (*emit_stop)(struct r600_common_context *, void (*emit_stop)(struct r600_common_context *,
struct r600_query_hw *, struct r600_query_hw *,
struct r600_resource *buffer, uint64_t va); struct r600_resource *buffer, uint64_t va);
void (*clear_result)(struct r600_query_hw *, union pipe_query_result *);
void (*add_result)(struct r600_common_context *ctx,
struct r600_query_hw *, void *buffer,
union pipe_query_result *result);
}; };
struct r600_query_buffer { struct r600_query_buffer {