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.
This commit is contained in:
Luca Barbieri 2010-09-05 08:27:12 +02:00
parent 14d5805235
commit 49b493ddd0
4 changed files with 36 additions and 10 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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