diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2011-10-20 22:42:59 +0200 |
---|---|---|
committer | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2011-10-21 23:00:40 +0200 |
commit | d988361ead27ce61615669bd428b04d2aac7af4f (patch) | |
tree | cf038c67142bf4352489fd0a80bb89df76c58c97 /src/gallium/drivers/nvc0 | |
parent | 28271fd00dc5dd83f95b5cb890e0ab2c0ff6159d (diff) |
nouveau,nvc0: fix/improve handling of multiple constant buffers
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 42 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_transfer.c | 36 |
4 files changed, 53 insertions, 31 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index d493d4b2a92..2927a0905bd 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -124,6 +124,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) nvc0->base.screen = &screen->base; nvc0->base.copy_data = nvc0_m2mf_copy_linear; nvc0->base.push_data = nvc0_m2mf_push_linear; + nvc0->base.push_cb = nvc0_cb_push; pipe->winsys = pipe_winsys; pipe->screen = pscreen; diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index c46e7430f85..4435c1b4f3c 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -221,6 +221,11 @@ nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); +void +nvc0_cb_push(struct nouveau_context *, + struct nouveau_bo *bo, unsigned domain, + unsigned base, unsigned size, + unsigned offset, unsigned words, const uint32_t *data); /* nvc0_vbo.c */ void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *); diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index e60ed972455..1ec95b7f8b5 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -340,7 +340,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) while (nvc0->constbuf_dirty[s]) { unsigned base = 0; - unsigned offset = 0, words = 0; + unsigned words = 0; boolean rebind = TRUE; i = ffs(nvc0->constbuf_dirty[s]) - 1; @@ -356,7 +356,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) } if (!nouveau_resource_mapped_by_gpu(&res->base)) { - if (i == 0) { + if (i == 0 && (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) { base = s << 16; bo = nvc0->screen->uniforms; @@ -365,19 +365,16 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) else nvc0->state.uniform_buffer_bound[s] = align(res->base.width0, 0x100); + + words = res->base.width0 / 4; } else { + nouveau_buffer_migrate(&nvc0->base, res, NOUVEAU_BO_VRAM); bo = res->bo; + base = res->offset; } -#if 0 - nvc0_m2mf_push_linear(nvc0, bo, NOUVEAU_BO_VRAM, - base, res->base.width0, res->data); - BEGIN_RING(chan, RING_3D_(0x021c), 1); - OUT_RING (chan, 0x1111); -#else - words = res->base.width0 / 4; -#endif } else { bo = res->bo; + base = res->offset; if (i == 0) nvc0->state.uniform_buffer_bound[s] = 0; } @@ -396,27 +393,10 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) OUT_RING (chan, (i << 4) | 1); } - while (words) { - unsigned nr = AVAIL_RING(chan); - - if (nr < 16) { - FIRE_RING(chan); - continue; - } - nr = MIN2(MIN2(nr - 6, words), NV04_PFIFO_MAX_PACKET_LEN - 1); - - MARK_RING (chan, nr + 5, 2); - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, align(res->base.width0, 0x100)); - OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1); - OUT_RING (chan, offset); - OUT_RINGp (chan, &res->data[offset], nr); - - offset += nr * 4; - words -= nr; - } + if (words) + nvc0_cb_push(&nvc0->base, + bo, NOUVEAU_BO_VRAM, base, res->base.width0, + 0, words, (const uint32_t *)res->data); } } } diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index 6404c8cc4ae..f16863733b7 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -365,3 +365,39 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx, nouveau_bo_unmap(tx->rect[1].bo); } +void +nvc0_cb_push(struct nouveau_context *nv, + struct nouveau_bo *bo, unsigned domain, + unsigned base, unsigned size, + unsigned offset, unsigned words, const uint32_t *data) +{ + struct nouveau_channel *chan = nv->screen->channel; + + assert(!(offset & 3)); + size = align(size, 0x100); + + MARK_RING (chan, 16, 2); + BEGIN_RING(chan, RING_3D(CB_SIZE), 3); + OUT_RING (chan, size); + OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR); + + while (words) { + unsigned nr = AVAIL_RING(chan); + nr = MIN2(nr, words); + nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1); + + BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1); + OUT_RING (chan, offset); + OUT_RINGp (chan, data, nr); + + words -= nr; + data += nr; + offset += nr * 4; + + if (words) { + MARK_RING(chan, 6, 1); + nouveau_bo_validate(chan, bo, domain | NOUVEAU_BO_WR); + } + } +} |