mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-15 02:20:29 +01:00
r600g: Implement timer queries.
This commit is contained in:
parent
e7ec532735
commit
90c2fd8640
5 changed files with 78 additions and 14 deletions
|
|
@ -113,6 +113,7 @@ struct r600_tiling_info {
|
|||
enum radeon_family r600_get_family(struct radeon *rw);
|
||||
enum chip_class r600_get_family_class(struct radeon *radeon);
|
||||
struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon);
|
||||
unsigned r600_get_clock_crystal_freq(struct radeon *radeon);
|
||||
|
||||
/* r600_bo.c */
|
||||
struct r600_bo;
|
||||
|
|
|
|||
|
|
@ -283,7 +283,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
|||
return 1;
|
||||
|
||||
/* Unsupported features (boolean caps). */
|
||||
case PIPE_CAP_TIMER_QUERY:
|
||||
case PIPE_CAP_STREAM_OUTPUT:
|
||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||
case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
|
||||
|
|
@ -318,6 +317,10 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||
return 0;
|
||||
|
||||
/* Timer queries, present when the clock frequency is non zero. */
|
||||
case PIPE_CAP_TIMER_QUERY:
|
||||
return r600_get_clock_crystal_freq(rscreen->radeon) != 0;
|
||||
|
||||
default:
|
||||
R600_ERR("r600: unknown param %d\n", param);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
#define RADEON_INFO_TILING_CONFIG 0x6
|
||||
#endif
|
||||
|
||||
#ifndef RADEON_INFO_CLOCK_CRYSTAL_FREQ
|
||||
#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x9
|
||||
#endif
|
||||
|
||||
enum radeon_family r600_get_family(struct radeon *r600)
|
||||
{
|
||||
return r600->family;
|
||||
|
|
@ -56,6 +60,11 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
|
|||
return &radeon->tiling_info;
|
||||
}
|
||||
|
||||
unsigned r600_get_clock_crystal_freq(struct radeon *radeon)
|
||||
{
|
||||
return radeon->clock_crystal_freq;
|
||||
}
|
||||
|
||||
static int radeon_get_device(struct radeon *radeon)
|
||||
{
|
||||
struct drm_radeon_info info;
|
||||
|
|
@ -124,6 +133,24 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_get_clock_crystal_freq(struct radeon *radeon)
|
||||
{
|
||||
struct drm_radeon_info info;
|
||||
uint32_t clock_crystal_freq;
|
||||
int r;
|
||||
|
||||
radeon->device = 0;
|
||||
info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ;
|
||||
info.value = (uintptr_t)&clock_crystal_freq;
|
||||
r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
|
||||
sizeof(struct drm_radeon_info));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
radeon->clock_crystal_freq = clock_crystal_freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_init_fence(struct radeon *radeon)
|
||||
{
|
||||
radeon->fence = 1;
|
||||
|
|
@ -205,6 +232,9 @@ static struct radeon *radeon_new(int fd, unsigned device)
|
|||
if (radeon_drm_get_tiling(radeon))
|
||||
return NULL;
|
||||
}
|
||||
/* get the GPU counter frequency, failure is non fatal */
|
||||
radeon_get_clock_crystal_freq(radeon);
|
||||
|
||||
radeon->bomgr = r600_bomgr_create(radeon, 1000000);
|
||||
if (radeon->bomgr == NULL) {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -1263,7 +1263,8 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
|
|||
for (i = 0; i < query->num_results; i += 4) {
|
||||
start = (u64)results[i] | (u64)results[i + 1] << 32;
|
||||
end = (u64)results[i + 2] | (u64)results[i + 3] << 32;
|
||||
if ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL)) {
|
||||
if (((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))
|
||||
|| query->type == PIPE_QUERY_TIME_ELAPSED) {
|
||||
query->result += end - start;
|
||||
}
|
||||
}
|
||||
|
|
@ -1275,8 +1276,15 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
|
|||
|
||||
void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
|
||||
{
|
||||
/* query request needs 6 dwords for begin + 6 dwords for end */
|
||||
if ((12 + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
|
||||
unsigned required_space;
|
||||
|
||||
/* query request needs 6/8 dwords for begin + 6/8 dwords for end */
|
||||
if (query->type == PIPE_QUERY_TIME_ELAPSED)
|
||||
required_space = 16;
|
||||
else
|
||||
required_space = 12;
|
||||
|
||||
if ((required_space + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
|
||||
/* need to flush */
|
||||
r600_context_flush(ctx);
|
||||
}
|
||||
|
|
@ -1288,10 +1296,19 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
|
|||
}
|
||||
|
||||
/* emit begin query */
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
if (query->type == PIPE_QUERY_TIME_ELAPSED) {
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
} else {
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
}
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
|
||||
|
|
@ -1304,10 +1321,19 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
|
|||
void r600_query_end(struct r600_context *ctx, struct r600_query *query)
|
||||
{
|
||||
/* emit begin query */
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
if (query->type == PIPE_QUERY_TIME_ELAPSED) {
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
} else {
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
}
|
||||
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
|
||||
ctx->pm4[ctx->pm4_cdwords++] = 0;
|
||||
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
|
||||
|
|
@ -1322,7 +1348,7 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned
|
|||
{
|
||||
struct r600_query *query;
|
||||
|
||||
if (query_type != PIPE_QUERY_OCCLUSION_COUNTER)
|
||||
if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && query_type != PIPE_QUERY_TIME_ELAPSED)
|
||||
return NULL;
|
||||
|
||||
query = calloc(1, sizeof(struct r600_query));
|
||||
|
|
@ -1366,7 +1392,10 @@ boolean r600_context_query_result(struct r600_context *ctx,
|
|||
}
|
||||
if (!r600_query_result(ctx, query, wait))
|
||||
return FALSE;
|
||||
*result = query->result;
|
||||
if (query->type == PIPE_QUERY_TIME_ELAPSED)
|
||||
*result = (1000000*query->result)/r600_get_clock_crystal_freq(ctx->radeon);
|
||||
else
|
||||
*result = query->result;
|
||||
query->result = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct radeon {
|
|||
unsigned fence;
|
||||
unsigned *cfence;
|
||||
struct r600_bo *fence_bo;
|
||||
unsigned clock_crystal_freq;
|
||||
};
|
||||
|
||||
struct r600_reg {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue