diff options
| author | Ben Skeggs <skeggsb@gmail.com> | 2008-02-03 12:08:31 +1100 |
|---|---|---|
| committer | Ben Skeggs <skeggsb@gmail.com> | 2008-02-15 13:50:29 +1100 |
| commit | 705022f98c32c44b94411ea13dfe4cbc899f5a77 (patch) | |
| tree | de1031e64b702e63faf0099c03bb520b3c5b00e0 /src/mesa/drivers | |
| parent | 8bbedc3f4b7b281a60286ba573077a6e3e659f63 (diff) | |
nouveau: avoid relocations where possible.
Potential relocations are emitted as NOPs where they're needed. In the
event a buffer moves, the pushbuf code will emit the relevant state
changes into the NOPs.
Just a start, more work is needed to get this looking how I want it to.
Diffstat (limited to 'src/mesa/drivers')
| -rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_local.h | 3 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c | 61 |
2 files changed, 39 insertions, 25 deletions
diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_local.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_local.h index 7a539c81a9..59febca292 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_local.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_local.h @@ -61,9 +61,8 @@ } while(0) #define OUT_RELOC(buf,data,flags,vor,tor) do { \ - nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur, \ + nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ buf, (data), (flags), (vor), (tor)); \ - OUT_RING(0); \ } while(0) /* Raw data + flags depending on FB/TT buffer */ diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c index a34a5c1866..7d5eddb92f 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c @@ -96,6 +96,31 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) return 0; } +static uint32_t +nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, + struct nouveau_pushbuf_reloc *r) +{ + uint32_t push; + + if (r->flags & NOUVEAU_BO_LOW) { + push = bo->offset + r->data; + } else + if (r->flags & NOUVEAU_BO_HIGH) { + push = (bo->offset + r->data) >> 32; + } else { + push = r->data; + } + + if (r->flags & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + push |= r->vor; + else + push |= r->tor; + } + + return push; +} + /* This would be our TTM "superioctl" */ int nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) @@ -133,34 +158,20 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) if (bo->offset == nouveau_bo(bo)->offset && bo->flags == nouveau_bo(bo)->flags) { - /*XXX: could avoid reloc in this case, except with the - * current design we'd confuse the GPU quite a bit - * if we did this. Will fix soon. - */ + while ((r = ptr_to_pbrel(pbbo->relocs))) { + pbbo->relocs = r->next; + free(r); + } + + nvpb->buffers = pbbo->next; + free(pbbo); + continue; } bo->offset = nouveau_bo(bo)->offset; bo->flags = nouveau_bo(bo)->flags; while ((r = ptr_to_pbrel(pbbo->relocs))) { - uint32_t push; - - if (r->flags & NOUVEAU_BO_LOW) { - push = bo->offset + r->data; - } else - if (r->flags & NOUVEAU_BO_HIGH) { - push = (bo->offset + r->data) >> 32; - } else { - push = r->data; - } - - if (r->flags & NOUVEAU_BO_OR) { - if (bo->flags & NOUVEAU_BO_VRAM) - push |= r->vor; - else - push |= r->tor; - } - - *r->ptr = push; + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); pbbo->relocs = r->next; free(r); } @@ -241,6 +252,10 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, r->vor = vor; r->tor = tor; + if (flags & NOUVEAU_BO_DUMMY) + *(uint32_t *)ptr = 0; + else + *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); return 0; } |
