nouveau: implement missing timer query functionality
This commit is contained in:
parent
426a23af14
commit
9ed65301e0
|
@ -8,10 +8,14 @@
|
|||
#include "util/u_format_s3tc.h"
|
||||
#include "util/u_string.h"
|
||||
|
||||
#include "os/os_time.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libdrm/nouveau_drm.h>
|
||||
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_fence.h"
|
||||
|
@ -39,6 +43,16 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen)
|
|||
return "nouveau";
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
nouveau_screen_get_timestamp(struct pipe_screen *pscreen)
|
||||
{
|
||||
int64_t cpu_time = os_time_get() * 1000;
|
||||
|
||||
/* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
|
||||
|
||||
return cpu_time + nouveau_screen(pscreen)->cpu_gpu_time_delta;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_screen_fence_ref(struct pipe_screen *pscreen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
|
@ -108,6 +122,7 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
|
|||
struct pipe_screen *pscreen = &screen->base;
|
||||
struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
|
||||
struct nvc0_fifo nvc0_data = { };
|
||||
uint64_t time;
|
||||
int size, ret;
|
||||
void *data;
|
||||
union nouveau_bo_config mm_config;
|
||||
|
@ -139,9 +154,18 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* getting CPU time first appears to be more accurate */
|
||||
screen->cpu_gpu_time_delta = os_time_get();
|
||||
|
||||
ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
|
||||
if (!ret)
|
||||
screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;
|
||||
|
||||
pscreen->get_name = nouveau_screen_get_name;
|
||||
pscreen->get_vendor = nouveau_screen_get_vendor;
|
||||
|
||||
pscreen->get_timestamp = nouveau_screen_get_timestamp;
|
||||
|
||||
pscreen->fence_reference = nouveau_screen_fence_ref;
|
||||
pscreen->fence_signalled = nouveau_screen_fence_signalled;
|
||||
pscreen->fence_finish = nouveau_screen_fence_finish;
|
||||
|
|
|
@ -39,6 +39,8 @@ struct nouveau_screen {
|
|||
|
||||
struct nouveau_mman *mm_VRAM;
|
||||
struct nouveau_mman *mm_GART;
|
||||
|
||||
int64_t cpu_gpu_time_delta;
|
||||
};
|
||||
|
||||
static INLINE struct nouveau_screen *
|
||||
|
|
|
@ -114,6 +114,7 @@ nv30_query_create(struct pipe_context *pipe, unsigned type)
|
|||
q->type = type;
|
||||
|
||||
switch (q->type) {
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
q->enable = 0x0000;
|
||||
q->report = 1;
|
||||
|
@ -158,6 +159,8 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
PUSH_DATA (push, (q->report << 24) | q->qo[0]->hw->start);
|
||||
}
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
return;
|
||||
default:
|
||||
BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1);
|
||||
PUSH_DATA (push, q->report);
|
||||
|
@ -193,13 +196,13 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
|
||||
static boolean
|
||||
nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
||||
boolean wait, void *result)
|
||||
boolean wait, union pipe_query_result *result)
|
||||
{
|
||||
struct nv30_screen *screen = nv30_screen(pipe->screen);
|
||||
struct nv30_query *q = nv30_query(pq);
|
||||
volatile uint32_t *ntfy0 = nv30_ntfy(screen, q->qo[0]);
|
||||
volatile uint32_t *ntfy1 = nv30_ntfy(screen, q->qo[1]);
|
||||
uint64_t *res64 = result;
|
||||
uint64_t *res64 = &result->u64;
|
||||
|
||||
if (ntfy1) {
|
||||
while (ntfy1[3] & 0xff000000) {
|
||||
|
@ -208,6 +211,9 @@ nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
|||
}
|
||||
|
||||
switch (q->type) {
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
q->result = *(uint64_t *)&ntfy1[0];
|
||||
break;
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
q->result = *(uint64_t *)&ntfy1[0] - *(uint64_t *)&ntfy0[0];
|
||||
break;
|
||||
|
|
|
@ -70,6 +70,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_SCALED_RESOLVE:
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
case PIPE_CAP_TIMER_QUERY:
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
case PIPE_CAP_TEXTURE_SWIZZLE:
|
||||
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
|
||||
|
@ -116,7 +117,6 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
|
||||
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
|
||||
case PIPE_CAP_START_INSTANCE:
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
return 0;
|
||||
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
|
||||
|
|
|
@ -215,11 +215,15 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
nv50_query_get(push, q, 0x00, 0x05805002);
|
||||
nv50_query_get(push, q, 0x10, 0x06805002);
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
q->sequence++;
|
||||
/* fall through */
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
nv50_query_get(push, q, 0, 0x00005002);
|
||||
break;
|
||||
case PIPE_QUERY_GPU_FINISHED:
|
||||
q->sequence++;
|
||||
nv50_query_get(push, q, 0, 0x1000f010);
|
||||
break;
|
||||
case NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
|
||||
|
@ -229,7 +233,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
|||
assert(0);
|
||||
break;
|
||||
}
|
||||
q->flushed = FALSE;
|
||||
q->ready = q->flushed = FALSE;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
|
@ -280,9 +284,12 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
|||
res64[0] = data64[0] - data64[4];
|
||||
res64[1] = data64[2] - data64[6];
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP:
|
||||
res64[0] = data64[1];
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT: /* u32 sequence, u32 0, u64 time */
|
||||
res64[0] = 1000000000;
|
||||
res8[8] = (data64[0] == data64[2]) ? FALSE : TRUE;
|
||||
res8[8] = (data64[1] == data64[3]) ? FALSE : TRUE;
|
||||
break;
|
||||
case PIPE_QUERY_TIME_ELAPSED:
|
||||
res64[0] = data64[1] - data64[3];
|
||||
|
|
|
@ -128,6 +128,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
|
||||
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
|
||||
return 1;
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
case PIPE_CAP_TIMER_QUERY:
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 1;
|
||||
|
@ -172,7 +173,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
return 0;
|
||||
default:
|
||||
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
|
||||
|
|
|
@ -108,6 +108,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
|
||||
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
|
||||
return 1;
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
case PIPE_CAP_TIMER_QUERY:
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
||||
|
@ -150,7 +151,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_QUERY_TIMESTAMP:
|
||||
return 0;
|
||||
default:
|
||||
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
|
||||
|
|
Loading…
Reference in New Issue