diff options
Diffstat (limited to 'src/mesa/drivers')
7 files changed, 61 insertions, 71 deletions
diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h index 294b66e5188..f201001bd9b 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h @@ -30,19 +30,6 @@ struct nouveau_context { struct nouveau_screen *nv_screen; struct pipe_surface *frontbuffer; - /* Bufmgr */ - struct { - struct nouveau_channel *channel; - struct nouveau_notifier *notify; - struct nouveau_grobj *m2mf; - uint32_t m2mf_src_ctxdma; - uint32_t m2mf_dst_ctxdma; - uint32_t next_sequence; - } bo; - - /* Relocations */ - struct nouveau_bo *reloc_head; - /* Hardware context */ uint32_t *pushbuf; struct nouveau_channel *channel; diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c index d00fddbff2f..3bb7c49762b 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c @@ -59,12 +59,13 @@ nouveau_dma_channel_init(struct nouveau_channel *chan) int i; nvchan->dma.base = nvchan->drm.put_base; - nvchan->dma.cur = nvchan->dma.put = RING_SKIPS; + nvchan->dma.cur = nvchan->dma.put = 0; nvchan->dma.max = (nvchan->drm.cmdbuf_size >> 2) - 2; nvchan->dma.free = nvchan->dma.max - nvchan->dma.cur; + RING_SPACE_CH(chan, RING_SKIPS); for (i = 0; i < RING_SKIPS; i++) - nvchan->pushbuf[i] = 0x00000000; + OUT_RING_CH(chan, 0); } #define CHECK_TIMEOUT() do { \ diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.h index c4667cc5c02..940a196bfe2 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.h @@ -88,11 +88,26 @@ nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) } static inline void +nouveau_dma_space(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + + if (nvchan->dma.free < size) { + if (nouveau_dma_wait(chan, size) && chan->hang_notify) + chan->hang_notify(chan); + } + nvchan->dma.free -= size; +#ifdef NOUVEAU_DMA_DEBUG + nvchan->dma.push_free = size; +#endif +} + +static inline void nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, int method, int size, const char* file, int line) { struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - int push_size = size + 1; + (void)nvchan; #ifdef NOUVEAU_DMA_TRACE NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, @@ -108,20 +123,11 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, sprintf(faulty,"%s:%d",file,line); #endif - if (nvchan->dma.free < push_size) { - if (nouveau_dma_wait(chan, push_size) && - chan->hang_notify) { - chan->hang_notify(chan); - } - } - nvchan->dma.free -= push_size; -#ifdef NOUVEAU_DMA_DEBUG - nvchan->dma.push_free = push_size; -#endif - + nouveau_dma_space(chan, (size + 1)); nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); } +#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) #define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) #define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) #define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h index 7e52de43235..4dc40b7593d 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h @@ -33,6 +33,7 @@ #include "pipe/nouveau/nouveau_notifier.h" #include "pipe/nouveau/nouveau_bo.h" #include "pipe/nouveau/nouveau_resource.h" +#include "pipe/nouveau/nouveau_pushbuf.h" struct nouveau_device_priv { struct nouveau_device base; @@ -121,12 +122,6 @@ struct nouveau_pushbuf_bo { int nr_relocs; }; -struct nouveau_pushbuf { - struct nouveau_channel *channel; - unsigned remaining; - uint32_t *cur; -}; - struct nouveau_pushbuf_priv { struct nouveau_pushbuf base; struct nouveau_pushbuf *next; @@ -138,6 +133,7 @@ struct nouveau_pushbuf_priv { int nr_buffers; }; #define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + #define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) #define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) #define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c index c9f0903e272..3b35a11bcbf 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c @@ -109,14 +109,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) NOUVEAU_ERR("AII wrap unhandled\n"); /*XXX: assumes subc 0 is populated */ - if (nvchan->dma.free < 2) - WAIT_RING_CH(&nvchan->base, 2); - nvchan->dma.free -= 2; -#ifdef NOUVEAU_DMA_DEBUG - nvchan->dma.push_free += 2; -#endif - OUT_RING_CH(&nvchan->base, 0x00040050); - OUT_RING_CH(&nvchan->base, nvfence->sequence); + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); if (nvchan->fence_tail) { nouveau_fence(nvchan->fence_tail)->next = fence; diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c index 981c4dd7dd7..2179664838e 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c @@ -29,6 +29,30 @@ #define PB_RSVD_DWORDS 2 +static int +nouveau_pushbuf_space(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb; + + nvpb = calloc(1, sizeof(struct nouveau_pushbuf_priv)); + if (!nvpb) + return -ENOMEM; + + while (nouveau_resource_alloc(nvchan->pb_heap, 0x2100, NULL, + &nvpb->res)) { + nouveau_fence_flush(chan); + } + + nvpb->base.channel = chan; + nvpb->base.remaining = (nvpb->res->size / 4) - PB_RSVD_DWORDS; + nvpb->base.cur = &nvchan->pushbuf[nvpb->res->start/4]; + nvchan->pb_tail = &nvpb->base; + nvchan->base.pushbuf = nvchan->pb_tail; + + return 0; +} + int nouveau_pushbuf_init(struct nouveau_channel *chan) { @@ -47,6 +71,8 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) nvchan->dma.max = (4096 / 4) - 2; nvchan->dma.free = nvchan->dma.max - nvchan->dma.cur; + assert(!nouveau_pushbuf_space(chan)); + return 0; } @@ -65,14 +91,11 @@ int nouveau_pushbuf_flush(struct nouveau_channel *chan) { struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(nvchan->pb_tail); + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); struct nouveau_pushbuf_bo *pbbo; struct nouveau_fence *fence = NULL; int ret; - if (!nvpb) - goto out_realloc; - if (nvpb->base.remaining == (nvpb->res->size / 4) - PB_RSVD_DWORDS) return 0; nvchan->pb_tail = NULL; @@ -119,12 +142,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) nvpb->nr_buffers = 0; /* Emit JMP to indirect pushbuf */ - if (nvchan->dma.free < 1) - WAIT_RING_CH(chan, 1); - nvchan->dma.free -= 1; -#ifdef NOUVEAU_DMA_DEBUG - nvchan->dma.push_free = 1; -#endif + RING_SPACE_CH(chan, 1); OUT_RING_CH(chan, 0x20000000 | nvpb->res->start); /* Add JMP back to master pushbuf from indirect pushbuf */ @@ -141,20 +159,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) FIRE_RING_CH(chan); /* Allocate space for next push buffer */ -out_realloc: - nvpb = calloc(1, sizeof(struct nouveau_pushbuf_priv)); - if (!nvpb) - return -ENOMEM; - - while (nouveau_resource_alloc(nvchan->pb_heap, 0x2100, NULL, - &nvpb->res)) { - nouveau_fence_flush(chan); - } - - nvpb->base.channel = chan; - nvpb->base.remaining = (nvpb->res->size / 4) - PB_RSVD_DWORDS; - nvpb->base.cur = &nvchan->pushbuf[nvpb->res->start/4]; - nvchan->pb_tail = &nvpb->base; + assert(!nouveau_pushbuf_space(chan)); return 0; } diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c index f588c956ca9..b31e0dcd1dd 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c @@ -37,15 +37,15 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, uint32_t * nouveau_pipe_dma_beginp(struct nouveau_grobj *grobj, int mthd, int size) { - struct nouveau_channel_priv *nvchan = nouveau_channel(grobj->channel); + struct nouveau_channel *chan = grobj->channel; uint32_t *pushbuf; - if (!nvchan->pb_tail || nvchan->pb_tail->remaining < (size + 1)) - nouveau_pushbuf_flush(grobj->channel); + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan); - pushbuf = nvchan->pb_tail->cur; - nvchan->pb_tail->cur += (size + 1); - nvchan->pb_tail->remaining -= (size + 1); + pushbuf = chan->pushbuf->cur; + chan->pushbuf->cur += (size + 1); + chan->pushbuf->remaining -= (size + 1); (*pushbuf++) = ((grobj->subc << 13) | (size << 18) | mthd); return pushbuf; |