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/nv50/nv50_transfer.c | |
parent | 28271fd00dc5dd83f95b5cb890e0ab2c0ff6159d (diff) |
nouveau,nvc0: fix/improve handling of multiple constant buffers
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_transfer.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_transfer.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index c86c417c071..6f860e73348 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -364,3 +364,36 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx, nouveau_bo_unmap(tx->rect[1].bo); } +void +nv50_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); + + while (words) { + unsigned nr; + + MARK_RING(chan, 24, 2); + nr = AVAIL_RING(chan); + nr = MIN2(nr - 7, words); + nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1); + + BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR); + OUT_RING (chan, (NV50_CB_TMP << 16) | (size & 0xffff)); + BEGIN_RING(chan, RING_3D(CB_ADDR), 1); + OUT_RING (chan, (offset << 6) | NV50_CB_TMP); + BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr); + OUT_RINGp (chan, data, nr); + + words -= nr; + data += nr; + offset += nr * 4; + } +} |