diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-11-23 18:54:11 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-11-23 18:54:19 +1100 |
commit | 558f3abb49475ba0aad585e7fb0c07121aecde6f (patch) | |
tree | 5553c9e561ddf359858a4cddc8228a387746081c /src/mesa/drivers | |
parent | dd1500b8b436dc4a009455489ade7dcf65f03d07 (diff) |
nv40: support for keeping multiple vtxprogs on the hw at the same time.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c index a2e85a0aa7..bdc89b9531 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c @@ -4,6 +4,89 @@ #include "pipe/nouveau/nouveau_winsys.h" static int +nouveau_resource_init(struct nouveau_resource **heap, int size) +{ + struct nouveau_resource *r; + + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = 0; + r->size = size; + *heap = r; + return 0; +} + +static int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = TRUE; + r->priv = priv; + + heap->size -= size; + + r->next = heap->next; + if (heap->next) + heap->next->prev = r; + r->prev = heap; + heap->next = r; + + *res = r; + return 0; + } + + heap = heap->next; + } + + return 1; +} + +static void +nouveau_resource_free(struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!res || !*res) + return; + r = *res; + + if (r->prev && !r->prev->in_use) { + r->prev->next = r->next; + if (r->next) + r->next->prev = r->prev; + r->prev->size += r->size; + free(r); + } else + if (r->next && !r->next->in_use) { + r->next->prev = r->prev; + if (r->prev) + r->prev->next = r->next; + r->next->size += r->size; + r->next->start = r->start; + free(r); + } else { + r->in_use = FALSE; + } + + *res = NULL; +} + +static int nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, struct nouveau_notifier **notify) { @@ -67,6 +150,10 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->nv = nv; nvws->channel = nv->channel; + nvws->res_init = nouveau_resource_init; + nvws->res_alloc = nouveau_resource_alloc; + nvws->res_free = nouveau_resource_free; + nvws->begin_ring = nouveau_pipe_dma_beginp; nvws->out_reloc = nouveau_bo_emit_reloc; nvws->fire_ring = nouveau_pipe_dma_kickoff; |