summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Barbieri <luca@luca-barbieri.com>2010-09-05 08:27:12 +0200
committerLuca Barbieri <luca@luca-barbieri.com>2010-09-05 17:52:26 +0200
commit49b493ddd0bd6718fe02258a070121f5f4aa10d8 (patch)
tree780bd80fa2edad5d803d6a2ac7f543fc1bb579d8
parent14d58052354cdd72fadabaeb1ae1be2d45d2a5ca (diff)
nvfx: pause occlusion queries during blitter usage
Thanks for Dave Airlie and Jerome Glisse for their code which made me realize I need this too.
-rw-r--r--src/gallium/drivers/nouveau/nouveau_class.h2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_query.c27
-rw-r--r--src/gallium/drivers/nvfx/nvfx_surface.c16
4 files changed, 36 insertions, 10 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h
index 72ddf9bf76..2c616886a3 100644
--- a/src/gallium/drivers/nouveau/nouveau_class.h
+++ b/src/gallium/drivers/nouveau/nouveau_class.h
@@ -6205,7 +6205,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 369c216388..a164ba6c10 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -177,6 +177,7 @@ struct nvfx_context {
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct nvfx_pipe_fragment_program* dummy_fs;
+ struct pipe_query* query;
unsigned nr_samplers;
unsigned nr_textures;
diff --git a/src/gallium/drivers/nvfx/nvfx_query.c b/src/gallium/drivers/nvfx/nvfx_query.c
index 1dab20c41a..eeeb897661 100644
--- a/src/gallium/drivers/nvfx/nvfx_query.c
+++ b/src/gallium/drivers/nvfx/nvfx_query.c
@@ -49,9 +49,10 @@ nvfx_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
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.
@@ -71,27 +72,35 @@ nvfx_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
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
diff --git a/src/gallium/drivers/nvfx/nvfx_surface.c b/src/gallium/drivers/nvfx/nvfx_surface.c
index aff7ac54b7..e39f7f15a3 100644
--- a/src/gallium/drivers/nvfx/nvfx_surface.c
+++ b/src/gallium/drivers/nvfx/nvfx_surface.c
@@ -163,6 +163,14 @@ nvfx_get_blitter(struct pipe_context* pipe, int copy)
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);
@@ -195,6 +203,14 @@ nvfx_put_blitter(struct pipe_context* pipe, struct blitter_context* blitter)
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