Maarten Maathuis
2009-Dec-05 20:55 UTC
[Nouveau] [PATCH] nouveau: avoid running out of relocs (attempt 4)
- Added flush notify functions for NV30 and NV40. - NV30 and NV40 need testing. --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 42 ++++++++++++++++++------ src/gallium/drivers/nv04/nv04_surface_2d.c | 9 +++-- src/gallium/drivers/nv30/nv30_context.c | 3 ++ src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state_emit.c | 10 +++++- src/gallium/drivers/nv40/nv40_context.c | 3 ++ src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state_emit.c | 10 +++++- src/gallium/drivers/nv50/nv50_query.c | 2 +- src/gallium/drivers/nv50/nv50_surface.c | 2 + src/gallium/drivers/nv50/nv50_transfer.c | 4 +- 11 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index b595405..67b6c94 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -111,19 +111,28 @@ so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) { struct nouveau_pushbuf *pb = chan->pushbuf; unsigned nr, i; + int ret = 0; nr = so->cur - so->push; - if (pb->remaining < nr) - nouveau_pushbuf_flush(chan, nr); + /* This will flush if we need space. + * We don't actually need the marker. + */ + if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) { + debug_printf("so_emit failed marker emit with error %d\n", ret); + return; + } pb->remaining -= nr; memcpy(pb->cur, so->push, nr * 4); for (i = 0; i < so->cur_reloc; i++) { struct nouveau_stateobj_reloc *r = &so->reloc[i]; - nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset, + if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset, r->bo, r->data, 0, r->flags, - r->vor, r->tor); + r->vor, r->tor))) { + debug_printf("so_emit failed reloc with error %d\n", ret); + return; + } } pb->cur += nr; } @@ -133,26 +142,39 @@ so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) { struct nouveau_pushbuf *pb = chan->pushbuf; unsigned i; + int ret = 0; if (!so) return; i = so->cur_reloc << 1; - if (pb->remaining < i) - nouveau_pushbuf_flush(chan, i); + /* This will flush if we need space. + * We don't actually need the marker. + */ + if ((ret = nouveau_pushbuf_marker_emit(chan, i, i))) { + debug_printf("so_emit_reloc_markers failed marker emit with \ + error %d\n", ret); + return; + } pb->remaining -= i; for (i = 0; i < so->cur_reloc; i++) { struct nouveau_stateobj_reloc *r = &so->reloc[i]; - nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0, + if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0, (r->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RDWR)) | - NOUVEAU_BO_DUMMY, 0, 0); - nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0, + NOUVEAU_BO_DUMMY, 0, 0))) { + debug_printf("so_emit_reloc_markers failed reloc \ + with error %d\n", ret); + } + if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0, r->flags | NOUVEAU_BO_DUMMY, - r->vor, r->tor); + r->vor, r->tor))) { + debug_printf("so_emit_reloc_markers failed reloc \ + with error %d\n", ret); + } } } diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c index 932893e..3020806 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c @@ -133,6 +133,9 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, assert(sub_w == w || util_is_pot(sub_w)); assert(sub_h == h || util_is_pot(sub_h)); + MARK_RING (chan, 8 + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*17, 2 + + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*2); + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -202,7 +205,7 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx, unsigned src_offset = src->offset + sy * src_pitch + sx * pf_get_blocksize(src->texture->format); - WAIT_RING (chan, 3 + ((h / 2047) + 1) * 9); + MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2); BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); OUT_RELOCo(chan, src_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); @@ -250,7 +253,7 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst, if (format < 0) return 1; - WAIT_RING (chan, 12); + MARK_RING (chan, 12, 4); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -315,7 +318,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst, gdirect_format = nv04_rect_format(dst->format); assert(gdirect_format >= 0); - WAIT_RING (chan, 16); + MARK_RING (chan, 16, 4); BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index d8300fd..46a821a 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -58,6 +58,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30->pipe.is_texture_referenced = nouveau_is_texture_referenced; nv30->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; + screen->base.channel->user_private = nv30; + screen->base.channel->flush_notify = nv30_state_flush_notify; + nv30_init_query_functions(nv30); nv30_init_surface_functions(nv30); nv30_init_state_functions(nv30); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 8d49366..6f44b1c 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -184,6 +184,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); /* nv30_state.c and friends */ extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_state_emit(struct nv30_context *nv30); +extern void nv30_state_flush_notify(struct nouveau_channel *chan); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_stipple; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 621b884..d2e5312 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -41,7 +41,7 @@ nv30_state_emit(struct nv30_context *nv30) struct nouveau_channel *chan = nv30->screen->base.channel; struct nv30_state *state = &nv30->state; struct nv30_screen *screen = nv30->screen; - unsigned i, samplers; + unsigned i; uint64_t states; if (nv30->pctx_id != screen->cur_pctx) { @@ -63,6 +63,14 @@ nv30_state_emit(struct nv30_context *nv30) } state->dirty = 0; +} + +void +nv30_state_flush_notify(struct nouveau_channel *chan) +{ + struct nv30_context *nv30 = chan->user_private; + struct nv30_state *state = &nv30->state; + unsigned i, samplers; so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 7f00827..eb9cce4 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -58,6 +58,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.is_texture_referenced = nouveau_is_texture_referenced; nv40->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; + screen->base.channel->user_private = nv40; + screen->base.channel->flush_notify = nv40_state_flush_notify; + nv40_init_query_functions(nv40); nv40_init_surface_functions(nv40); nv40_init_state_functions(nv40); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index a3d5941..cf33b64 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -204,6 +204,7 @@ extern void nv40_fragtex_bind(struct nv40_context *); extern boolean nv40_state_validate(struct nv40_context *nv40); extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); extern void nv40_state_emit(struct nv40_context *nv40); +extern void nv40_state_flush_notify(struct nouveau_channel *chan); extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 1986929..ba0fbcb 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -57,7 +57,7 @@ nv40_state_emit(struct nv40_context *nv40) struct nouveau_channel *chan = nv40->screen->base.channel; struct nv40_state *state = &nv40->state; struct nv40_screen *screen = nv40->screen; - unsigned i, samplers; + unsigned i; uint64_t states; if (nv40->pctx_id != screen->cur_pctx) { @@ -87,6 +87,14 @@ nv40_state_emit(struct nv40_context *nv40) } state->dirty = 0; +} + +void +nv40_state_flush_notify(struct nouveau_channel *chan) +{ + struct nv40_context *nv40 = chan->user_private; + struct nv40_state *state = &nv40->state; + unsigned i, samplers; so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 5305c93..268c982 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -93,7 +93,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_query *q = nv50_query(pq); - WAIT_RING (chan, 5); + MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */ BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 6bf6f77..79655fc 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -62,6 +62,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) return 1; if (!bo->tile_flags) { + MARK_RING (chan, 9, 2); /* flush on lack of space or relocs */ BEGIN_RING(chan, eng2d, mthd, 2); OUT_RING (chan, format); OUT_RING (chan, 1); @@ -72,6 +73,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) OUT_RELOCh(chan, bo, ps->offset, flags); OUT_RELOCl(chan, bo, ps->offset, flags); } else { + MARK_RING (chan, 11, 2); /* flush on lack of space or relocs */ BEGIN_RING(chan, eng2d, mthd, 5); OUT_RING (chan, format); OUT_RING (chan, 0); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 4705f96..1b6c8d6 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -81,7 +81,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, while (height) { int line_count = height > 2047 ? 2047 : height; - WAIT_RING (chan, 15); + MARK_RING (chan, 15, 4); /* flush on lack of space or relocs */ BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2); OUT_RELOCh(chan, src_bo, src_offset, src_reloc); @@ -282,7 +282,7 @@ nv50_upload_sifc(struct nv50_context *nv50, reloc |= NOUVEAU_BO_WR; - WAIT_RING (chan, 32); + MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */ if (bo->tile_flags) { BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5); -- 1.6.5.3
Maarten Maathuis
2009-Dec-13 00:33 UTC
[Nouveau] [PATCH] nouveau: avoid running out of relocs (attempt 4)
On Sat, Dec 5, 2009 at 9:55 PM, Maarten Maathuis <madman2003 at gmail.com> wrote:> - Added flush notify functions for NV30 and NV40. > - NV30 and NV40 need testing. > --- > ?src/gallium/drivers/nouveau/nouveau_stateobj.h | ? 42 ++++++++++++++++++------ > ?src/gallium/drivers/nv04/nv04_surface_2d.c ? ? | ? ?9 +++-- > ?src/gallium/drivers/nv30/nv30_context.c ? ? ? ?| ? ?3 ++ > ?src/gallium/drivers/nv30/nv30_context.h ? ? ? ?| ? ?1 + > ?src/gallium/drivers/nv30/nv30_state_emit.c ? ? | ? 10 +++++- > ?src/gallium/drivers/nv40/nv40_context.c ? ? ? ?| ? ?3 ++ > ?src/gallium/drivers/nv40/nv40_context.h ? ? ? ?| ? ?1 + > ?src/gallium/drivers/nv40/nv40_state_emit.c ? ? | ? 10 +++++- > ?src/gallium/drivers/nv50/nv50_query.c ? ? ? ? ?| ? ?2 +- > ?src/gallium/drivers/nv50/nv50_surface.c ? ? ? ?| ? ?2 + > ?src/gallium/drivers/nv50/nv50_transfer.c ? ? ? | ? ?4 +- > ?11 files changed, 69 insertions(+), 18 deletions(-) > > diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h > index b595405..67b6c94 100644 > --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h > +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h > @@ -111,19 +111,28 @@ so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) > ?{ > ? ? ? ?struct nouveau_pushbuf *pb = chan->pushbuf; > ? ? ? ?unsigned nr, i; > + ? ? ? int ret = 0; > > ? ? ? ?nr = so->cur - so->push; > - ? ? ? if (pb->remaining < nr) > - ? ? ? ? ? ? ? nouveau_pushbuf_flush(chan, nr); > + ? ? ? /* This will flush if we need space. > + ? ? ? ?* We don't actually need the marker. > + ? ? ? ?*/ > + ? ? ? if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) { > + ? ? ? ? ? ? ? debug_printf("so_emit failed marker emit with error %d\n", ret); > + ? ? ? ? ? ? ? return; > + ? ? ? } > ? ? ? ?pb->remaining -= nr; > > ? ? ? ?memcpy(pb->cur, so->push, nr * 4); > ? ? ? ?for (i = 0; i < so->cur_reloc; i++) { > ? ? ? ? ? ? ? ?struct nouveau_stateobj_reloc *r = &so->reloc[i]; > > - ? ? ? ? ? ? ? nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset, > + ? ? ? ? ? ? ? if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r->bo, r->data, 0, r->flags, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?r->vor, r->tor); > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?r->vor, r->tor))) { > + ? ? ? ? ? ? ? ? ? ? ? debug_printf("so_emit failed reloc with error %d\n", ret); > + ? ? ? ? ? ? ? ? ? ? ? return; > + ? ? ? ? ? ? ? } > ? ? ? ?} > ? ? ? ?pb->cur += nr; > ?} > @@ -133,26 +142,39 @@ so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) > ?{ > ? ? ? ?struct nouveau_pushbuf *pb = chan->pushbuf; > ? ? ? ?unsigned i; > + ? ? ? int ret = 0; > > ? ? ? ?if (!so) > ? ? ? ? ? ? ? ?return; > > ? ? ? ?i = so->cur_reloc << 1; > - ? ? ? if (pb->remaining < i) > - ? ? ? ? ? ? ? nouveau_pushbuf_flush(chan, i); > + ? ? ? /* This will flush if we need space. > + ? ? ? ?* We don't actually need the marker. > + ? ? ? ?*/ > + ? ? ? if ((ret = nouveau_pushbuf_marker_emit(chan, i, i))) { > + ? ? ? ? ? ? ? debug_printf("so_emit_reloc_markers failed marker emit with \ > + ? ? ? ? ? ? ? ? ? ? ? error %d\n", ret); > + ? ? ? ? ? ? ? return; > + ? ? ? } > ? ? ? ?pb->remaining -= i; > > ? ? ? ?for (i = 0; i < so->cur_reloc; i++) { > ? ? ? ? ? ? ? ?struct nouveau_stateobj_reloc *r = &so->reloc[i]; > > - ? ? ? ? ? ? ? nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0, > + ? ? ? ? ? ? ? if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (r->flags & (NOUVEAU_BO_VRAM | > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NOUVEAU_BO_GART | > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NOUVEAU_BO_RDWR)) | > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NOUVEAU_BO_DUMMY, 0, 0); > - ? ? ? ? ? ? ? nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NOUVEAU_BO_DUMMY, 0, 0))) { > + ? ? ? ? ? ? ? ? ? ? ? debug_printf("so_emit_reloc_markers failed reloc \ > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with error %d\n", ret); > + ? ? ? ? ? ? ? } > + ? ? ? ? ? ? ? if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r->flags | NOUVEAU_BO_DUMMY, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?r->vor, r->tor); > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?r->vor, r->tor))) { > + ? ? ? ? ? ? ? ? ? ? ? debug_printf("so_emit_reloc_markers failed reloc \ > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with error %d\n", ret); > + ? ? ? ? ? ? ? } > ? ? ? ?} > ?} > > diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c > index 932893e..3020806 100644 > --- a/src/gallium/drivers/nv04/nv04_surface_2d.c > +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c > @@ -133,6 +133,9 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, > ? ? ? ?assert(sub_w == w || util_is_pot(sub_w)); > ? ? ? ?assert(sub_h == h || util_is_pot(sub_h)); > > + ? ? ? MARK_RING (chan, 8 + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*17, 2 + > + ? ? ? ? ? ? ? ? ? ? ? ?((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*2); > + > ? ? ? ?BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); > ? ? ? ?OUT_RELOCo(chan, dst_bo, > ? ? ? ? ? ? ? ? ? ? ? ? NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > @@ -202,7 +205,7 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx, > ? ? ? ?unsigned src_offset = src->offset + sy * src_pitch + > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sx * pf_get_blocksize(src->texture->format); > > - ? ? ? WAIT_RING (chan, 3 + ((h / 2047) + 1) * 9); > + ? ? ? MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2); > ? ? ? ?BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); > ? ? ? ?OUT_RELOCo(chan, src_bo, > ? ? ? ? ? ? ? ? ? NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); > @@ -250,7 +253,7 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst, > ? ? ? ?if (format < 0) > ? ? ? ? ? ? ? ?return 1; > > - ? ? ? WAIT_RING (chan, 12); > + ? ? ? MARK_RING (chan, 12, 4); > ? ? ? ?BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); > ? ? ? ?OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); > ? ? ? ?OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > @@ -315,7 +318,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst, > ? ? ? ?gdirect_format = nv04_rect_format(dst->format); > ? ? ? ?assert(gdirect_format >= 0); > > - ? ? ? WAIT_RING (chan, 16); > + ? ? ? MARK_RING (chan, 16, 4); > ? ? ? ?BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); > ? ? ? ?OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > ? ? ? ?OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c > index d8300fd..46a821a 100644 > --- a/src/gallium/drivers/nv30/nv30_context.c > +++ b/src/gallium/drivers/nv30/nv30_context.c > @@ -58,6 +58,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) > ? ? ? ?nv30->pipe.is_texture_referenced = nouveau_is_texture_referenced; > ? ? ? ?nv30->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; > > + ? ? ? screen->base.channel->user_private = nv30; > + ? ? ? screen->base.channel->flush_notify = nv30_state_flush_notify; > + > ? ? ? ?nv30_init_query_functions(nv30); > ? ? ? ?nv30_init_surface_functions(nv30); > ? ? ? ?nv30_init_state_functions(nv30); > diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h > index 8d49366..6f44b1c 100644 > --- a/src/gallium/drivers/nv30/nv30_context.h > +++ b/src/gallium/drivers/nv30/nv30_context.h > @@ -184,6 +184,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); > ?/* nv30_state.c and friends */ > ?extern boolean nv30_state_validate(struct nv30_context *nv30); > ?extern void nv30_state_emit(struct nv30_context *nv30); > +extern void nv30_state_flush_notify(struct nouveau_channel *chan); > ?extern struct nv30_state_entry nv30_state_rasterizer; > ?extern struct nv30_state_entry nv30_state_scissor; > ?extern struct nv30_state_entry nv30_state_stipple; > diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c > index 621b884..d2e5312 100644 > --- a/src/gallium/drivers/nv30/nv30_state_emit.c > +++ b/src/gallium/drivers/nv30/nv30_state_emit.c > @@ -41,7 +41,7 @@ nv30_state_emit(struct nv30_context *nv30) > ? ? ? ?struct nouveau_channel *chan = nv30->screen->base.channel; > ? ? ? ?struct nv30_state *state = &nv30->state; > ? ? ? ?struct nv30_screen *screen = nv30->screen; > - ? ? ? unsigned i, samplers; > + ? ? ? unsigned i; > ? ? ? ?uint64_t states; > > ? ? ? ?if (nv30->pctx_id != screen->cur_pctx) { > @@ -63,6 +63,14 @@ nv30_state_emit(struct nv30_context *nv30) > ? ? ? ?} > > ? ? ? ?state->dirty = 0; > +} > + > +void > +nv30_state_flush_notify(struct nouveau_channel *chan) > +{ > + ? ? ? struct nv30_context *nv30 = chan->user_private; > + ? ? ? struct nv30_state *state = &nv30->state; > + ? ? ? unsigned i, samplers; > > ? ? ? ?so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]); > ? ? ? ?for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { > diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c > index 7f00827..eb9cce4 100644 > --- a/src/gallium/drivers/nv40/nv40_context.c > +++ b/src/gallium/drivers/nv40/nv40_context.c > @@ -58,6 +58,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) > ? ? ? ?nv40->pipe.is_texture_referenced = nouveau_is_texture_referenced; > ? ? ? ?nv40->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; > > + ? ? ? screen->base.channel->user_private = nv40; > + ? ? ? screen->base.channel->flush_notify = nv40_state_flush_notify; > + > ? ? ? ?nv40_init_query_functions(nv40); > ? ? ? ?nv40_init_surface_functions(nv40); > ? ? ? ?nv40_init_state_functions(nv40); > diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h > index a3d5941..cf33b64 100644 > --- a/src/gallium/drivers/nv40/nv40_context.h > +++ b/src/gallium/drivers/nv40/nv40_context.h > @@ -204,6 +204,7 @@ extern void nv40_fragtex_bind(struct nv40_context *); > ?extern boolean nv40_state_validate(struct nv40_context *nv40); > ?extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); > ?extern void nv40_state_emit(struct nv40_context *nv40); > +extern void nv40_state_flush_notify(struct nouveau_channel *chan); > ?extern struct nv40_state_entry nv40_state_rasterizer; > ?extern struct nv40_state_entry nv40_state_scissor; > ?extern struct nv40_state_entry nv40_state_stipple; > diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c > index 1986929..ba0fbcb 100644 > --- a/src/gallium/drivers/nv40/nv40_state_emit.c > +++ b/src/gallium/drivers/nv40/nv40_state_emit.c > @@ -57,7 +57,7 @@ nv40_state_emit(struct nv40_context *nv40) > ? ? ? ?struct nouveau_channel *chan = nv40->screen->base.channel; > ? ? ? ?struct nv40_state *state = &nv40->state; > ? ? ? ?struct nv40_screen *screen = nv40->screen; > - ? ? ? unsigned i, samplers; > + ? ? ? unsigned i; > ? ? ? ?uint64_t states; > > ? ? ? ?if (nv40->pctx_id != screen->cur_pctx) { > @@ -87,6 +87,14 @@ nv40_state_emit(struct nv40_context *nv40) > ? ? ? ?} > > ? ? ? ?state->dirty = 0; > +} > + > +void > +nv40_state_flush_notify(struct nouveau_channel *chan) > +{ > + ? ? ? struct nv40_context *nv40 = chan->user_private; > + ? ? ? struct nv40_state *state = &nv40->state; > + ? ? ? unsigned i, samplers; > > ? ? ? ?so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]); > ? ? ? ?for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { > diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c > index 5305c93..268c982 100644 > --- a/src/gallium/drivers/nv50/nv50_query.c > +++ b/src/gallium/drivers/nv50/nv50_query.c > @@ -93,7 +93,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) > ? ? ? ?struct nouveau_grobj *tesla = nv50->screen->tesla; > ? ? ? ?struct nv50_query *q = nv50_query(pq); > > - ? ? ? WAIT_RING (chan, 5); > + ? ? ? MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */ > ? ? ? ?BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); > ? ? ? ?OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > ? ? ? ?OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c > index 6bf6f77..79655fc 100644 > --- a/src/gallium/drivers/nv50/nv50_surface.c > +++ b/src/gallium/drivers/nv50/nv50_surface.c > @@ -62,6 +62,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) > ? ? ? ? ? ? ? ?return 1; > > ? ? ? ?if (!bo->tile_flags) { > + ? ? ? ? ? ? ? MARK_RING (chan, 9, 2); /* flush on lack of space or relocs */ > ? ? ? ? ? ? ? ?BEGIN_RING(chan, eng2d, mthd, 2); > ? ? ? ? ? ? ? ?OUT_RING ?(chan, format); > ? ? ? ? ? ? ? ?OUT_RING ?(chan, 1); > @@ -72,6 +73,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) > ? ? ? ? ? ? ? ?OUT_RELOCh(chan, bo, ps->offset, flags); > ? ? ? ? ? ? ? ?OUT_RELOCl(chan, bo, ps->offset, flags); > ? ? ? ?} else { > + ? ? ? ? ? ? ? MARK_RING (chan, 11, 2); /* flush on lack of space or relocs */ > ? ? ? ? ? ? ? ?BEGIN_RING(chan, eng2d, mthd, 5); > ? ? ? ? ? ? ? ?OUT_RING ?(chan, format); > ? ? ? ? ? ? ? ?OUT_RING ?(chan, 0); > diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c > index 4705f96..1b6c8d6 100644 > --- a/src/gallium/drivers/nv50/nv50_transfer.c > +++ b/src/gallium/drivers/nv50/nv50_transfer.c > @@ -81,7 +81,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, > ? ? ? ?while (height) { > ? ? ? ? ? ? ? ?int line_count = height > 2047 ? 2047 : height; > > - ? ? ? ? ? ? ? WAIT_RING (chan, 15); > + ? ? ? ? ? ? ? MARK_RING (chan, 15, 4); /* flush on lack of space or relocs */ > ? ? ? ? ? ? ? ?BEGIN_RING(chan, m2mf, > ? ? ? ? ? ? ? ? ? ? ? ?NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2); > ? ? ? ? ? ? ? ?OUT_RELOCh(chan, src_bo, src_offset, src_reloc); > @@ -282,7 +282,7 @@ nv50_upload_sifc(struct nv50_context *nv50, > > ? ? ? ?reloc |= NOUVEAU_BO_WR; > > - ? ? ? WAIT_RING (chan, 32); > + ? ? ? MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */ > > ? ? ? ?if (bo->tile_flags) { > ? ? ? ? ? ? ? ?BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5); > -- > 1.6.5.3 > >Can someone on NV30 and NV40 test this patch?
Apparently Analagous Threads
- [PATCH] nouveau: avoid running out of relocs (attempt 5)
- [PATCH] nouveau: avoid running out of relocs (attempt 3)
- [PATCH 1/2] nv30-nv40: Rewrite primitive splitting and emission
- [PATCH 1/3] nv50: remove vtxbuf stateobject after a referenced vtxbuf is mapped
- [PATCH 1/2] Unreference state/buffer objects on context/screen destruction