#define NV34TCL_COLOR_MATERIAL_BACK_B 0x000017b8
#define NV34TCL_COLOR_MATERIAL_BACK_A 0x000017c0
#define NV34TCL_QUERY_RESET 0x000017c8
-#define NV34TCL_QUERY_UNK17CC 0x000017cc
+#define NV34TCL_QUERY_ENABLE 0x000017cc
#define NV34TCL_QUERY_GET 0x00001800
#define NV34TCL_QUERY_GET_UNK24_SHIFT 24
#define NV34TCL_QUERY_GET_UNK24_MASK 0xff000000
struct nvfx_query *q = nvfx_query(pq);
struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *eng3d = screen->eng3d;
uint64_t tmp;
+ assert(!nvfx->query);
+
/* Happens when end_query() is called, then another begin_query()
* without querying the result in-between. For now we'll wait for
* the existing query to notify completion, but it could be better.
nouveau_notifier_reset(nvfx->screen->query, q->object->start);
- BEGIN_RING(chan, eng3d, NV34TCL_QUERY_RESET, 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, eng3d, NV34TCL_QUERY_UNK17CC, 1);
- OUT_RING (chan, 1);
+ WAIT_RING(chan, 4);
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_RESET, 1));
+ OUT_RING(chan, 1);
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_ENABLE, 1));
+ OUT_RING(chan, 1);
q->ready = FALSE;
+
+ nvfx->query = pq;
}
static void
nvfx_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
- struct nvfx_screen *screen = nvfx->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *eng3d = screen->eng3d;
+ struct nouveau_channel *chan = nvfx->screen->base.channel;
struct nvfx_query *q = nvfx_query(pq);
- BEGIN_RING(chan, eng3d, NV34TCL_QUERY_GET, 1);
+ assert(nvfx->query == pq);
+
+ WAIT_RING(chan, 4);
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_GET, 1));
OUT_RING (chan, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_ENABLE, 1));
+ OUT_RING(chan, 0);
FIRE_RING(chan);
+
+ nvfx->query = 0;
}
static boolean
assert(nvfx->blitters_in_use < Elements(nvfx->blitter));
+ if(nvfx->query && !nvfx->blitters_in_use)
+ {
+ struct nouveau_channel* chan = nvfx->screen->base.channel;
+ WAIT_RING(chan, 2);
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_ENABLE, 1));
+ OUT_RING(chan, 0);
+ }
+
struct blitter_context** pblitter = &nvfx->blitter[nvfx->blitters_in_use++];
if(!*pblitter)
*pblitter = util_blitter_create(pipe);
struct nvfx_context* nvfx = nvfx_context(pipe);
--nvfx->blitters_in_use;
assert(nvfx->blitters_in_use >= 0);
+
+ if(nvfx->query && !nvfx->blitters_in_use)
+ {
+ struct nouveau_channel* chan = nvfx->screen->base.channel;
+ WAIT_RING(chan, 2);
+ OUT_RING(chan, RING_3D(NV34TCL_QUERY_ENABLE, 1));
+ OUT_RING(chan, 1);
+ }
}
static unsigned