summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/nv40/nv40_query.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-11-18 17:08:06 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-11-18 17:34:06 +1100
commit2f33b5b56e9221f2613b34cd1a1a9d82d5ed4303 (patch)
tree9bcdd27b60eaf4c3d608b4dd2f582fcee7c39f11 /src/mesa/pipe/nv40/nv40_query.c
parent193c85ec7a1aec44eebc67c6224fb6ecbb4607a5 (diff)
nouveau: Very rough cut at gallium winsys + nv40 pipe driver.
Diffstat (limited to 'src/mesa/pipe/nv40/nv40_query.c')
-rw-r--r--src/mesa/pipe/nv40/nv40_query.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/mesa/pipe/nv40/nv40_query.c b/src/mesa/pipe/nv40/nv40_query.c
new file mode 100644
index 0000000000..efd81e6640
--- /dev/null
+++ b/src/mesa/pipe/nv40/nv40_query.c
@@ -0,0 +1,98 @@
+#include "pipe/p_context.h"
+
+#include "nv40_context.h"
+#include "nv40_dma.h"
+
+static uint
+nv40_query_object_find(struct nv40_context *nv40, struct pipe_query_object *q)
+{
+ int id;
+
+ for (id = 0; id < nv40->num_query_objects; id++) {
+ if (nv40->query_objects[id] == q)
+ return id;
+ }
+
+ return -1;
+}
+
+void
+nv40_query_begin(struct pipe_context *pipe, struct pipe_query_object *q)
+{
+ struct nv40_context *nv40 = (struct nv40_context *)pipe;
+ int id;
+
+ assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+
+ id = nv40_query_object_find(nv40, NULL);
+ assert(id >= 0);
+ nv40->query_objects[id] = q;
+
+ nv40->nvws->notifier_reset(nv40->query, id);
+ q->ready = 0;
+
+ BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
+ OUT_RING (1);
+ BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1);
+ OUT_RING (1);
+}
+
+static void
+nv40_query_update(struct pipe_context *pipe, struct pipe_query_object *q)
+{
+ struct nv40_context *nv40 = (struct nv40_context *)pipe;
+ int id;
+
+ id = nv40_query_object_find(nv40, q);
+ assert(id >= 0);
+
+ if (nv40->nvws->notifier_status(nv40->query, id) == 0) {
+ q->ready = 1;
+ q->count = nv40->nvws->notifier_retval(nv40->query, id);
+ nv40->query_objects[id] = NULL;
+ }
+}
+
+void
+nv40_query_end(struct pipe_context *pipe, struct pipe_query_object *q)
+{
+ struct nv40_context *nv40 = (struct nv40_context *)pipe;
+ int id;
+
+ id = nv40_query_object_find(nv40, q);
+ assert(id >= 0);
+
+ BEGIN_RING(curie, NV40TCL_QUERY_GET, 1);
+ OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
+ ((id * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
+ FIRE_RING ();
+
+ /*XXX: Some apps spin waiting for GL_QUERY_RESULT_AVAILABLE_ARB.
+ * Core mesa won't ask the driver to update the query object's
+ * status in this case, so the app waits forever.. fix this some
+ * day.
+ */
+#if 0
+ nv40_query_update(pipe, q);
+#else
+ nv40_query_wait(pipe, q);
+#endif
+}
+
+void
+nv40_query_wait(struct pipe_context *pipe, struct pipe_query_object *q)
+{
+ nv40_query_update(pipe, q);
+ if (!q->ready) {
+ struct nv40_context *nv40 = (struct nv40_context *)pipe;
+ int id;
+
+ id = nv40_query_object_find(nv40, q);
+ assert(id >= 0);
+
+ nv40->nvws->notifier_wait(nv40->query, id, 0, 0);
+ nv40_query_update(pipe, q);
+ assert(q->ready);
+ }
+}
+