diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-03-01 12:26:20 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-03-01 14:44:43 +1000 |
commit | 79079141fa7cbf395d1ffc77364ac301d9824211 (patch) | |
tree | f891d7925be9edf943827cf3d702dcdb94378419 /src/gallium/drivers/nv50 | |
parent | 5c1c4f8593073c0bad9bada9234657dda1b25ff0 (diff) |
nv50: move onto common linear buffer manager
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/Makefile | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_buffer.c | 491 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_push.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_resource.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_resource.h | 141 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_shader_state.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tex.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_transfer.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 41 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_winsys.h | 10 |
15 files changed, 72 insertions, 688 deletions
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index dc9ea0eeba..02bcc26cfb 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = nv50 C_SOURCES = \ - nv50_buffer.c \ nv50_context.c \ nv50_draw.c \ nv50_formats.c \ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c deleted file mode 100644 index ae65591e7f..0000000000 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ /dev/null @@ -1,491 +0,0 @@ - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#define NOUVEAU_NVC0 -#include "nouveau/nouveau_screen.h" -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_mm.h" -#undef NOUVEAU_NVC0 - -#include "nv50_context.h" -#include "nv50_resource.h" - -struct nv50_transfer { - struct pipe_transfer base; -}; - -static INLINE struct nv50_transfer * -nv50_transfer(struct pipe_transfer *transfer) -{ - return (struct nv50_transfer *)transfer; -} - -static INLINE boolean -nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, - unsigned domain) -{ - if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nouveau_mm_allocate(screen->base.mm_VRAM, buf->base.width0, - &buf->bo, &buf->offset); - if (!buf->bo) - return nv50_buffer_allocate(screen, buf, NOUVEAU_BO_GART); - } else - if (domain == NOUVEAU_BO_GART) { - buf->mm = nouveau_mm_allocate(screen->base.mm_GART, buf->base.width0, - &buf->bo, &buf->offset); - if (!buf->bo) - return FALSE; - } - if (domain != NOUVEAU_BO_GART) { - if (!buf->data) { - buf->data = MALLOC(buf->base.width0); - if (!buf->data) - return FALSE; - } - } - buf->domain = domain; - return TRUE; -} - -static INLINE void -release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence) -{ - nouveau_fence_work(fence, nouveau_mm_free_work, *mm); - (*mm) = NULL; -} - -INLINE void -nv50_buffer_release_gpu_storage(struct nv50_resource *buf) -{ - nouveau_bo_ref(NULL, &buf->bo); - - if (buf->mm) - release_allocation(&buf->mm, buf->fence); - - buf->domain = 0; -} - -static INLINE boolean -nv50_buffer_reallocate(struct nv50_screen *screen, struct nv50_resource *buf, - unsigned domain) -{ - nv50_buffer_release_gpu_storage(buf); - - return nv50_buffer_allocate(screen, buf, domain); -} - -static void -nv50_buffer_destroy(struct pipe_screen *pscreen, - struct pipe_resource *presource) -{ - struct nv50_resource *res = nv50_resource(presource); - - nv50_buffer_release_gpu_storage(res); - - if (res->data && !(res->status & NV50_BUFFER_STATUS_USER_MEMORY)) - FREE(res->data); - - FREE(res); -} - -/* Maybe just migrate to GART right away if we actually need to do this. */ -boolean -nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf, - unsigned start, unsigned size) -{ - struct nouveau_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - assert(buf->domain == NOUVEAU_BO_VRAM); - - mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset); - if (!bounce) - return FALSE; - - nv50_m2mf_copy_linear(nv50, 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)) - return FALSE; - memcpy(buf->data + start, bounce->map, size); - nouveau_bo_unmap(bounce); - - buf->status &= ~NV50_BUFFER_STATUS_DIRTY; - - nouveau_bo_ref(NULL, &bounce); - if (mm) - nouveau_mm_free(mm); - return TRUE; -} - -static boolean -nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, - unsigned start, unsigned size) -{ - struct nouveau_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - if (size <= 192) { - nv50_sifc_linear_u8(nv50, buf->bo, buf->domain, buf->offset + start, - size, buf->data + start); - return TRUE; - } - - mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset); - 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); - - nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - bounce, offset, NOUVEAU_BO_GART, size); - - nouveau_bo_ref(NULL, &bounce); - if (mm) - release_allocation(&mm, nv50->screen->base.fence.current); - - if (start == 0 && size == buf->base.width0) - buf->status &= ~NV50_BUFFER_STATUS_DIRTY; - return TRUE; -} - -static struct pipe_transfer * -nv50_buffer_transfer_get(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box) -{ - struct nv50_resource *buf = nv50_resource(resource); - struct nv50_transfer *xfr = CALLOC_STRUCT(nv50_transfer); - if (!xfr) - return NULL; - - xfr->base.resource = resource; - xfr->base.box.x = box->x; - xfr->base.box.width = box->width; - xfr->base.usage = usage; - - if (buf->domain == NOUVEAU_BO_VRAM) { - if (usage & PIPE_TRANSFER_READ) { - if (buf->status & NV50_BUFFER_STATUS_DIRTY) - nv50_buffer_download(nv50_context(pipe), buf, 0, buf->base.width0); - } - } - - return &xfr->base; -} - -static void -nv50_buffer_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nv50_resource *buf = nv50_resource(transfer->resource); - struct nv50_transfer *xfr = nv50_transfer(transfer); - - if (xfr->base.usage & PIPE_TRANSFER_WRITE) { - /* writing is worse */ - nv50_buffer_adjust_score(nv50_context(pipe), buf, -5000); - - if (buf->domain == NOUVEAU_BO_VRAM) { - nv50_buffer_upload(nv50_context(pipe), buf, - transfer->box.x, transfer->box.width); - } - - if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | - PIPE_BIND_INDEX_BUFFER))) - nv50_context(pipe)->vbo_dirty = TRUE; - } - - FREE(xfr); -} - -static INLINE boolean -nv50_buffer_sync(struct nv50_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) { - if (!buf->fence_wr) - return TRUE; - if (!nouveau_fence_wait(buf->fence_wr)) - return FALSE; - } else { - if (!buf->fence) - return TRUE; - if (!nouveau_fence_wait(buf->fence)) - return FALSE; - - nouveau_fence_ref(NULL, &buf->fence); - } - nouveau_fence_ref(NULL, &buf->fence_wr); - - return TRUE; -} - -static INLINE boolean -nv50_buffer_busy(struct nv50_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) - return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); - else - return (buf->fence && !nouveau_fence_signalled(buf->fence)); -} - -static void * -nv50_buffer_transfer_map(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nv50_transfer *xfr = nv50_transfer(transfer); - struct nv50_resource *buf = nv50_resource(transfer->resource); - struct nouveau_bo *bo = buf->bo; - uint8_t *map; - int ret; - uint32_t offset = xfr->base.box.x; - uint32_t flags; - - nv50_buffer_adjust_score(nv50_context(pipe), buf, -250); - - if (buf->domain != NOUVEAU_BO_GART) - return buf->data + offset; - - if (buf->mm) - flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR; - else - flags = nouveau_screen_transfer_flags(xfr->base.usage); - - offset += buf->offset; - - ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags); - 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); - - if (buf->mm) { - if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) { - if (nv50_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) - return NULL; - } else - if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { - nv50_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); - } - } - return map; -} - - - -static void -nv50_buffer_transfer_flush_region(struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct nv50_resource *res = nv50_resource(transfer->resource); - struct nouveau_bo *bo = res->bo; - unsigned offset = res->offset + transfer->box.x + box->x; - - /* not using non-snoop system memory yet, no need for cflush */ - if (1) - return; - - /* XXX: maybe need to upload for VRAM buffers here */ - - nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width); -} - -static void -nv50_buffer_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - /* we've called nouveau_bo_unmap right after map */ -} - -const struct u_resource_vtbl nv50_buffer_vtbl = -{ - u_default_resource_get_handle, /* get_handle */ - nv50_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - nv50_buffer_transfer_get, /* get_transfer */ - nv50_buffer_transfer_destroy, /* transfer_destroy */ - nv50_buffer_transfer_map, /* transfer_map */ - nv50_buffer_transfer_flush_region, /* transfer_flush_region */ - nv50_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - -struct pipe_resource * -nv50_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ) -{ - struct nv50_screen *screen = nv50_screen(pscreen); - struct nv50_resource *buffer; - boolean ret; - - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; - - buffer->base = *templ; - buffer->vtbl = &nv50_buffer_vtbl; - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = pscreen; - - if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) - ret = nv50_buffer_allocate(screen, buffer, 0); - else - ret = nv50_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); - - if (ret == FALSE) - goto fail; - - return &buffer->base; - -fail: - FREE(buffer); - return NULL; -} - - -struct pipe_resource * -nv50_user_buffer_create(struct pipe_screen *pscreen, - void *ptr, - unsigned bytes, - unsigned bind) -{ - struct nv50_resource *buffer; - - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->vtbl = &nv50_buffer_vtbl; - buffer->base.screen = pscreen; - buffer->base.format = PIPE_FORMAT_R8_UNORM; - buffer->base.usage = PIPE_USAGE_IMMUTABLE; - buffer->base.bind = bind; - buffer->base.width0 = bytes; - buffer->base.height0 = 1; - buffer->base.depth0 = 1; - - buffer->data = ptr; - buffer->status = NV50_BUFFER_STATUS_USER_MEMORY; - - return &buffer->base; -} - -/* Like download, but for GART buffers. Merge ? */ -static INLINE boolean -nv50_buffer_data_fetch(struct nv50_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)) - return FALSE; - memcpy(buf->data, bo->map, size); - nouveau_bo_unmap(bo); - - return TRUE; -} - -/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ -boolean -nv50_buffer_migrate(struct nv50_context *nv50, - struct nv50_resource *buf, const unsigned new_domain) -{ - struct nv50_screen *screen = nv50_screen(buf->base.screen); - struct nouveau_bo *bo; - const unsigned old_domain = buf->domain; - unsigned size = buf->base.width0; - unsigned offset; - int ret; - - assert(new_domain != old_domain); - - if (new_domain == NOUVEAU_BO_GART && old_domain == 0) { - if (!nv50_buffer_allocate(screen, buf, new_domain)) - return FALSE; - ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR | - NOUVEAU_BO_NOSYNC); - if (ret) - return ret; - memcpy(buf->bo->map, buf->data, size); - nouveau_bo_unmap(buf->bo); - FREE(buf->data); - } else - if (old_domain != 0 && new_domain != 0) { - struct nouveau_mm_allocation *mm = buf->mm; - - if (new_domain == NOUVEAU_BO_VRAM) { - /* keep a system memory copy of our data in case we hit a fallback */ - if (!nv50_buffer_data_fetch(buf, buf->bo, buf->offset, size)) - return FALSE; - debug_printf("migrating %u KiB to VRAM\n", size / 1024); - } - - offset = buf->offset; - bo = buf->bo; - buf->bo = NULL; - buf->mm = NULL; - nv50_buffer_allocate(screen, buf, new_domain); - - nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset, new_domain, - bo, offset, old_domain, buf->base.width0); - - nouveau_bo_ref(NULL, &bo); - if (mm) - release_allocation(&mm, screen->base.fence.current); - } else - if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { - if (!nv50_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) - return FALSE; - if (!nv50_buffer_upload(nv50, buf, 0, buf->base.width0)) - return FALSE; - } else - return FALSE; - - assert(buf->domain == new_domain); - return TRUE; -} - -/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. - * We'd like to only allocate @size bytes here, but then we'd have to rebase - * the vertex indices ... - */ -boolean -nv50_user_buffer_upload(struct nv50_resource *buf, unsigned base, unsigned size) -{ - struct nv50_screen *screen = nv50_screen(buf->base.screen); - int ret; - - assert(buf->status & NV50_BUFFER_STATUS_USER_MEMORY); - - buf->base.width0 = base + size; - if (!nv50_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); - if (ret) - return FALSE; - memcpy(buf->bo->map, buf->data + base, size); - nouveau_bo_unmap(buf->bo); - - return TRUE; -} diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 4380945a1e..03a5c3d2d9 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -119,13 +119,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv) } struct resident { - struct nv50_resource *res; + struct nv04_resource *res; uint32_t flags; }; void nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, - struct nv50_resource *resource, uint32_t flags) + struct nv04_resource *resource, uint32_t flags) { struct resident rsd = { resource, flags }; @@ -140,7 +140,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, void nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx, - struct nv50_resource *resource) + struct nv04_resource *resource) { struct resident *rsd, *top; unsigned i; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index a6275d7958..55d996da27 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -155,9 +155,9 @@ void nv50_default_flush_notify(struct nouveau_channel *); void nv50_bufctx_emit_relocs(struct nv50_context *); void nv50_bufctx_add_resident(struct nv50_context *, int ctx, - struct nv50_resource *, uint32_t flags); + struct nv04_resource *, uint32_t flags); void nv50_bufctx_del_resident(struct nv50_context *, int ctx, - struct nv50_resource *); + struct nv04_resource *); static INLINE void nv50_bufctx_reset(struct nv50_context *nv50, int ctx) { @@ -204,11 +204,11 @@ nv50_create_sampler_view(struct pipe_context *, /* nv50_transfer.c */ void -nv50_sifc_linear_u8(struct nv50_context *nv50, - struct nouveau_bo *dst, unsigned domain, int offset, +nv50_sifc_linear_u8(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nv50_m2mf_copy_linear(struct nv50_context *nv50, +nv50_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 51ada6d749..07034bdcf6 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -227,10 +227,10 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) for (i = 0; i < nv50->num_vtxbufs; ++i) { uint8_t *data; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; - struct nv50_resource *res = nv50_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); - data = nv50_resource_map_offset(nv50, res, - vb->buffer_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nv50->pipe, res, + vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) data += info->index_bias * vb->stride; @@ -239,9 +239,9 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nv50_resource_map_offset(nv50, - nv50_resource(nv50->idxbuf.buffer), - nv50->idxbuf.offset, NOUVEAU_BO_RD); + ctx.idxbuf = nouveau_resource_map_offset(&nv50->pipe, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) return; index_size = nv50->idxbuf.index_size; @@ -285,8 +285,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) - nv50_resource_unmap(nv50_resource(nv50->idxbuf.buffer)); + nouveau_resource_unmap(nv04_resource(nv50->idxbuf.buffer)); for (i = 0; i < nv50->num_vtxbufs; ++i) - nv50_resource_unmap(nv50_resource(nv50->vtxbuf[i].buffer)); + nouveau_resource_unmap(nv04_resource(nv50->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c index ae1a2bf55d..2a2fb0e32b 100644 --- a/src/gallium/drivers/nv50/nv50_resource.c +++ b/src/gallium/drivers/nv50/nv50_resource.c @@ -8,7 +8,7 @@ nv50_resource_is_referenced(struct pipe_context *pipe, struct pipe_resource *resource, unsigned face, int layer) { - struct nv50_resource *res = nv50_resource(resource); + struct nv04_resource *res = nv04_resource(resource); unsigned flags = 0; unsigned bo_flags = nouveau_bo_pending(res->bo); @@ -26,7 +26,7 @@ nv50_resource_create(struct pipe_screen *screen, { switch (templ->target) { case PIPE_BUFFER: - return nv50_buffer_create(screen, templ); + return nouveau_buffer_create(screen, templ); default: return nv50_miptree_create(screen, templ); } @@ -64,5 +64,5 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_from_handle = nv50_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; - pscreen->user_buffer_create = nv50_user_buffer_create; + pscreen->user_buffer_create = nouveau_user_buffer_create; } diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index 64563421fd..76229298f7 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -6,112 +6,14 @@ #include "util/u_double_list.h" #define NOUVEAU_NVC0 #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_buffer.h" #undef NOUVEAU_NVC0 -struct pipe_resource; -struct nouveau_bo; -struct nv50_context; - -#define NV50_BUFFER_SCORE_MIN -25000 -#define NV50_BUFFER_SCORE_MAX 25000 -#define NV50_BUFFER_SCORE_VRAM_THRESHOLD 20000 - -/* DIRTY: buffer was (or will be after the next flush) written to by GPU and - * resource->data has not been updated to reflect modified VRAM contents - * - * USER_MEMORY: resource->data is a pointer to client memory and may change - * between GL calls - */ -#define NV50_BUFFER_STATUS_DIRTY (1 << 0) -#define NV50_BUFFER_STATUS_USER_MEMORY (1 << 7) - -/* Resources, if mapped into the GPU's address space, are guaranteed to - * have constant virtual addresses. - * The address of a resource will lie within the nouveau_bo referenced, - * and this bo should be added to the memory manager's validation list. - */ -struct nv50_resource { - struct pipe_resource base; - const struct u_resource_vtbl *vtbl; - - uint8_t *data; - struct nouveau_bo *bo; - uint32_t offset; - - uint8_t status; - uint8_t domain; - - int16_t score; /* low if mapped very often, if high can move to VRAM */ - - struct nouveau_fence *fence; - struct nouveau_fence *fence_wr; - - struct nouveau_mm_allocation *mm; -}; - void -nv50_buffer_release_gpu_storage(struct nv50_resource *); - -boolean -nv50_buffer_download(struct nv50_context *, struct nv50_resource *, - unsigned start, unsigned size); - -boolean -nv50_buffer_migrate(struct nv50_context *, - struct nv50_resource *, unsigned domain); - -static INLINE void -nv50_buffer_adjust_score(struct nv50_context *nv50, struct nv50_resource *res, - int16_t score) -{ - if (score < 0) { - if (res->score > NV50_BUFFER_SCORE_MIN) - res->score += score; - } else - if (score > 0){ - if (res->score < NV50_BUFFER_SCORE_MAX) - res->score += score; - if (res->domain == NOUVEAU_BO_GART && - res->score > NV50_BUFFER_SCORE_VRAM_THRESHOLD) - nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM); - } -} - -/* XXX: wait for fence (atm only using this for vertex push) */ -static INLINE void * -nv50_resource_map_offset(struct nv50_context *nv50, - struct nv50_resource *res, uint32_t offset, - uint32_t flags) -{ - void *map; - - nv50_buffer_adjust_score(nv50, res, -250); - - if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NV50_BUFFER_STATUS_DIRTY)) - nv50_buffer_download(nv50, res, 0, res->base.width0); - - if ((res->domain != NOUVEAU_BO_GART) || - (res->status & NV50_BUFFER_STATUS_USER_MEMORY)) - return res->data + offset; - - if (res->mm) - flags |= NOUVEAU_BO_NOSYNC; - - if (nouveau_bo_map_range(res->bo, res->offset + offset, - res->base.width0, flags)) - return NULL; - - map = res->bo->map; - nouveau_bo_unmap(res->bo); - return map; -} +nv50_init_resource_functions(struct pipe_context *pcontext); -static INLINE void -nv50_resource_unmap(struct nv50_resource *res) -{ - /* no-op */ -} +void +nv50_screen_init_resource_functions(struct pipe_screen *pscreen); #define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) @@ -133,7 +35,7 @@ struct nv50_miptree_level { #define NV50_MAX_TEXTURE_LEVELS 16 struct nv50_miptree { - struct nv50_resource base; + struct nv04_resource base; struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; uint32_t total_size; uint32_t layer_stride; @@ -146,25 +48,6 @@ nv50_miptree(struct pipe_resource *pt) return (struct nv50_miptree *)pt; } -static INLINE struct nv50_resource * -nv50_resource(struct pipe_resource *resource) -{ - return (struct nv50_resource *)resource; -} - -/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ -static INLINE boolean -nv50_resource_mapped_by_gpu(struct pipe_resource *resource) -{ - return nv50_resource(resource)->domain != 0; -} - -void -nv50_init_resource_functions(struct pipe_context *pcontext); - -void -nv50_screen_init_resource_functions(struct pipe_screen *pscreen); - /* Internal functions: */ struct pipe_resource * @@ -176,17 +59,6 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle); -struct pipe_resource * -nv50_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ); - -struct pipe_resource * -nv50_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); - - struct pipe_surface * nv50_miptree_surface_new(struct pipe_context *, struct pipe_resource *, @@ -195,7 +67,4 @@ nv50_miptree_surface_new(struct pipe_context *, void nv50_miptree_surface_del(struct pipe_context *, struct pipe_surface *); -boolean -nv50_user_buffer_upload(struct nv50_resource *, unsigned base, unsigned size); - #endif diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f2b03e8156..13c03b1a7e 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -310,6 +310,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; + screen->base.copy_data = nv50_m2mf_copy_linear; + screen->base.push_data = nv50_sifc_linear_u8; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 3bf67eb656..eb9743a05d 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -73,7 +73,7 @@ int nv50_screen_tic_alloc(struct nv50_screen *, void *); int nv50_screen_tsc_alloc(struct nv50_screen *, void *); static INLINE void -nv50_resource_fence(struct nv50_resource *res, uint32_t flags) +nv50_resource_fence(struct nv04_resource *res, uint32_t flags) { struct nv50_screen *screen = nv50_screen(res->base.screen); @@ -86,7 +86,7 @@ nv50_resource_fence(struct nv50_resource *res, uint32_t flags) } static INLINE void -nv50_resource_validate(struct nv50_resource *res, uint32_t flags) +nv50_resource_validate(struct nv04_resource *res, uint32_t flags) { struct nv50_screen *screen = nv50_screen(res->base.screen); diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index e530b3390a..2d7572820f 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -35,7 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) unsigned s; for (s = 0; s < 3; ++s) { - struct nv50_resource *res; + struct nv04_resource *res; int i; unsigned p, b; @@ -55,7 +55,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) i = ffs(nv50->constbuf_dirty[s]) - 1; nv50->constbuf_dirty[s] &= ~(1 << i); - res = nv50_resource(nv50->constbuf[s][i]); + res = nv04_resource(nv50->constbuf[s][i]); if (!res) { if (i != 0) { BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); @@ -75,8 +75,8 @@ nv50_constbufs_validate(struct nv50_context *nv50) assert(0); - if (!nv50_resource_mapped_by_gpu(&res->base)) { - nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM); + if (!nouveau_resource_mapped_by_gpu(&res->base)) { + nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM); BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (chan, 0); @@ -149,9 +149,9 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; prog->code_base = prog->res->start; - nv50_sifc_linear_u8(nv50, nv50->screen->code, NOUVEAU_BO_VRAM, - (prog->type << 16) + prog->code_base, prog->code_size, - prog->code); + nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code, + (prog->type << 16) + prog->code_base, + NOUVEAU_BO_VRAM, prog->code_size, prog->code); BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (nv50->screen->base.channel, 0); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 5e1fff46e4..ed2fd3b0f8 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -651,8 +651,7 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (nv50->constbuf[shader][index]) nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT, - nv50_resource( - nv50->constbuf[shader][index])); + nv04_resource(nv50->constbuf[shader][index])); pipe_resource_reference(&nv50->constbuf[shader][index], res); diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 93e74ca059..eaee0a1107 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -168,7 +168,7 @@ nv50_validate_tic(struct nv50_context *nv50, int s) for (i = 0; i < nv50->num_textures[s]; ++i) { struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]); - struct nv50_resource *res; + struct nv04_resource *res; if (!tic) { BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); @@ -261,8 +261,9 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) if (tsc->id < 0) { tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); - nv50_sifc_linear_u8(nv50, nv50->screen->txc, NOUVEAU_BO_VRAM, - 65536 + tsc->id * 32, 32, tsc->tsc); + nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->txc, + 65536 + tsc->id * 32, + NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; } nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 696350d10c..d80a535490 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -102,10 +102,11 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nv50_sifc_linear_u8(struct nv50_context *nv50, - struct nouveau_bo *dst, unsigned domain, int offset, +nv50_sifc_linear_u8(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { + struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -158,11 +159,12 @@ nv50_sifc_linear_u8(struct nv50_context *nv50, } void -nv50_m2mf_copy_linear(struct nv50_context *nv50, +nv50_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { + struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index d18b2dffd1..1f0d34ed79 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -127,12 +127,12 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, { const void *data; struct nouveau_channel *chan = nv50->screen->base.channel; - struct nv50_resource *res = nv50_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); float v[4]; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nv50_resource_map_offset(nv50, res, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nv50->pipe, res, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -189,7 +189,7 @@ static void nv50_prevalidate_vbufs(struct nv50_context *nv50) { struct pipe_vertex_buffer *vb; - struct nv50_resource *buf; + struct nv04_resource *buf; int i; uint32_t base, size; @@ -201,27 +201,27 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) vb = &nv50->vtxbuf[i]; if (!vb->stride) continue; - buf = nv50_resource(vb->buffer); + buf = nv04_resource(vb->buffer); /* NOTE: user buffers with temporary storage count as mapped by GPU */ - if (!nv50_resource_mapped_by_gpu(vb->buffer)) { + if (!nouveau_resource_mapped_by_gpu(vb->buffer)) { if (nv50->vbo_push_hint) { nv50->vbo_fifo = ~0; continue; } else { - if (buf->status & NV50_BUFFER_STATUS_USER_MEMORY) { + if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) { nv50->vbo_user |= 1 << i; assert(vb->stride > vb->buffer_offset); nv50_vbuf_range(nv50, i, &base, &size); - nv50_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } else { - nv50_buffer_migrate(nv50, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nv50->pipe, buf, NOUVEAU_BO_GART); } nv50->vbo_dirty = TRUE; } } nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nv50_buffer_adjust_score(nv50, buf, 1); + nouveau_buffer_adjust_score(&nv50->pipe, buf, 1); } } @@ -237,7 +237,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe; const int b = ve->vertex_buffer_index; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b]; - struct nv50_resource *buf = nv50_resource(vb->buffer); + struct nv04_resource *buf = nv04_resource(vb->buffer); if (!(nv50->vbo_user & (1 << b))) continue; @@ -250,7 +250,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) if (!(written & (1 << b))) { written |= 1 << b; - nv50_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } offset = vb->buffer_offset + ve->src_offset; @@ -274,7 +274,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50) int i = ffs(vbo_user) - 1; vbo_user &= ~(1 << i); - nv50_buffer_release_gpu_storage(nv50_resource(nv50->vtxbuf[i].buffer)); + nouveau_buffer_release_gpu_storage(nv04_resource(nv50->vtxbuf[i].buffer)); } } @@ -308,7 +308,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) } for (i = 0; i < vertex->num_elements; ++i) { - struct nv50_resource *res; + struct nv04_resource *res; unsigned size, offset; ve = &vertex->element[i]; @@ -327,7 +327,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) OUT_RING (chan, 0); } - res = nv50_resource(vb->buffer); + res = nv04_resource(vb->buffer); if (nv50->vbo_fifo || unlikely(vb->stride == 0)) { if (!nv50->vbo_fifo) @@ -536,11 +536,11 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, nv50->state.index_bias = index_bias; } - if (nv50_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) { - struct nv50_resource *res = nv50_resource(nv50->idxbuf.buffer); + if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) { + struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); unsigned offset = res->offset + nv50->idxbuf.offset; - nv50_buffer_adjust_score(nv50, res, 1); + nouveau_buffer_adjust_score(&nv50->pipe, res, 1); while (instance_count--) { BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); @@ -597,8 +597,9 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nv50_resource_map_offset(nv50, nv50_resource(nv50->idxbuf.buffer), - nv50->idxbuf.offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nv50->pipe, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!data) return; diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index 8aaf24c009..35e79210a6 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -4,6 +4,7 @@ #include <stdint.h> #include <unistd.h> + #include "pipe/p_defines.h" #include "nouveau/nouveau_bo.h" @@ -13,8 +14,9 @@ #include "nouveau/nouveau_resource.h" #include "nouveau/nouveau_pushbuf.h" #include "nouveau/nouveau_reloc.h" +#include "nouveau/nouveau_notifier.h" -#include "nv50_resource.h" /* OUT_RESRC */ +#include "nouveau/nouveau_buffer.h" #ifndef NV04_PFIFO_MAX_PACKET_LEN #define NV04_PFIFO_MAX_PACKET_LEN 2047 @@ -68,18 +70,18 @@ BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size) } static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nv50_resource *res, +OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags); } static INLINE int -OUT_RESRCl(struct nouveau_channel *chan, struct nv50_resource *res, +OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NV50_BUFFER_STATUS_DIRTY; + res->status |= NOUVEAU_BUFFER_STATUS_DIRTY; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } |