diff options
author | Christoph Bumiller <[email protected]> | 2012-04-06 15:41:55 +0200 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2012-04-14 02:56:33 +1000 |
commit | 6d1cdec3ba151168bfc3aef222fba6265dfb41fb (patch) | |
tree | c8c013eaa14e1b7463b6b3f39221524d901370f6 /src/gallium/drivers/nouveau/nouveau_buffer.c | |
parent | 3c7872f35f4ae439082d413ab31333cf99be7e91 (diff) |
nouveau: switch to libdrm_nouveau-2.0
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c')
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_buffer.c | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index f3cef8c288f..653acaa18fe 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -49,6 +49,9 @@ nouveau_buffer_allocate(struct nouveau_screen *screen, } } buf->domain = domain; + if (buf->bo) + buf->address = buf->bo->offset + buf->offset; + return TRUE; } @@ -112,10 +115,9 @@ nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf, nv->copy_data(nv, bounce, offset, NOUVEAU_BO_GART, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); - if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD)) + if (nouveau_bo_map(bounce, NOUVEAU_BO_RD, nv->screen->client)) return FALSE; - memcpy(buf->data + start, bounce->map, size); - nouveau_bo_unmap(bounce); + memcpy(buf->data + start, (uint8_t *)bounce->map + offset, size); buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; @@ -147,10 +149,8 @@ nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf, if (!bounce) return FALSE; - nouveau_bo_map_range(bounce, offset, size, - NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); - memcpy(bounce->map, buf->data + start, size); - nouveau_bo_unmap(bounce); + nouveau_bo_map(bounce, 0, nv->screen->client); + memcpy((uint8_t *)bounce->map + offset, buf->data + start, size); nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, bounce, offset, NOUVEAU_BO_GART, size); @@ -246,34 +246,27 @@ static void * nouveau_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { + struct nouveau_context *nv = nouveau_context(pipe); struct nouveau_transfer *xfr = nouveau_transfer(transfer); struct nv04_resource *buf = nv04_resource(transfer->resource); struct nouveau_bo *bo = buf->bo; uint8_t *map; int ret; uint32_t offset = xfr->base.box.x; - uint32_t flags; + uint32_t flags = 0; if (buf->domain != NOUVEAU_BO_GART) return buf->data + offset; - if (buf->mm) - flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR; - else + if (!buf->mm) flags = nouveau_screen_transfer_flags(xfr->base.usage); offset += buf->offset; - ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags); + ret = nouveau_bo_map(buf->bo, flags, nv->screen->client); if (ret) return NULL; - map = bo->map; - - /* Unmap right now. Since multiple buffers can share a single nouveau_bo, - * not doing so might make future maps fail or trigger "reloc while mapped" - * errors. For now, mappings to userspace are guaranteed to be persistent. - */ - nouveau_bo_unmap(bo); + map = (uint8_t *)bo->map + offset; if (buf->mm) { if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) { @@ -294,6 +287,7 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, struct pipe_transfer *transfer, const struct pipe_box *box) { +#if 0 struct nv04_resource *res = nv04_resource(transfer->resource); struct nouveau_bo *bo = res->bo; unsigned offset = res->offset + transfer->box.x + box->x; @@ -303,17 +297,43 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, return; /* XXX: maybe need to upload for VRAM buffers here */ - - nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width); +#endif } static void nouveau_buffer_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - /* we've called nouveau_bo_unmap right after map */ } + +void * +nouveau_resource_map_offset(struct nouveau_context *nv, + struct nv04_resource *res, uint32_t offset, + uint32_t flags) +{ + if ((res->domain == NOUVEAU_BO_VRAM) && + (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)) + nouveau_buffer_download(nv, res, 0, res->base.width0); + + if ((res->domain != NOUVEAU_BO_GART) || + (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) + return res->data + offset; + + if (res->mm) { + unsigned rw; + rw = (flags & NOUVEAU_BO_WR) ? PIPE_TRANSFER_WRITE : PIPE_TRANSFER_READ; + nouveau_buffer_sync(res, rw); + if (nouveau_bo_map(res->bo, 0, NULL)) + return NULL; + } else { + if (nouveau_bo_map(res->bo, flags, nv->screen->client)) + return NULL; + } + return (uint8_t *)res->bo->map + res->offset + offset; +} + + const struct u_resource_vtbl nouveau_buffer_vtbl = { u_default_resource_get_handle, /* get_handle */ @@ -387,18 +407,17 @@ nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr, /* Like download, but for GART buffers. Merge ? */ static INLINE boolean -nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo, - unsigned offset, unsigned size) +nouveau_buffer_data_fetch(struct nouveau_context *nv, struct nv04_resource *buf, + struct nouveau_bo *bo, unsigned offset, unsigned size) { if (!buf->data) { buf->data = MALLOC(size); if (!buf->data) return FALSE; } - if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD)) + if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->screen->client)) return FALSE; - memcpy(buf->data, bo->map, size); - nouveau_bo_unmap(bo); + memcpy(buf->data, (uint8_t *)bo->map + offset, size); return TRUE; } @@ -420,12 +439,10 @@ nouveau_buffer_migrate(struct nouveau_context *nv, if (new_domain == NOUVEAU_BO_GART && old_domain == 0) { if (!nouveau_buffer_allocate(screen, buf, new_domain)) return FALSE; - ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR | - NOUVEAU_BO_NOSYNC); + ret = nouveau_bo_map(buf->bo, 0, nv->screen->client); if (ret) return ret; - memcpy(buf->bo->map, buf->data, size); - nouveau_bo_unmap(buf->bo); + memcpy((uint8_t *)buf->bo->map + buf->offset, buf->data, size); FREE(buf->data); } else if (old_domain != 0 && new_domain != 0) { @@ -433,7 +450,7 @@ nouveau_buffer_migrate(struct nouveau_context *nv, if (new_domain == NOUVEAU_BO_VRAM) { /* keep a system memory copy of our data in case we hit a fallback */ - if (!nouveau_buffer_data_fetch(buf, buf->bo, buf->offset, size)) + if (!nouveau_buffer_data_fetch(nv, buf, buf->bo, buf->offset, size)) return FALSE; if (nouveau_mesa_debug) debug_printf("migrating %u KiB to VRAM\n", size / 1024); @@ -469,7 +486,8 @@ nouveau_buffer_migrate(struct nouveau_context *nv, * the vertex indices ... */ boolean -nouveau_user_buffer_upload(struct nv04_resource *buf, +nouveau_user_buffer_upload(struct nouveau_context *nv, + struct nv04_resource *buf, unsigned base, unsigned size) { struct nouveau_screen *screen = nouveau_screen(buf->base.screen); @@ -481,12 +499,10 @@ nouveau_user_buffer_upload(struct nv04_resource *buf, if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) return FALSE; - ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, - NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); + ret = nouveau_bo_map(buf->bo, 0, nv->screen->client); if (ret) return FALSE; - memcpy(buf->bo->map, buf->data + base, size); - nouveau_bo_unmap(buf->bo); + memcpy((uint8_t *)buf->bo->map + buf->offset + base, buf->data + base, size); return TRUE; } |