summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2012-04-19 14:44:56 +0200
committerChristoph Bumiller <[email protected]>2012-04-19 14:56:04 +0200
commit939b26639fdc0913c5670b7fa20aab1f41b2b155 (patch)
treed102c8f1a1bcf56b9495073e64d55fedc0b2e79b /src
parent90b5301ceab8fd86fccf76efe7ebb039c0e4a28f (diff)
nv50,nvc0: prevent multiple flushes when user spins on get_query_result
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_query.c43
2 files changed, 31 insertions, 19 deletions
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 220b166f985..5275e74964a 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -42,6 +42,7 @@ struct nv50_query {
uint32_t base;
uint32_t offset; /* base + i * 16 */
boolean ready;
+ boolean flushed;
boolean is64bit;
struct nouveau_mm_allocation *mm;
};
@@ -230,6 +231,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
assert(0);
break;
}
+ q->flushed = FALSE;
}
static INLINE boolean
@@ -253,7 +255,10 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
if (!q->ready) {
if (!wait) {
/* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
- PUSH_KICK(nv50->base.pushbuf);
+ if (!q->flushed) {
+ q->flushed = TRUE;
+ PUSH_KICK(nv50->base.pushbuf);
+ }
return FALSE;
}
if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c
index b0ef83a1df2..8dfda378374 100644
--- a/src/gallium/drivers/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nvc0/nvc0_query.c
@@ -27,6 +27,11 @@
#include "nvc0_context.h"
#include "nouveau/nv_object.xml.h"
+#define NVC0_QUERY_STATE_READY 0
+#define NVC0_QUERY_STATE_ACTIVE 1
+#define NVC0_QUERY_STATE_ENDED 2
+#define NVC0_QUERY_STATE_FLUSHED 3
+
struct nvc0_query {
uint32_t *data;
uint16_t type;
@@ -35,8 +40,7 @@ struct nvc0_query {
struct nouveau_bo *bo;
uint32_t base;
uint32_t offset; /* base + i * rotate */
- boolean ready;
- boolean active;
+ uint8_t state;
boolean is64bit;
uint8_t rotate;
int nesting; /* only used for occlusion queries */
@@ -60,7 +64,7 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size)
if (q->bo) {
nouveau_bo_ref(NULL, &q->bo);
if (q->mm) {
- if (q->ready)
+ if (q->state == NVC0_QUERY_STATE_READY)
nouveau_mm_free(q->mm);
else
nouveau_fence_work(screen->base.fence.current,
@@ -242,8 +246,7 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
default:
break;
}
- q->ready = FALSE;
- q->active = TRUE;
+ q->state = NVC0_QUERY_STATE_ACTIVE;
}
static void
@@ -253,14 +256,13 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_query *q = nvc0_query(pq);
- if (!q->active) {
+ if (q->state != NVC0_QUERY_STATE_ACTIVE) {
/* some queries don't require 'begin' to be called (e.g. GPU_FINISHED) */
if (q->rotate)
nvc0_query_rotate(nvc0, q);
q->sequence++;
}
- q->ready = FALSE;
- q->active = FALSE;
+ q->state = NVC0_QUERY_STATE_ENDED;
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
@@ -317,13 +319,15 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
}
}
-static INLINE boolean
-nvc0_query_ready(struct nouveau_client *cli, struct nvc0_query *q)
+static INLINE void
+nvc0_query_update(struct nouveau_client *cli, struct nvc0_query *q)
{
if (q->is64bit) {
- return !nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli);
+ if (!nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli))
+ q->state = NVC0_QUERY_STATE_READY;
} else {
- return q->data[0] == q->sequence;
+ if (q->data[0] == q->sequence)
+ q->state = NVC0_QUERY_STATE_READY;
}
}
@@ -339,19 +343,22 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
uint64_t *data64 = (uint64_t *)q->data;
unsigned i;
- if (!q->ready) /* update ? */
- q->ready = nvc0_query_ready(nvc0->screen->base.client, q);
- if (!q->ready) {
+ if (q->state != NVC0_QUERY_STATE_READY)
+ nvc0_query_update(nvc0->screen->base.client, q);
+
+ if (q->state != NVC0_QUERY_STATE_READY) {
if (!wait) {
- /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
- if (nouveau_pushbuf_refd(nvc0->base.pushbuf, q->bo) & NOUVEAU_BO_WR)
+ if (q->state != NVC0_QUERY_STATE_FLUSHED) {
+ q->state = NVC0_QUERY_STATE_FLUSHED;
+ /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
PUSH_KICK(nvc0->base.pushbuf);
+ }
return FALSE;
}
if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
return FALSE;
}
- q->ready = TRUE;
+ q->state = NVC0_QUERY_STATE_READY;
switch (q->type) {
case PIPE_QUERY_GPU_FINISHED: