From: Christoph Bumiller Date: Fri, 6 Apr 2012 13:41:55 +0000 (+0200) Subject: nouveau: switch to libdrm_nouveau-2.0 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6d1cdec3ba151168bfc3aef222fba6265dfb41fb;p=mesa.git nouveau: switch to libdrm_nouveau-2.0 --- diff --git a/configure.ac b/configure.ac index 1e4d9ae5587..c9be8c76fbd 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ LIBDRM_REQUIRED=2.4.24 LIBDRM_RADEON_REQUIRED=2.4.31 LIBDRM_INTEL_REQUIRED=2.4.32 LIBDRM_NVVIEUX_REQUIRED=2.4.33 -LIBDRM_NOUVEAU_REQUIRED=0.6 +LIBDRM_NOUVEAU_REQUIRED=2.4.33 DRI2PROTO_REQUIRED=2.6 GLPROTO_REQUIRED=1.4.14 LIBDRM_XORG_REQUIRED=2.4.24 diff --git a/src/gallium/drivers/nouveau/Makefile.sources b/src/gallium/drivers/nouveau/Makefile.sources index 5a5998bca0a..cc9e68f44a8 100644 --- a/src/gallium/drivers/nouveau/Makefile.sources +++ b/src/gallium/drivers/nouveau/Makefile.sources @@ -3,4 +3,5 @@ C_SOURCES := \ nouveau_fence.c \ nouveau_mm.c \ nouveau_buffer.c \ + nouveau_heap.c \ nouveau_video.c 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; } diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index c0a781c6fd3..3d97ac33b7d 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -28,6 +28,8 @@ struct nv04_resource { struct pipe_resource base; const struct u_resource_vtbl *vtbl; + uint64_t address; /* virtual address (nv50+) */ + uint8_t *data; struct nouveau_bo *bo; uint32_t offset; @@ -52,33 +54,9 @@ boolean nouveau_buffer_migrate(struct nouveau_context *, struct nv04_resource *, unsigned domain); -/* XXX: wait for fence (atm only using this for vertex push) */ -static INLINE void * -nouveau_resource_map_offset(struct nouveau_context *pipe, - struct nv04_resource *res, uint32_t offset, - uint32_t flags) -{ - void *map; - - if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)) - nouveau_buffer_download(pipe, 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) - 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; -} +void * +nouveau_resource_map_offset(struct nouveau_context *, struct nv04_resource *, + uint32_t offset, uint32_t flags); static INLINE void nouveau_resource_unmap(struct nv04_resource *res) @@ -108,7 +86,7 @@ nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, unsigned usage); boolean -nouveau_user_buffer_upload(struct nv04_resource *, unsigned base, - unsigned size); +nouveau_user_buffer_upload(struct nouveau_context *, struct nv04_resource *, + unsigned base, unsigned size); #endif diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index 92aea76b424..4e6085f6935 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -3,10 +3,14 @@ #include "pipe/p_context.h" +struct nouveau_pushbuf; + struct nouveau_context { struct pipe_context pipe; struct nouveau_screen *screen; + struct nouveau_pushbuf *pushbuf; + boolean vbo_dirty; boolean cb_dirty; diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index a2fcafef4a7..d2f98654f31 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -23,10 +23,9 @@ #include "util/u_double_list.h" #include "nouveau_screen.h" +#include "nouveau_winsys.h" #include "nouveau_fence.h" -#include "nouveau/nouveau_pushbuf.h" - #ifdef PIPE_OS_UNIX #include #endif @@ -197,7 +196,7 @@ nouveau_fence_wait(struct nouveau_fence *fence) nouveau_fence_new(screen, &screen->fence.current, FALSE); } if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) - FIRE_RING(screen->channel); + nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel); do { nouveau_fence_update(screen, FALSE); diff --git a/src/gallium/drivers/nouveau/nouveau_heap.c b/src/gallium/drivers/nouveau/nouveau_heap.c new file mode 100644 index 00000000000..769211b82f0 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_heap.c @@ -0,0 +1,123 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "nouveau_heap.h" + +int +nouveau_heap_init(struct nouveau_heap **heap, + unsigned start, unsigned size) +{ + struct nouveau_heap *r; + + r = calloc(1, sizeof(struct nouveau_heap)); + if (!r) + return 1; + + r->start = start; + r->size = size; + *heap = r; + return 0; +} + +void +nouveau_heap_destroy(struct nouveau_heap **heap) +{ + if (!*heap) + return; + free(*heap); + *heap = NULL; +} + +int +nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv, + struct nouveau_heap **res) +{ + struct nouveau_heap *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = calloc(1, sizeof(struct nouveau_heap)); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = 1; + 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; +} + +void +nouveau_heap_free(struct nouveau_heap **res) +{ + struct nouveau_heap *r; + + if (!res || !*res) + return; + r = *res; + *res = NULL; + + r->in_use = 0; + + if (r->next && !r->next->in_use) { + struct nouveau_heap *new = r->next; + + new->prev = r->prev; + if (r->prev) + r->prev->next = new; + new->size += r->size; + new->start = r->start; + + free(r); + r = new; + } + + 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); + } +} diff --git a/src/gallium/drivers/nouveau/nouveau_heap.h b/src/gallium/drivers/nouveau/nouveau_heap.h new file mode 100644 index 00000000000..34d9a82774e --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_heap.h @@ -0,0 +1,52 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __NOUVEAU_HEAP_H__ +#define __NOUVEAU_HEAP_H__ + +struct nouveau_heap { + struct nouveau_heap *prev; + struct nouveau_heap *next; + + void *priv; + + unsigned start; + unsigned size; + + int in_use; +}; + +int +nouveau_heap_init(struct nouveau_heap **heap, unsigned start, + unsigned size); + +void +nouveau_heap_destroy(struct nouveau_heap **heap); + +int +nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv, + struct nouveau_heap **); + +void +nouveau_heap_free(struct nouveau_heap **); + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 8d0b7bfe99a..4207084aecf 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -5,11 +5,10 @@ #include "util/u_memory.h" #include "util/u_double_list.h" +#include "nouveau_winsys.h" #include "nouveau_screen.h" #include "nouveau_mm.h" -#include "nouveau/nouveau_bo.h" - #define MM_MIN_ORDER 7 #define MM_MAX_ORDER 20 @@ -28,8 +27,8 @@ struct mm_bucket { struct nouveau_mman { struct nouveau_device *dev; struct mm_bucket bucket[MM_NUM_BUCKETS]; - uint32_t storage_type; uint32_t domain; + union nouveau_bo_config config; uint64_t allocated; }; @@ -128,8 +127,9 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order) memset(&slab->bits[0], ~0, words * 4); slab->bo = NULL; - ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size, - 0, cache->storage_type, &slab->bo); + + ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config, + &slab->bo); if (ret) { FREE(slab); return PIPE_ERROR_OUT_OF_MEMORY; @@ -155,7 +155,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order) /* @return token to identify slab or NULL if we just allocated a new bo */ struct nouveau_mm_allocation * nouveau_mm_allocate(struct nouveau_mman *cache, - uint32_t size, struct nouveau_bo **bo, uint32_t *offset) + uint32_t size, struct nouveau_bo **bo, uint32_t *offset) { struct mm_bucket *bucket; struct mm_slab *slab; @@ -164,10 +164,11 @@ nouveau_mm_allocate(struct nouveau_mman *cache, bucket = mm_bucket_by_size(cache, size); if (!bucket) { - ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size, - 0, cache->storage_type, bo); + ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config, + bo); if (ret) - debug_printf("bo_new(%x, %x): %i\n", size, cache->storage_type, ret); + debug_printf("bo_new(%x, %x): %i\n", + size, cache->config.nv50.memtype, ret); *offset = 0; return NULL; @@ -233,7 +234,7 @@ nouveau_mm_free_work(void *data) struct nouveau_mman * nouveau_mm_create(struct nouveau_device *dev, uint32_t domain, - uint32_t storage_type) + union nouveau_bo_config *config) { struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman); int i; @@ -243,7 +244,7 @@ nouveau_mm_create(struct nouveau_device *dev, uint32_t domain, cache->dev = dev; cache->domain = domain; - cache->storage_type = storage_type; + cache->config = *config; cache->allocated = 0; for (i = 0; i < MM_NUM_BUCKETS; ++i) { diff --git a/src/gallium/drivers/nouveau/nouveau_mm.h b/src/gallium/drivers/nouveau/nouveau_mm.h index 5b57c8ba4f2..8e4f1e5713f 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.h +++ b/src/gallium/drivers/nouveau/nouveau_mm.h @@ -1,6 +1,7 @@ #ifndef __NOUVEAU_MM_H__ #define __NOUVEAU_MM_H__ +union nouveau_bo_config; struct nouveau_mman; /* Since a resource can be migrated, we need to decouple allocations from @@ -14,7 +15,7 @@ struct nouveau_mm_allocation { extern struct nouveau_mman * nouveau_mm_create(struct nouveau_device *, uint32_t domain, - uint32_t storage_type); + union nouveau_bo_config *); extern void nouveau_mm_destroy(struct nouveau_mman *); diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 8ebae8e27dc..74377799977 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -12,17 +12,15 @@ #include #include -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_mm.h" #include "nouveau_winsys.h" #include "nouveau_screen.h" #include "nouveau_fence.h" +#include "nouveau_mm.h" +#include "nouveau_buffer.h" /* XXX this should go away */ #include "state_tracker/drm_driver.h" -#include "nouveau_drmif.h" - int nouveau_mesa_debug = 0; static const char * @@ -41,102 +39,6 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen) return "nouveau"; } - - -struct nouveau_bo * -nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, - unsigned usage, unsigned bind, unsigned size) -{ - struct nouveau_device *dev = nouveau_screen(pscreen)->device; - struct nouveau_bo *bo = NULL; - uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0; - int ret; - - if (bind & PIPE_BIND_VERTEX_BUFFER) - flags |= nouveau_screen(pscreen)->vertex_buffer_flags; - else if (bind & PIPE_BIND_INDEX_BUFFER) - flags |= nouveau_screen(pscreen)->index_buffer_flags; - - if (bind & (PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DEPTH_STENCIL | - PIPE_BIND_SCANOUT | - PIPE_BIND_DISPLAY_TARGET | - PIPE_BIND_SAMPLER_VIEW)) - { - /* TODO: this may be incorrect or suboptimal */ - if (!(bind & PIPE_BIND_SCANOUT)) - flags |= NOUVEAU_BO_GART; - if (usage != PIPE_USAGE_DYNAMIC) - flags |= NOUVEAU_BO_VRAM; - - if (dev->chipset == 0x50 || dev->chipset >= 0x80) { - if (bind & PIPE_BIND_DEPTH_STENCIL) - tile_flags = 0x2800; - else - tile_flags = 0x7000; - } - } - - ret = nouveau_bo_new_tile(dev, flags, alignment, size, - tile_mode, tile_flags, &bo); - if (ret) - return NULL; - - return bo; -} - -void * -nouveau_screen_bo_map(struct pipe_screen *pscreen, - struct nouveau_bo *bo, - unsigned map_flags) -{ - int ret; - - ret = nouveau_bo_map(bo, map_flags); - if (ret) { - debug_printf("map failed: %d\n", ret); - return NULL; - } - - return bo->map; -} - -void * -nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, - unsigned offset, unsigned length, unsigned flags) -{ - int ret; - - ret = nouveau_bo_map_range(bo, offset, length, flags); - if (ret) { - nouveau_bo_unmap(bo); - if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY) - debug_printf("map_range failed: %d\n", ret); - return NULL; - } - - return (char *)bo->map - offset; /* why gallium? why? */ -} - -void -nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, - unsigned offset, unsigned length) -{ - nouveau_bo_map_flush(bo, offset, length); -} - -void -nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo) -{ - nouveau_bo_unmap(bo); -} - -void -nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo) -{ - nouveau_bo_ref(NULL, &bo); -} - static void nouveau_screen_fence_ref(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr, @@ -157,7 +59,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *pfence, uint64_t timeout) { - return nouveau_fence_wait(nouveau_fence(pfence)); + return nouveau_fence_wait(nouveau_fence(pfence)); } @@ -170,7 +72,7 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, struct nouveau_bo *bo = 0; int ret; - ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo); + ret = nouveau_bo_name_ref(dev, whandle->handle, &bo); if (ret) { debug_printf("%s: ref name 0x%08x failed with %d\n", __FUNCTION__, whandle->handle, ret); @@ -191,7 +93,7 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, whandle->stride = stride; if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { - return nouveau_bo_handle_get(bo, &whandle->handle) == 0; + return nouveau_bo_name_get(bo, &whandle->handle) == 0; } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { whandle->handle = bo->handle; return TRUE; @@ -204,18 +106,39 @@ int nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) { struct pipe_screen *pscreen = &screen->base; - int ret; + struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 }; + struct nvc0_fifo nvc0_data = { }; + int size, ret; + void *data; + union nouveau_bo_config mm_config; char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG"); if (nv_dbg) nouveau_mesa_debug = atoi(nv_dbg); - ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202, - 512*1024, &screen->channel); + if (dev->chipset < 0xc0) { + data = &nv04_data; + size = sizeof(nv04_data); + } else { + data = &nvc0_data; + size = sizeof(nvc0_data); + } + + ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS, + data, size, &screen->channel); if (ret) return ret; screen->device = dev; + ret = nouveau_client_new(screen->device, &screen->client); + if (ret) + return ret; + ret = nouveau_pushbuf_new(screen->client, screen->channel, + 4, 512 * 1024, 1, + &screen->pushbuf); + if (ret) + return ret; + pscreen->get_name = nouveau_screen_get_name; pscreen->get_vendor = nouveau_screen_get_vendor; @@ -225,10 +148,12 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) util_format_s3tc_init(); + memset(&mm_config, 0, sizeof(mm_config)); + screen->mm_GART = nouveau_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0x000); - screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); + &mm_config); + screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config); return 0; } @@ -238,8 +163,10 @@ nouveau_screen_fini(struct nouveau_screen *screen) nouveau_mm_destroy(screen->mm_GART); nouveau_mm_destroy(screen->mm_VRAM); - nouveau_channel_free(&screen->channel); + nouveau_pushbuf_del(&screen->pushbuf); - nouveau_device_close(&screen->device); -} + nouveau_client_del(&screen->client); + nouveau_object_del(&screen->channel); + nouveau_device_del(&screen->device); +} diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index d2003e62f51..a2784773143 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -3,6 +3,7 @@ #include "pipe/p_screen.h" #include "util/u_memory.h" + typedef uint32_t u32; extern int nouveau_mesa_debug; @@ -12,12 +13,10 @@ struct nouveau_bo; struct nouveau_screen { struct pipe_screen base; struct nouveau_device *device; - struct nouveau_channel *channel; + struct nouveau_object *channel; + struct nouveau_client *client; + struct nouveau_pushbuf *pushbuf; - /* note that OpenGL doesn't distinguish between these, so - * these almost always should be set to the same value */ - unsigned vertex_buffer_flags; - unsigned index_buffer_flags; unsigned sysmem_bindings; struct { @@ -40,30 +39,6 @@ nouveau_screen(struct pipe_screen *pscreen) return (struct nouveau_screen *)pscreen; } - - -/* Not really sure if this is needed, or whether the individual - * drivers are happy to talk to the bo functions themselves. In a way - * this is what we'd expect from a regular winsys interface. - */ -struct nouveau_bo * -nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, - unsigned usage, unsigned bind, unsigned size); -void * -nouveau_screen_bo_map(struct pipe_screen *pscreen, - struct nouveau_bo *pb, - unsigned usage); -void * -nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, - unsigned offset, unsigned length, unsigned usage); -void -nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, - unsigned offset, unsigned length); -void -nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo); -void -nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo); - boolean nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, struct nouveau_bo *bo, @@ -80,19 +55,4 @@ void nouveau_screen_fini(struct nouveau_screen *); void nouveau_screen_init_vdec(struct nouveau_screen *); - -#ifndef NOUVEAU_NVC0 -static INLINE unsigned -RING_3D(unsigned mthd, unsigned size) -{ - return (7 << 13) | (size << 18) | mthd; -} - -static INLINE unsigned -RING_3D_NI(unsigned mthd, unsigned size) -{ - return 0x40000000 | (7 << 13) | (size << 18) | mthd; -} -#endif - #endif diff --git a/src/gallium/drivers/nouveau/nouveau_statebuf.h b/src/gallium/drivers/nouveau/nouveau_statebuf.h index dcffdd91154..4f8bd7bdf16 100644 --- a/src/gallium/drivers/nouveau/nouveau_statebuf.h +++ b/src/gallium/drivers/nouveau/nouveau_statebuf.h @@ -20,8 +20,13 @@ struct nouveau_statebuf_builder #define sb_data(sb, v) *(sb).p++ = (v) #endif -#define sb_method(sb, v, n) sb_data(sb, RING_3D(v, n)); +static INLINE uint32_t sb_header(unsigned subc, unsigned mthd, unsigned size) +{ + return (size << 18) | (subc << 13) | mthd; +} + +#define sb_method(sb, v, n) sb_data(sb, sb_header(SUBC_3D(v), n)); #define sb_len(sb, var) ((sb).p - (var)) -#define sb_emit(chan, sb_buf, sb_len) do {WAIT_RING((chan), (sb_len)); OUT_RINGp((chan), (sb_buf), (sb_len)); } while(0) +#define sb_emit(push, sb_buf, sb_len) do {PUSH_SPACE((push), (sb_len)); PUSH_DATAp((push), (sb_buf), (sb_len)); } while(0) #endif diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c index 42bc102b1cf..bd8f0961bc4 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.c +++ b/src/gallium/drivers/nouveau/nouveau_video.c @@ -27,27 +27,23 @@ #include "nouveau_context.h" #include "nouveau_video.h" -#include "nouveau/nouveau_bo.h" #include "nouveau/nouveau_buffer.h" #include "util/u_video.h" #include "util/u_format.h" #include "util/u_sampler.h" -#include "nouveau/nouveau_device.h" -#include "nouveau_winsys.h" static int nouveau_vpe_init(struct nouveau_decoder *dec) { int ret; if (dec->cmds) return 0; - ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR); + ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR, dec->client); if (ret) { debug_printf("Mapping cmd bo: %s\n", strerror(-ret)); return ret; } - ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR); + ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR, dec->client); if (ret) { - nouveau_bo_unmap(dec->cmd_bo); debug_printf("Mapping data bo: %s\n", strerror(-ret)); return ret; } @@ -58,39 +54,45 @@ nouveau_vpe_init(struct nouveau_decoder *dec) { static void nouveau_vpe_synch(struct nouveau_decoder *dec) { - struct nouveau_channel *chan = dec->screen->channel; + struct nouveau_pushbuf *push = dec->push; #if 0 if (dec->fence_map) { - BEGIN_RING(chan, dec->mpeg, NV84_MPEG_QUERY_COUNTER, 1); - OUT_RING(chan, ++dec->fence_seq); - FIRE_RING(chan); + BEGIN_NV04(push, NV84_MPEG(QUERY_COUNTER), 1); + PUSH_DATA (push, ++dec->fence_seq); + PUSH_KICK (push); while (dec->fence_map[0] != dec->fence_seq) usleep(1000); } else #endif - FIRE_RING(chan); + PUSH_KICK(push); } static void nouveau_vpe_fini(struct nouveau_decoder *dec) { - struct nouveau_channel *chan = dec->screen->channel; + struct nouveau_pushbuf *push = dec->push; if (!dec->cmds) return; - nouveau_bo_unmap(dec->data_bo); - nouveau_bo_unmap(dec->cmd_bo); + nouveau_pushbuf_space(push, 8, 2, 0); + nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_CMD); - MARK_RING(chan, 8, 2); - BEGIN_RING(chan, dec->mpeg, NV31_MPEG_CMD_OFFSET, 2); - OUT_RELOCl(chan, dec->cmd_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART); - OUT_RING(chan, dec->ofs * 4); +#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_CMD, NOUVEAU_BO_RD - BEGIN_RING(chan, dec->mpeg, NV31_MPEG_DATA_OFFSET, 2); - OUT_RELOCl(chan, dec->data_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART); - OUT_RING(chan, dec->data_pos * 4); + BEGIN_NV04(push, NV31_MPEG(CMD_OFFSET), 2); + PUSH_MTHDl(push, NV31_MPEG(CMD_OFFSET), dec->cmd_bo, 0, BCTX_ARGS); + PUSH_DATA (push, dec->ofs * 4); - BEGIN_RING(chan, dec->mpeg, NV31_MPEG_EXEC, 1); - OUT_RING(chan, 1); + BEGIN_NV04(push, NV31_MPEG(DATA_OFFSET), 2); + PUSH_MTHDl(push, NV31_MPEG(DATA_OFFSET), dec->data_bo, 0, BCTX_ARGS); + PUSH_DATA (push, dec->data_pos * 4); + +#undef BCTX_ARGS + + if (unlikely(nouveau_pushbuf_validate(dec->push))) + return; + + BEGIN_NV04(push, NV31_MPEG(EXEC), 1); + PUSH_DATA (push, 1); nouveau_vpe_synch(dec); dec->ofs = dec->data_pos = dec->num_surfaces = 0; @@ -384,9 +386,10 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec, struct pipe_video_buffer *buffer) { struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer; - struct nouveau_channel *chan = dec->screen->channel; - struct nouveau_bo *bo_y = ((struct nv04_resource *)buf->resources[0])->bo; - struct nouveau_bo *bo_c = ((struct nv04_resource *)buf->resources[1])->bo; + struct nouveau_pushbuf *push = dec->push; + struct nouveau_bo *bo_y = nv04_resource(buf->resources[0])->bo; + struct nouveau_bo *bo_c = nv04_resource(buf->resources[1])->bo; + unsigned i; if (!buf) @@ -399,10 +402,14 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec, dec->surfaces[i] = buf; dec->num_surfaces++; - MARK_RING(chan, 3, 2); - BEGIN_RING(chan, dec->mpeg, NV31_MPEG_IMAGE_Y_OFFSET(i), 2); - OUT_RELOCl(chan, bo_y, 0, NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo_c, 0, NOUVEAU_BO_RDWR); + nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_IMG(i)); + +#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_IMG(i), NOUVEAU_BO_RDWR + BEGIN_NV04(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), 2); + PUSH_MTHDl(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), bo_y, 0, BCTX_ARGS); + PUSH_MTHDl(push, NV31_MPEG(IMAGE_C_OFFSET(i)), bo_c, 0, BCTX_ARGS); +#undef BCTX_ARGS + return i; } @@ -475,18 +482,24 @@ nouveau_decoder_destroy(struct pipe_video_decoder *decoder) { struct nouveau_decoder *dec = (struct nouveau_decoder*)decoder; - if (dec->cmds) { - nouveau_bo_unmap(dec->data_bo); - nouveau_bo_unmap(dec->cmd_bo); - } - if (dec->data_bo) nouveau_bo_ref(NULL, &dec->data_bo); if (dec->cmd_bo) nouveau_bo_ref(NULL, &dec->cmd_bo); if (dec->fence_bo) nouveau_bo_ref(NULL, &dec->fence_bo); - nouveau_grobj_free(&dec->mpeg); + + nouveau_object_del(&dec->mpeg); + + if (dec->bufctx) + nouveau_bufctx_del(&dec->bufctx); + if (dec->push) + nouveau_pushbuf_del(&dec->push); + if (dec->client) + nouveau_client_del(&dec->client); + if (dec->chan) + nouveau_object_del(&dec->chan); + FREE(dec); } @@ -499,9 +512,10 @@ nouveau_create_decoder(struct pipe_context *context, unsigned width, unsigned height, unsigned max_references, bool expect_chunked_decode) { - struct nouveau_channel *chan = screen->channel; - struct nouveau_grobj *mpeg = NULL; + struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 }; + struct nouveau_object *mpeg = NULL; struct nouveau_decoder *dec; + struct nouveau_pushbuf *push; int ret; bool is8274 = screen->device->chipset > 0x80; @@ -515,23 +529,40 @@ nouveau_create_decoder(struct pipe_context *context, if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0) goto vl; + dec = CALLOC_STRUCT(nouveau_decoder); + if (!dec) + return NULL; + + ret = nouveau_object_new(&screen->device->object, 0, + NOUVEAU_FIFO_CHANNEL_CLASS, + &nv04_data, sizeof(nv04_data), &dec->chan); + if (ret) + goto fail; + ret = nouveau_client_new(screen->device, &dec->client); + if (ret) + goto fail; + ret = nouveau_pushbuf_new(dec->client, dec->chan, 2, 4096, 1, &dec->push); + if (ret) + goto fail; + ret = nouveau_bufctx_new(dec->client, NV31_VIDEO_BIND_COUNT, &dec->bufctx); + if (ret) + goto fail; + push = dec->push; + width = align(width, 64); height = align(height, 64); if (is8274) - ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x8274, &mpeg); + ret = nouveau_object_new(dec->chan, 0xbeef8274, NV84_MPEG_CLASS, NULL, 0, + &mpeg); else - ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x3174, &mpeg); + ret = nouveau_object_new(dec->chan, 0xbeef3174, NV31_MPEG_CLASS, NULL, 0, + &mpeg); if (ret < 0) { debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret); return NULL; } - dec = CALLOC_STRUCT(nouveau_decoder); - if (!dec) { - nouveau_grobj_free(&mpeg); - goto fail; - } dec->mpeg = mpeg; dec->base.context = context; dec->base.profile = profile; @@ -543,61 +574,67 @@ nouveau_create_decoder(struct pipe_context *context, dec->base.destroy = nouveau_decoder_destroy; dec->base.begin_frame = nouveau_decoder_begin_frame; dec->base.decode_macroblock = nouveau_decoder_decode_macroblock; - dec->base.begin_frame = nouveau_decoder_end_frame; + dec->base.end_frame = nouveau_decoder_end_frame; dec->base.flush = nouveau_decoder_flush; dec->screen = screen; - ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, 1024 * 1024, &dec->cmd_bo); + ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0, 1024 * 1024, NULL, &dec->cmd_bo); if (ret) goto fail; - ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, width * height * 6, &dec->data_bo); + ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0, width * height * 6, NULL, &dec->data_bo); if (ret) goto fail; - ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP, 0, 4096, - &dec->fence_bo); + /* we don't need the fence, the kernel sync's for us */ +#if 0 + ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0, 4096, NULL, &dec->fence_bo); if (ret) goto fail; - nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR); + nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, NULL); dec->fence_map = dec->fence_bo->map; - nouveau_bo_unmap(dec->fence_bo); dec->fence_map[0] = 0; +#endif - if (is8274) - MARK_RING(chan, 25, 3); - else - MARK_RING(chan, 20, 2); + nouveau_pushbuf_bufctx(dec->push, dec->bufctx); + nouveau_pushbuf_space(push, 32, 4, 0); - BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_CMD, 1); - OUT_RING(chan, chan->vram->handle); + BEGIN_NV04(push, SUBC_MPEG(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, dec->mpeg->handle); - BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_DATA, 1); - OUT_RING(chan, chan->vram->handle); + BEGIN_NV04(push, NV31_MPEG(DMA_CMD), 1); + PUSH_DATA (push, nv04_data.gart); - BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_IMAGE, 1); - OUT_RING(chan, chan->vram->handle); + BEGIN_NV04(push, NV31_MPEG(DMA_DATA), 1); + PUSH_DATA (push, nv04_data.gart); - BEGIN_RING(chan, mpeg, NV31_MPEG_PITCH, 2); - OUT_RING(chan, width | NV31_MPEG_PITCH_UNK); - OUT_RING(chan, (height << NV31_MPEG_SIZE_H__SHIFT) | width); + BEGIN_NV04(push, NV31_MPEG(DMA_IMAGE), 1); + PUSH_DATA (push, nv04_data.vram); - BEGIN_RING(chan, mpeg, NV31_MPEG_FORMAT, 2); - OUT_RING(chan, 0); + BEGIN_NV04(push, NV31_MPEG(PITCH), 2); + PUSH_DATA (push, width | NV31_MPEG_PITCH_UNK); + PUSH_DATA (push, (height << NV31_MPEG_SIZE_H__SHIFT) | width); + + BEGIN_NV04(push, NV31_MPEG(FORMAT), 2); + PUSH_DATA (push, 0); switch (entrypoint) { - case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: OUT_RING(chan, 0x100); break; - case PIPE_VIDEO_ENTRYPOINT_IDCT: OUT_RING(chan, 1); break; - case PIPE_VIDEO_ENTRYPOINT_MC: OUT_RING(chan, 0); break; + case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: PUSH_DATA (push, 0x100); break; + case PIPE_VIDEO_ENTRYPOINT_IDCT: PUSH_DATA (push, 1); break; + case PIPE_VIDEO_ENTRYPOINT_MC: PUSH_DATA (push, 0); break; default: assert(0); } if (is8274) { - BEGIN_RING(chan, mpeg, NV84_MPEG_DMA_QUERY, 1); - OUT_RING(chan, chan->vram->handle); - - BEGIN_RING(chan, mpeg, NV84_MPEG_QUERY_OFFSET, 2); - OUT_RELOCl(chan, dec->fence_bo, 0, NOUVEAU_BO_WR|NOUVEAU_BO_GART); - OUT_RING(chan, dec->fence_seq); + BEGIN_NV04(push, NV84_MPEG(DMA_QUERY), 1); + PUSH_DATA (push, nv04_data.vram); +#if 0 + BEGIN_NV04(push, NV84_MPEG(QUERY_OFFSET), 2); + PUSH_DATA (push, dec->fence_bo->offset); + PUSH_DATA (push, dec->fence_seq); +#endif } ret = nouveau_vpe_init(dec); diff --git a/src/gallium/drivers/nouveau/nouveau_video.h b/src/gallium/drivers/nouveau/nouveau_video.h index 22593ff9bbc..1d6ced035fb 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.h +++ b/src/gallium/drivers/nouveau/nouveau_video.h @@ -1,8 +1,11 @@ #ifndef __NOUVEAU_VIDEO_H__ -#define __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_VIDEO_H__ #include "nv17_mpeg.xml.h" #include "nv31_mpeg.xml.h" +#include "nv_object.xml.h" + +#include "nouveau_winsys.h" struct nouveau_video_buffer { struct pipe_video_buffer base; @@ -16,7 +19,11 @@ struct nouveau_video_buffer { struct nouveau_decoder { struct pipe_video_decoder base; struct nouveau_screen *screen; - struct nouveau_grobj *mpeg; + struct nouveau_pushbuf *push; + struct nouveau_object *chan; + struct nouveau_client *client; + struct nouveau_bufctx *bufctx; + struct nouveau_object *mpeg; struct nouveau_bo *cmd_bo, *data_bo, *fence_bo; unsigned *fence_map; @@ -34,9 +41,56 @@ struct nouveau_decoder { struct nouveau_video_buffer *surfaces[8]; }; +#define NV31_VIDEO_BIND_IMG(i) i +#define NV31_VIDEO_BIND_CMD NV31_MPEG_IMAGE_Y_OFFSET__LEN +#define NV31_VIDEO_BIND_COUNT (NV31_MPEG_IMAGE_Y_OFFSET__LEN + 1) + static INLINE void nouveau_vpe_write(struct nouveau_decoder *dec, unsigned data) { dec->cmds[dec->ofs++] = data; } +#define SUBC_MPEG(mthd) 1, mthd +#define NV31_MPEG(mthd) SUBC_MPEG(NV31_MPEG_##mthd) +#define NV84_MPEG(mthd) SUBC_MPEG(NV84_MPEG_##mthd) + +static INLINE uint32_t +NV04_FIFO_PKHDR(int subc, int mthd, unsigned size) +{ + return 0x00000000 | (size << 18) | (subc << 13) | mthd; +} + +static INLINE uint32_t +NV04_FIFO_PKHDR_NI(int subc, int mthd, unsigned size) +{ + return 0x40000000 | (size << 18) | (subc << 13) | mthd; +} + +static INLINE void +BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) +{ + PUSH_SPACE(push, size + 1); + PUSH_DATA (push, NV04_FIFO_PKHDR(subc, mthd, size)); +} + +static INLINE void +BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) +{ + PUSH_SPACE(push, size + 1); + PUSH_DATA (push, NV04_FIFO_PKHDR_NI(subc, mthd, size)); +} + +static INLINE void +PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd, + struct nouveau_bo *bo, uint32_t offset, + struct nouveau_bufctx *ctx, int bin, uint32_t rw) +{ + nouveau_bufctx_mthd(ctx, bin, NV04_FIFO_PKHDR(subc, mthd, 1), + bo, offset, + NOUVEAU_BO_LOW | (bo->flags & NOUVEAU_BO_APER) | rw, + 0, 0); + + PUSH_DATA(push, bo->offset + offset); +} + #endif diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 5c634771aff..9fb865e170d 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -6,19 +6,54 @@ #include "pipe/p_defines.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_notifier.h" -#ifndef NOUVEAU_NVC0 -#include "nouveau/nv04_pushbuf.h" -#endif +#include #ifndef NV04_PFIFO_MAX_PACKET_LEN #define NV04_PFIFO_MAX_PACKET_LEN 2047 #endif +static INLINE uint32_t +PUSH_AVAIL(struct nouveau_pushbuf *push) +{ + return push->end - push->cur; +} + +static INLINE boolean +PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size) +{ + if (PUSH_AVAIL(push) < size) + return nouveau_pushbuf_space(push, size, 0, 0) == 0; + return TRUE; +} + +static INLINE void +PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data) +{ + *push->cur++ = data; +} + +static INLINE void +PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size) +{ + memcpy(push->cur, data, size * 4); + push->cur += size; +} + +static INLINE void +PUSH_DATAf(struct nouveau_pushbuf *push, float f) +{ + union { float f; uint32_t i; } u; + u.f = f; + PUSH_DATA(push, u.i); +} + +static INLINE void +PUSH_KICK(struct nouveau_pushbuf *push) +{ + nouveau_pushbuf_kick(push, push->channel); +} + + #define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) #define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1) @@ -27,16 +62,14 @@ nouveau_screen_transfer_flags(unsigned pipe) { uint32_t flags = 0; - if (pipe & PIPE_TRANSFER_READ) - flags |= NOUVEAU_BO_RD; - if (pipe & PIPE_TRANSFER_WRITE) - flags |= NOUVEAU_BO_WR; - if (pipe & PIPE_TRANSFER_DISCARD_RANGE) - flags |= NOUVEAU_BO_INVAL; - if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED) - flags |= NOUVEAU_BO_NOSYNC; - else if (pipe & PIPE_TRANSFER_DONTBLOCK) - flags |= NOUVEAU_BO_NOWAIT; + if (!(pipe & PIPE_TRANSFER_UNSYNCHRONIZED)) { + if (pipe & PIPE_TRANSFER_READ) + flags |= NOUVEAU_BO_RD; + if (pipe & PIPE_TRANSFER_WRITE) + flags |= NOUVEAU_BO_WR; + if (pipe & PIPE_TRANSFER_DONTBLOCK) + flags |= NOUVEAU_BO_NOBLOCK; + } return flags; } diff --git a/src/gallium/drivers/nouveau/nv_m2mf.xml.h b/src/gallium/drivers/nouveau/nv_m2mf.xml.h index ffdaf95de62..dbc96a945ef 100644 --- a/src/gallium/drivers/nouveau/nv_m2mf.xml.h +++ b/src/gallium/drivers/nouveau/nv_m2mf.xml.h @@ -1,5 +1,5 @@ -#ifndef NV_M2MF_XML -#define NV_M2MF_XML +#ifndef RNNDB_NV_M2MF_XML +#define RNNDB_NV_M2MF_XML /* Autogenerated file, DO NOT EDIT manually! @@ -8,13 +8,14 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng git clone git://0x04.net/rules-ng-ng The rules-ng-ng source files this header was generated from are: -- nv_m2mf.xml ( 2710 bytes, from 2010-08-05 19:38:53) -- copyright.xml ( 6503 bytes, from 2010-04-10 23:15:50) -- nv_object.xml ( 10424 bytes, from 2010-08-05 19:38:53) -- nvchipsets.xml ( 2824 bytes, from 2010-08-05 19:38:53) -- nv_defs.xml ( 4437 bytes, from 2010-08-05 19:38:53) - -Copyright (C) 2006-2010 by the following authors: +- rnndb/nv_m2mf.xml ( 2696 bytes, from 2011-07-09 13:43:58) +- ./rnndb/copyright.xml ( 6452 bytes, from 2011-07-09 13:43:58) +- ./rnndb/nv_object.xml ( 12672 bytes, from 2011-07-17 12:14:32) +- ./rnndb/nvchipsets.xml ( 3701 bytes, from 2012-04-06 13:21:15) +- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-07-09 13:43:58) +- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-07-09 13:43:58) + +Copyright (C) 2006-2011 by the following authors: - Artur Huillet (ahuillet) - Ben Skeggs (darktama, darktama_) - B. R. (koala_br) @@ -25,7 +26,7 @@ Copyright (C) 2006-2010 by the following authors: - Dmitry Eremin-Solenikov (lumag) - EdB (edb_) - Erik Waling (erikwaling) -- Francisco Jerez (curro, curro_, currojerez) +- Francisco Jerez (curro) - imirkin (imirkin) - jb17bsome (jb17bsome) - Jeremy Kolb (kjeremy) @@ -36,7 +37,7 @@ Copyright (C) 2006-2010 by the following authors: - Mark Carey (careym) - Matthieu Castet (mat-c) - nvidiaman (nvidiaman) -- Patrice Mandin (pmandin, pmdata) +- Patrice Mandin (pmandin, pmdata) - Pekka Paalanen (pq, ppaalanen) - Peter Popov (ironpeter) - Richard Hughes (hughsient) @@ -74,11 +75,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -#define NV04_M2MF_DMA_NOTIFY 0x00000180 +#define NV03_M2MF_DMA_NOTIFY 0x00000180 -#define NV04_M2MF_DMA_BUFFER_IN 0x00000184 +#define NV03_M2MF_DMA_BUFFER_IN 0x00000184 -#define NV04_M2MF_DMA_BUFFER_OUT 0x00000188 +#define NV03_M2MF_DMA_BUFFER_OUT 0x00000188 #define NV50_M2MF_LINEAR_IN 0x00000200 @@ -121,35 +122,35 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_M2MF_OFFSET_OUT_HIGH 0x0000023c -#define NV04_M2MF_OFFSET_IN 0x0000030c +#define NV03_M2MF_OFFSET_IN 0x0000030c -#define NV04_M2MF_OFFSET_OUT 0x00000310 +#define NV03_M2MF_OFFSET_OUT 0x00000310 -#define NV04_M2MF_PITCH_IN 0x00000314 +#define NV03_M2MF_PITCH_IN 0x00000314 -#define NV04_M2MF_PITCH_OUT 0x00000318 +#define NV03_M2MF_PITCH_OUT 0x00000318 -#define NV04_M2MF_LINE_LENGTH_IN 0x0000031c +#define NV03_M2MF_LINE_LENGTH_IN 0x0000031c -#define NV04_M2MF_LINE_COUNT 0x00000320 +#define NV03_M2MF_LINE_COUNT 0x00000320 -#define NV04_M2MF_FORMAT 0x00000324 -#define NV04_M2MF_FORMAT_INPUT_INC__MASK 0x000000ff -#define NV04_M2MF_FORMAT_INPUT_INC__SHIFT 0 -#define NV04_M2MF_FORMAT_INPUT_INC_1 0x00000001 -#define NV04_M2MF_FORMAT_INPUT_INC_2 0x00000002 -#define NV04_M2MF_FORMAT_INPUT_INC_4 0x00000004 +#define NV03_M2MF_FORMAT 0x00000324 +#define NV03_M2MF_FORMAT_INPUT_INC__MASK 0x000000ff +#define NV03_M2MF_FORMAT_INPUT_INC__SHIFT 0 +#define NV03_M2MF_FORMAT_INPUT_INC_1 0x00000001 +#define NV03_M2MF_FORMAT_INPUT_INC_2 0x00000002 +#define NV03_M2MF_FORMAT_INPUT_INC_4 0x00000004 #define NV50_M2MF_FORMAT_INPUT_INC_8 0x00000008 #define NV50_M2MF_FORMAT_INPUT_INC_16 0x00000010 -#define NV04_M2MF_FORMAT_OUTPUT_INC__MASK 0x0000ff00 -#define NV04_M2MF_FORMAT_OUTPUT_INC__SHIFT 8 -#define NV04_M2MF_FORMAT_OUTPUT_INC_1 0x00000100 -#define NV04_M2MF_FORMAT_OUTPUT_INC_2 0x00000200 -#define NV04_M2MF_FORMAT_OUTPUT_INC_4 0x00000400 +#define NV03_M2MF_FORMAT_OUTPUT_INC__MASK 0x0000ff00 +#define NV03_M2MF_FORMAT_OUTPUT_INC__SHIFT 8 +#define NV03_M2MF_FORMAT_OUTPUT_INC_1 0x00000100 +#define NV03_M2MF_FORMAT_OUTPUT_INC_2 0x00000200 +#define NV03_M2MF_FORMAT_OUTPUT_INC_4 0x00000400 #define NV50_M2MF_FORMAT_OUTPUT_INC_8 0x00000800 #define NV50_M2MF_FORMAT_OUTPUT_INC_16 0x00001000 -#define NV04_M2MF_BUF_NOTIFY 0x00000328 +#define NV03_M2MF_BUF_NOTIFY 0x00000328 -#endif /* NV_M2MF_XML */ +#endif /* RNNDB_NV_M2MF_XML */ diff --git a/src/gallium/drivers/nouveau/nv_object.xml.h b/src/gallium/drivers/nouveau/nv_object.xml.h index 47dc6751041..d87d7139bf3 100644 --- a/src/gallium/drivers/nouveau/nv_object.xml.h +++ b/src/gallium/drivers/nouveau/nv_object.xml.h @@ -1,5 +1,10 @@ -#ifndef NV_OBJECT_XML -#define NV_OBJECT_XML +#ifndef RNNDB_NV_OBJECT_XML +#define RNNDB_NV_OBJECT_XML + +/* WARNING ABOUT NOT EDITING AUTOGENERATED FILE IGNORED, _CLASS SUFFIX HAS + * BEEN ADDED TO ALL THE OBJECT CLASS DEFINITIONS TO AVOID CONFLICTS WITH + * THE RING MACROS WE WANT TO USE + */ /* Autogenerated file, DO NOT EDIT manually! @@ -8,12 +13,13 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng git clone git://0x04.net/rules-ng-ng The rules-ng-ng source files this header was generated from are: -- nv_object.xml ( 11547 bytes, from 2010-10-24 15:29:34) -- copyright.xml ( 6498 bytes, from 2010-10-03 13:18:37) -- nvchipsets.xml ( 2907 bytes, from 2010-10-15 16:28:21) -- nv_defs.xml ( 4437 bytes, from 2010-07-06 07:43:58) +- rnndb/nv_object.xml ( 12672 bytes, from 2011-07-17 12:14:32) +- ./rnndb/copyright.xml ( 6452 bytes, from 2011-07-09 13:43:58) +- ./rnndb/nvchipsets.xml ( 3701 bytes, from 2012-04-06 13:21:15) +- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-07-09 13:43:58) +- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-07-09 13:43:58) -Copyright (C) 2006-2010 by the following authors: +Copyright (C) 2006-2011 by the following authors: - Artur Huillet (ahuillet) - Ben Skeggs (darktama, darktama_) - B. R. (koala_br) @@ -24,7 +30,7 @@ Copyright (C) 2006-2010 by the following authors: - Dmitry Eremin-Solenikov (lumag) - EdB (edb_) - Erik Waling (erikwaling) -- Francisco Jerez (curro, curro_, currojerez) +- Francisco Jerez (curro) - imirkin (imirkin) - jb17bsome (jb17bsome) - Jeremy Kolb (kjeremy) @@ -72,114 +78,129 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define NV01_ROOT 0x00000001 -#define NV01_CONTEXT_DMA 0x00000002 -#define NV01_DEVICE 0x00000003 -#define NV01_TIMER 0x00000004 -#define NV01_NULL 0x00000030 -#define NV01_MEMORY_LOCAL_BANKED 0x0000003d -#define NV01_MAPPING_SYSTEM 0x0000003e -#define NV03_MEMORY_LOCAL_CURSOR 0x0000003f -#define NV01_MEMORY_LOCAL_LINEAR 0x00000040 -#define NV01_MAPPING_LOCAL 0x00000041 -#define NV03_VIDEO_LUT_CURSOR_DAC 0x00000046 -#define NV03_CHANNEL_PIO 0x0000006a -#define NV03_CHANNEL_DMA 0x0000006b -#define NV10_VIDEO_DISPLAY 0x0000007c -#define NV01_CONTEXT_BETA1 0x00000012 -#define NV04_BETA_SOLID 0x00000072 -#define NV01_CONTEXT_COLOR_KEY 0x00000017 -#define NV04_CONTEXT_COLOR_KEY 0x00000057 -#define NV01_CONTEXT_PATTERN 0x00000018 -#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019 -#define NV03_CONTEXT_ROP 0x00000043 -#define NV04_IMAGE_PATTERN 0x00000044 -#define NV01_RENDER_SOLID_LINE 0x0000001c -#define NV04_RENDER_SOLID_LINE 0x0000005c -#define NV30_RENDER_SOLID_LINE 0x0000035c -#define NV40_RENDER_SOLID_LINE 0x0000305c -#define NV01_RENDER_SOLID_TRIANGLE 0x0000001d -#define NV04_RENDER_SOLID_TRIANGLE 0x0000005d -#define NV01_RENDER_SOLID_RECTANGLE 0x0000001e -#define NV04_RENDER_SOLID_RECTANGLE 0x0000005e -#define NV01_IMAGE_BLIT 0x0000001f -#define NV04_IMAGE_BLIT 0x0000005f -#define NV11_IMAGE_BLIT 0x0000009f -#define NV01_IMAGE_FROM_CPU 0x00000021 -#define NV04_IMAGE_FROM_CPU 0x00000061 -#define NV05_IMAGE_FROM_CPU 0x00000065 -#define NV10_IMAGE_FROM_CPU 0x0000008a -#define NV30_IMAGE_FROM_CPU 0x0000038a -#define NV40_IMAGE_FROM_CPU 0x0000308a -#define NV03_STRETCHED_IMAGE_FROM_CPU 0x00000036 -#define NV04_STRETCHED_IMAGE_FROM_CPU 0x00000076 -#define NV05_STRETCHED_IMAGE_FROM_CPU 0x00000066 -#define NV30_STRETCHED_IMAGE_FROM_CPU 0x00000366 -#define NV40_STRETCHED_IMAGE_FROM_CPU 0x00003066 -#define NV03_SCALED_IMAGE_FROM_MEMORY 0x00000037 -#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077 -#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063 -#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089 -#define NV30_SCALED_IMAGE_FROM_MEMORY 0x00000389 -#define NV40_SCALED_IMAGE_FROM_MEMORY 0x00003089 -#define NV50_SCALED_IMAGE_FROM_MEMORY 0x00005089 -#define NV04_DVD_SUBPICTURE 0x00000038 -#define NV10_DVD_SUBPICTURE 0x00000088 -#define NV03_GDI_RECTANGLE_TEXT 0x0000004b -#define NV04_GDI_RECTANGLE_TEXT 0x0000004a -#define NV04_SWIZZLED_SURFACE 0x00000052 -#define NV11_SWIZZLED_SURFACE 0x0000009e -#define NV30_SWIZZLED_SURFACE 0x0000039e -#define NV40_SWIZZLED_SURFACE 0x0000309e -#define NV03_CONTEXT_SURFACE_DST 0x00000058 -#define NV03_CONTEXT_SURFACE_SRC 0x00000059 -#define NV04_CONTEXT_SURFACES_2D 0x00000042 -#define NV10_CONTEXT_SURFACES_2D 0x00000062 -#define NV30_CONTEXT_SURFACES_2D 0x00000362 -#define NV40_CONTEXT_SURFACES_2D 0x00003062 -#define NV50_CONTEXT_SURFACES_2D 0x00005062 -#define NV04_INDEXED_IMAGE_FROM_CPU 0x00000060 -#define NV05_INDEXED_IMAGE_FROM_CPU 0x00000064 -#define NV30_INDEXED_IMAGE_FROM_CPU 0x00000364 -#define NV40_INDEXED_IMAGE_FROM_CPU 0x00003064 -#define NV10_TEXTURE_FROM_CPU 0x0000007b -#define NV30_TEXTURE_FROM_CPU 0x0000037b -#define NV40_TEXTURE_FROM_CPU 0x0000307b -#define NV04_M2MF 0x00000039 -#define NV50_M2MF 0x00005039 -#define NVC0_M2MF 0x00009039 -#define NV03_TEXTURED_TRIANGLE 0x00000048 -#define NV04_TEXTURED_TRIANGLE 0x00000054 -#define NV10_TEXTURED_TRIANGLE 0x00000094 -#define NV04_MULTITEX_TRIANGLE 0x00000055 -#define NV10_MULTITEX_TRIANGLE 0x00000095 -#define NV03_CONTEXT_SURFACE_COLOR 0x0000005a -#define NV03_CONTEXT_SURFACE_ZETA 0x0000005b -#define NV04_CONTEXT_SURFACES_3D 0x00000053 -#define NV10_CONTEXT_SURFACES_3D 0x00000093 -#define NV10_3D 0x00000056 -#define NV11_3D 0x00000096 -#define NV17_3D 0x00000099 -#define NV20_3D 0x00000097 -#define NV25_3D 0x00000597 -#define NV30_3D 0x00000397 -#define NV35_3D 0x00000497 -#define NV34_3D 0x00000697 -#define NV40_3D 0x00004097 -#define NV44_3D 0x00004497 -#define NV50_3D 0x00005097 -#define NV84_3D 0x00008297 -#define NVA0_3D 0x00008397 -#define NVA3_3D 0x00008597 -#define NVAF_3D 0x00008697 -#define NVC0_3D 0x00009097 -#define NV50_2D 0x0000502d -#define NVC0_2D 0x0000902d -#define NV50_COMPUTE 0x000050c0 -#define NVA3_COMPUTE 0x000085c0 -#define NVC0_COMPUTE 0x000090c0 -#define NV84_CRYPT 0x000074c1 -#define NV01_SUBCHAN__SIZE 0x00002000 +#define NV01_DMA_FROM_MEMORY_CLASS 0x00000002 +#define NV01_DMA_TO_MEMORY_CLASS 0x00000003 +#define NV01_NULL_CLASS 0x00000030 +#define NV03_DMA_IN_MEMORY_CLASS 0x0000003d +#define NV01_OP_CLIP_CLASS 0x00000010 +#define NV01_OP_BLEND_AND_CLASS 0x00000011 +#define NV01_BETA_CLASS 0x00000012 +#define NV04_BETA4_CLASS 0x00000072 +#define NV01_OP_ROP_AND_CLASS 0x00000013 +#define NV01_ROP_CLASS 0x00000014 +#define NV03_ROP_CLASS 0x00000043 +#define NV01_OP_CHROMA_CLASS 0x00000015 +#define NV01_OP_PLANE_SWITCH_CLASS 0x00000016 +#define NV01_CHROMA_CLASS 0x00000017 +#define NV04_CHROMA_CLASS 0x00000057 +#define NV01_PATTERN_CLASS 0x00000018 +#define NV04_PATTERN_CLASS 0x00000044 +#define NV01_CLIP_CLASS 0x00000019 +#define NV01_OP_SRCCOPY_AND_CLASS 0x00000064 +#define NV03_OP_SRCCOPY_CLASS 0x00000065 +#define NV04_OP_SRCCOPY_PREMULT_CLASS 0x00000066 +#define NV04_OP_BLEND_PREMULT_CLASS 0x00000067 +#define NV01_POINT_CLASS 0x0000001a +#define NV01_LINE_CLASS 0x0000001b +#define NV01_LIN_CLASS 0x0000001c +#define NV04_LIN_CLASS 0x0000005c +#define NV30_LIN_CLASS 0x0000035c +#define NV40_LIN_CLASS 0x0000305c +#define NV01_TRI_CLASS 0x0000001d +#define NV04_TRI_CLASS 0x0000005d +#define NV01_RECT_CLASS 0x0000001e +#define NV04_RECT_CLASS 0x0000005e +#define NV01_BLIT_CLASS 0x0000001f +#define NV04_BLIT_CLASS 0x0000005f +#define NV15_BLIT_CLASS 0x0000009f +#define NV01_IFROMMEM_CLASS 0x00000020 +#define NV01_IFC_CLASS 0x00000021 +#define NV04_IFC_CLASS 0x00000061 +#define NV05_IFC_CLASS 0x00000065 +#define NV10_IFC_CLASS 0x0000008a +#define NV30_IFC_CLASS 0x0000038a +#define NV40_IFC_CLASS 0x0000308a +#define NV01_BITMAP_CLASS 0x00000022 +#define NV01_ITOMEM_CLASS 0x00000025 +#define NV03_SIFC_CLASS 0x00000036 +#define NV04_SIFC_CLASS 0x00000076 +#define NV05_SIFC_CLASS 0x00000066 +#define NV30_SIFC_CLASS 0x00000366 +#define NV40_SIFC_CLASS 0x00003066 +#define NV03_SIFM_CLASS 0x00000037 +#define NV04_SIFM_CLASS 0x00000077 +#define NV05_SIFM_CLASS 0x00000063 +#define NV10_SIFM_CLASS 0x00000089 +#define NV30_SIFM_CLASS 0x00000389 +#define NV40_SIFM_CLASS 0x00003089 +#define NV50_SIFM_CLASS 0x00005089 +#define NV03_SYFM_CLASS 0x00000038 +#define NV03_GDI_CLASS 0x0000004b +#define NV04_GDI_CLASS 0x0000004a +#define NV04_SURFACE_SWZ_CLASS 0x00000052 +#define NV20_SURFACE_SWZ_CLASS 0x0000009e +#define NV30_SURFACE_SWZ_CLASS 0x0000039e +#define NV40_SURFACE_SWZ_CLASS 0x0000309e +#define NV03_SURFACE_DST_CLASS 0x00000058 +#define NV03_SURFACE_SRC_CLASS 0x00000059 +#define NV04_SURFACE_2D_CLASS 0x00000042 +#define NV10_SURFACE_2D_CLASS 0x00000062 +#define NV30_SURFACE_2D_CLASS 0x00000362 +#define NV40_SURFACE_2D_CLASS 0x00003062 +#define NV50_SURFACE_2D_CLASS 0x00005062 +#define NV04_INDEX_CLASS 0x00000060 +#define NV05_INDEX_CLASS 0x00000064 +#define NV30_INDEX_CLASS 0x00000364 +#define NV40_INDEX_CLASS 0x00003064 +#define NV10_TEXUPLOAD_CLASS 0x0000007b +#define NV30_TEXUPLOAD_CLASS 0x0000037b +#define NV40_TEXUPLOAD_CLASS 0x0000307b +#define NV04_DVD_SUBPICTURE_CLASS 0x00000038 +#define NV10_DVD_SUBPICTURE_CLASS 0x00000088 +#define NV03_M2MF_CLASS 0x00000039 +#define NV50_M2MF_CLASS 0x00005039 +#define NVC0_M2MF_CLASS 0x00009039 +#define NV03_SURFACE_COLOR_CLASS 0x0000005a +#define NV03_SURFACE_ZETA_CLASS 0x0000005b +#define NV03_TEXTURED_TRIANGLE_CLASS 0x00000048 +#define NV04_TEXTURED_TRIANGLE_CLASS 0x00000054 +#define NV10_TEXTURED_TRIANGLE_CLASS 0x00000094 +#define NV04_SURFACE_3D_CLASS 0x00000053 +#define NV10_SURFACE_3D_CLASS 0x00000093 +#define NV04_MULTITEX_TRIANGLE_CLASS 0x00000055 +#define NV10_MULTITEX_TRIANGLE_CLASS 0x00000095 +#define NV10_3D_CLASS 0x00000056 +#define NV15_3D_CLASS 0x00000096 +#define NV11_3D_CLASS 0x00000098 +#define NV17_3D_CLASS 0x00000099 +#define NV20_3D_CLASS 0x00000097 +#define NV25_3D_CLASS 0x00000597 +#define NV30_3D_CLASS 0x00000397 +#define NV35_3D_CLASS 0x00000497 +#define NV34_3D_CLASS 0x00000697 +#define NV40_3D_CLASS 0x00004097 +#define NV44_3D_CLASS 0x00004497 +#define NV50_3D_CLASS 0x00005097 +#define NV84_3D_CLASS 0x00008297 +#define NVA0_3D_CLASS 0x00008397 +#define NVA3_3D_CLASS 0x00008597 +#define NVAF_3D_CLASS 0x00008697 +#define NVC0_3D_CLASS 0x00009097 +#define NVC1_3D_CLASS 0x00009197 +#define NVC8_3D_CLASS 0x00009297 +#define NV50_2D_CLASS 0x0000502d +#define NVC0_2D_CLASS 0x0000902d +#define NV50_COMPUTE_CLASS 0x000050c0 +#define NVA3_COMPUTE_CLASS 0x000085c0 +#define NVC0_COMPUTE_CLASS 0x000090c0 +#define NVC8_COMPUTE_CLASS 0x000092c0 +#define NV84_CRYPT_CLASS 0x000074c1 +#define BLOB_NVC0_PCOPY1_CLASS 0x000090b8 +#define BLOB_NVC0_PCOPY0_CLASS 0x000090b5 +#define NV31_MPEG_CLASS 0x00003174 +#define NV84_MPEG_CLASS 0x00008274 + +#define NV01_SUBCHAN__SIZE 0x00008000 #define NV01_SUBCHAN 0x00000000 #define NV01_SUBCHAN_OBJECT 0x00000000 @@ -217,55 +238,64 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV04_GRAPH_NOP 0x00000100 -#define NV01_GRAPH_NOTIFY 0x00000104 -#define NV01_GRAPH_NOTIFY_WRITE 0x00000000 -#define NV01_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001 - -#define NV50_GRAPH_WAIT_FOR_IDLE 0x00000110 +#define NV04_GRAPH_NOTIFY 0x00000104 +#define NV04_GRAPH_NOTIFY_WRITE 0x00000000 +#define NV04_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001 -#define NVA3_GRAPH_UNK0120 0x00000120 +#define NVC0_GRAPH_NOTIFY_ADDRESS_HIGH 0x00000104 -#define NVA3_GRAPH_UNK0124 0x00000124 +#define NVC0_GRAPH_NOTIFY_ADDRESS_LOW 0x00000108 -#define NV40_GRAPH_PM_TRIGGER 0x00000140 +#define NVC0_GRAPH_NOTIFY 0x0000010c +#define NVC0_GRAPH_NOTIFY_WRITE 0x00000000 +#define NVC0_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001 -#define NVC0_SUBCHAN__SIZE 0x00008000 -#define NVC0_SUBCHAN 0x00000000 +#define NV50_GRAPH_SERIALIZE 0x00000110 -#define NVC0_SUBCHAN_OBJECT 0x00000000 +#define NVC0_GRAPH_MACRO_UPLOAD_POS 0x00000114 +#define NVC0_GRAPH_MACRO_UPLOAD_DATA 0x00000118 -#define NVC0_SUBCHAN_QUERY_ADDRESS_HIGH 0x00000010 +#define NVC0_GRAPH_MACRO_ID 0x0000011c -#define NVC0_SUBCHAN_QUERY_ADDRESS_LOW 0x00000014 +#define NVC0_GRAPH_MACRO_POS 0x00000120 -#define NVC0_SUBCHAN_QUERY_SEQUENCE 0x00000018 +#define NVA3_GRAPH_UNK0120 0x00000120 -#define NVC0_SUBCHAN_QUERY_GET 0x0000001c +#define NVA3_GRAPH_UNK0124 0x00000124 -#define NVC0_SUBCHAN_REF_CNT 0x00000050 +#define NVC0_GRAPH_UNK0124 0x00000124 -#define NVC0_GRAPH 0x00000000 +#define NVC0_GRAPH_COND_ADDRESS_HIGH 0x00000130 -#define NVC0_GRAPH_NOP 0x00000100 +#define NVC0_GRAPH_COND_ADDRESS_LOW 0x00000134 -#define NVC0_GRAPH_NOTIFY_ADDRESS_HIGH 0x00000104 +#define NVC0_GRAPH_COND_MODE 0x00000138 +#define NVC0_GRAPH_COND_MODE_NEVER 0x00000000 +#define NVC0_GRAPH_COND_MODE_ALWAYS 0x00000001 +#define NVC0_GRAPH_COND_MODE_RES_NON_ZERO 0x00000002 +#define NVC0_GRAPH_COND_MODE_EQUAL 0x00000003 +#define NVC0_GRAPH_COND_MODE_NOT_EQUAL 0x00000004 -#define NVC0_GRAPH_NOTIFY_ADDRESS_LOW 0x00000108 +#define NVC0_GRAPH_UNK013C 0x0000013c -#define NVC0_GRAPH_NOTIFY 0x0000010c -#define NVC0_GRAPH_NOTIFY_WRITE 0x00000000 -#define NVC0_GRAPH_NOTIFY_WRITE_AND_AWAKEN 0x00000001 +#define NV40_GRAPH_PM_TRIGGER 0x00000140 -#define NVC0_GRAPH_SERIALIZE 0x00000110 +#define NVC0_GRAPH_UNK0150 0x00000150 -#define NVC0_GRAPH_MACRO_UPLOAD_POS 0x00000114 +#define NVC0_GRAPH_UNK0154 0x00000154 -#define NVC0_GRAPH_MACRO_UPLOAD_DATA 0x00000118 +#define NVC0_GRAPH_SCRATCH(i0) (0x00003400 + 0x4*(i0)) +#define NVC0_GRAPH_SCRATCH__ESIZE 0x00000004 +#define NVC0_GRAPH_SCRATCH__LEN 0x00000080 -#define NVC0_GRAPH_MACRO_ID 0x0000011c +#define NVC0_GRAPH_MACRO(i0) (0x00003800 + 0x8*(i0)) +#define NVC0_GRAPH_MACRO__ESIZE 0x00000008 +#define NVC0_GRAPH_MACRO__LEN 0x00000080 -#define NVC0_GRAPH_MACRO_POS 0x00000120 +#define NVC0_GRAPH_MACRO_PARAM(i0) (0x00003804 + 0x8*(i0)) +#define NVC0_GRAPH_MACRO_PARAM__ESIZE 0x00000008 +#define NVC0_GRAPH_MACRO_PARAM__LEN 0x00000080 -#endif /* NV_OBJECT_XML */ +#endif /* RNNDB_NV_OBJECT_XML */ diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h index 0f5a77de9a1..9dff8b2dd13 100644 --- a/src/gallium/drivers/nv50/nv50_3d.xml.h +++ b/src/gallium/drivers/nv50/nv50_3d.xml.h @@ -1,5 +1,5 @@ -#ifndef NV50_3D_XML -#define NV50_3D_XML +#ifndef RNNDB_NV50_3D_XML +#define RNNDB_NV50_3D_XML /* Autogenerated file, DO NOT EDIT manually! @@ -8,15 +8,15 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng git clone git://0x04.net/rules-ng-ng The rules-ng-ng source files this header was generated from are: -- nv50_3d.xml ( 64479 bytes, from 2011-02-27 17:58:08) -- copyright.xml ( 6452 bytes, from 2010-12-15 23:45:18) -- nv_defs.xml ( 4437 bytes, from 2010-12-15 23:45:18) -- nv50_defs.xml ( 4487 bytes, from 2010-12-15 23:45:18) -- nv_3ddefs.xml ( 16394 bytes, from 2010-12-15 23:45:18) -- nv_object.xml ( 12191 bytes, from 2011-02-27 17:58:08) -- nvchipsets.xml ( 3074 bytes, from 2011-02-27 17:58:08) - -Copyright (C) 2006-2011 by the following authors: +- rnndb/nv50_3d.xml ( 65226 bytes, from 2012-01-28 13:46:30) +- ./rnndb/copyright.xml ( 6452 bytes, from 2011-08-11 18:25:12) +- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-08-11 18:25:12) +- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-08-11 18:25:12) +- ./rnndb/nvchipsets.xml ( 3617 bytes, from 2011-08-11 18:25:12) +- ./rnndb/nv_3ddefs.xml ( 16394 bytes, from 2011-08-11 18:25:12) +- ./rnndb/nv_object.xml ( 12672 bytes, from 2011-08-11 18:25:12) + +Copyright (C) 2006-2012 by the following authors: - Artur Huillet (ahuillet) - Ben Skeggs (darktama, darktama_) - B. R. (koala_br) @@ -74,7 +74,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define NV50_3D_SERIALIZE 0x00000110 + #define NV50_3D_DMA_NOTIFY 0x00000180 @@ -592,9 +592,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_CLIPID_ADDRESS_LOW 0x00000fd0 -#define NV50_3D_MAP_SEMANTIC_5 0x00000fd4 -#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK 0x000000ff -#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT 0 +#define NV50_3D_SEMANTIC_VIEWPORT 0x00000fd4 +#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__MASK 0x000000ff +#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__SHIFT 0 #define NV50_3D_UNK0FD8 0x00000fd8 #define NV50_3D_UNK0FD8_UNK0 0x00000001 @@ -1184,7 +1184,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_BIND_TSC2__ESIZE 0x00000008 #define NV50_3D_BIND_TSC2__LEN 0x00000003 #define NV50_3D_BIND_TSC2_VALID 0x00000001 -#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x000000f0 +#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x00000010 #define NV50_3D_BIND_TSC2_SAMPLER__SHIFT 4 #define NV50_3D_BIND_TSC2_TSC__MASK 0x001ff000 #define NV50_3D_BIND_TSC2_TSC__SHIFT 12 @@ -1193,7 +1193,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_BIND_TIC2__ESIZE 0x00000008 #define NV50_3D_BIND_TIC2__LEN 0x00000003 #define NV50_3D_BIND_TIC2_VALID 0x00000001 -#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x000001fe +#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x00000002 #define NV50_3D_BIND_TIC2_TEXTURE__SHIFT 1 #define NV50_3D_BIND_TIC2_TIC__MASK 0x7ffffe00 #define NV50_3D_BIND_TIC2_TIC__SHIFT 9 @@ -1217,15 +1217,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK 0xffff0000 #define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT 16 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE 0x00001510 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0 0x00000001 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1 0x00000002 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2 0x00000004 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3 0x00000008 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4 0x00000010 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5 0x00000020 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6 0x00000040 -#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7 0x00000080 +#define NV50_3D_CLIP_DISTANCE_ENABLE 0x00001510 +#define NV50_3D_CLIP_DISTANCE_ENABLE_0 0x00000001 +#define NV50_3D_CLIP_DISTANCE_ENABLE_1 0x00000002 +#define NV50_3D_CLIP_DISTANCE_ENABLE_2 0x00000004 +#define NV50_3D_CLIP_DISTANCE_ENABLE_3 0x00000008 +#define NV50_3D_CLIP_DISTANCE_ENABLE_4 0x00000010 +#define NV50_3D_CLIP_DISTANCE_ENABLE_5 0x00000020 +#define NV50_3D_CLIP_DISTANCE_ENABLE_6 0x00000040 +#define NV50_3D_CLIP_DISTANCE_ENABLE_7 0x00000080 #define NV50_3D_SAMPLECNT_ENABLE 0x00001514 @@ -1391,9 +1391,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_MULTISAMPLE_MODE_MS8 0x00000003 #define NV50_3D_MULTISAMPLE_MODE_MS8_ALT 0x00000004 #define NV50_3D_MULTISAMPLE_MODE_MS2_ALT 0x00000005 +#define NV50_3D_MULTISAMPLE_MODE_UNK6 0x00000006 #define NV50_3D_MULTISAMPLE_MODE_MS4_CS4 0x00000008 #define NV50_3D_MULTISAMPLE_MODE_MS4_CS12 0x00000009 #define NV50_3D_MULTISAMPLE_MODE_MS8_CS8 0x0000000a +#define NV50_3D_MULTISAMPLE_MODE_MS8_CS24 0x0000000b #define NV50_3D_VERTEX_BEGIN_D3D 0x000015d4 #define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK 0x0fffffff @@ -1440,7 +1442,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_VERTEX_END_GL_UNK0 0x00000001 #define NVA0_3D_VERTEX_END_GL_UNK1 0x00000002 -#define NV50_3D_EDGEFLAG_ENABLE 0x000015e4 +#define NV50_3D_EDGEFLAG 0x000015e4 #define NV50_3D_VB_ELEMENT_U32 0x000015e8 @@ -1666,34 +1668,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_GP_VIEWPORT_ID_ENABLE 0x00001900 -#define NV50_3D_MAP_SEMANTIC_0 0x00001904 -#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK 0x000000ff -#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT 0 -#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK 0x0000ff00 -#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT 8 -#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK 0x00ff0000 -#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT 16 -#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN 0x01000000 - -#define NV50_3D_MAP_SEMANTIC_1 0x00001908 -#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK 0x000000ff -#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT 0 -#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK 0x00000f00 -#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT 8 - -#define NV50_3D_MAP_SEMANTIC_2 0x0000190c -#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK 0x000000ff -#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT 0 - -#define NV50_3D_MAP_SEMANTIC_3 0x00001910 -#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK 0x00000001 -#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT 0 -#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK 0x00000ff0 -#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT 4 - -#define NV50_3D_MAP_SEMANTIC_4 0x00001914 -#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK 0x000000ff -#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT 0 +#define NV50_3D_SEMANTIC_COLOR 0x00001904 +#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__MASK 0x000000ff +#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT 0 +#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__MASK 0x0000ff00 +#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__SHIFT 8 +#define NV50_3D_SEMANTIC_COLOR_COLR_NR__MASK 0x00ff0000 +#define NV50_3D_SEMANTIC_COLOR_COLR_NR__SHIFT 16 +#define NV50_3D_SEMANTIC_COLOR_CLMP_EN 0x01000000 + +#define NV50_3D_SEMANTIC_CLIP 0x00001908 +#define NV50_3D_SEMANTIC_CLIP_CLIP_START__MASK 0x000000ff +#define NV50_3D_SEMANTIC_CLIP_CLIP_START__SHIFT 0 +#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__MASK 0x00000f00 +#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__SHIFT 8 + +#define NV50_3D_SEMANTIC_LAYER 0x0000190c +#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__MASK 0x000000ff +#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__SHIFT 0 + +#define NV50_3D_SEMANTIC_PTSZ 0x00001910 +#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK 0x00000001 +#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__SHIFT 0 +#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__MASK 0x00000ff0 +#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__SHIFT 4 + +#define NV50_3D_SEMANTIC_PRIM_ID 0x00001914 +#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__MASK 0x000000ff +#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__SHIFT 0 #define NV50_3D_CULL_FACE_ENABLE 0x00001918 @@ -1729,15 +1731,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1 0x00001000 #define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2 0x00002000 -#define NV50_3D_UNK1940 0x00001940 -#define NV50_3D_UNK1940_0 0x00000001 -#define NV50_3D_UNK1940_1 0x00000010 -#define NV50_3D_UNK1940_2 0x00000100 -#define NV50_3D_UNK1940_3 0x00001000 -#define NV50_3D_UNK1940_4 0x00010000 -#define NV50_3D_UNK1940_5 0x00100000 -#define NV50_3D_UNK1940_6 0x01000000 -#define NV50_3D_UNK1940_7 0x10000000 +#define NV50_3D_CLIP_DISTANCE_MODE 0x00001940 +#define NV50_3D_CLIP_DISTANCE_MODE_0__MASK 0x00000001 +#define NV50_3D_CLIP_DISTANCE_MODE_0__SHIFT 0 +#define NV50_3D_CLIP_DISTANCE_MODE_0_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_0_CULL 0x00000001 +#define NV50_3D_CLIP_DISTANCE_MODE_1__MASK 0x00000010 +#define NV50_3D_CLIP_DISTANCE_MODE_1__SHIFT 4 +#define NV50_3D_CLIP_DISTANCE_MODE_1_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_1_CULL 0x00000010 +#define NV50_3D_CLIP_DISTANCE_MODE_2__MASK 0x00000100 +#define NV50_3D_CLIP_DISTANCE_MODE_2__SHIFT 8 +#define NV50_3D_CLIP_DISTANCE_MODE_2_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_2_CULL 0x00000100 +#define NV50_3D_CLIP_DISTANCE_MODE_3__MASK 0x00001000 +#define NV50_3D_CLIP_DISTANCE_MODE_3__SHIFT 12 +#define NV50_3D_CLIP_DISTANCE_MODE_3_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_3_CULL 0x00001000 +#define NV50_3D_CLIP_DISTANCE_MODE_4__MASK 0x00010000 +#define NV50_3D_CLIP_DISTANCE_MODE_4__SHIFT 16 +#define NV50_3D_CLIP_DISTANCE_MODE_4_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_4_CULL 0x00010000 +#define NV50_3D_CLIP_DISTANCE_MODE_5__MASK 0x00100000 +#define NV50_3D_CLIP_DISTANCE_MODE_5__SHIFT 20 +#define NV50_3D_CLIP_DISTANCE_MODE_5_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_5_CULL 0x00100000 +#define NV50_3D_CLIP_DISTANCE_MODE_6__MASK 0x01000000 +#define NV50_3D_CLIP_DISTANCE_MODE_6__SHIFT 24 +#define NV50_3D_CLIP_DISTANCE_MODE_6_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_6_CULL 0x01000000 +#define NV50_3D_CLIP_DISTANCE_MODE_7__MASK 0x10000000 +#define NV50_3D_CLIP_DISTANCE_MODE_7__SHIFT 28 +#define NV50_3D_CLIP_DISTANCE_MODE_7_CLIP 0x00000000 +#define NV50_3D_CLIP_DISTANCE_MODE_7_CULL 0x10000000 #define NVA3_3D_UNK1944 0x00001944 @@ -2048,7 +2074,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVA3_3D_IBLEND__ESIZE 0x00000020 #define NVA3_3D_IBLEND__LEN 0x00000008 -#define NVA3_3D_IBLEND_UNK00(i0) (0x00001e00 + 0x20*(i0)) +#define NVA3_3D_IBLEND_SEPARATE_ALPHA(i0) (0x00001e00 + 0x20*(i0)) #define NVA3_3D_IBLEND_EQUATION_RGB(i0) (0x00001e04 + 0x20*(i0)) #define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD 0x00008006 @@ -2081,4 +2107,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN 0x00000020 -#endif /* NV50_3D_XML */ +#endif /* RNNDB_NV50_3D_XML */ diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 3b0f8f07d1c..88eb4bb246c 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -33,40 +33,36 @@ static void nv50_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { - struct nouveau_screen *screen = &nv50_context(pipe)->screen->base; + struct nouveau_screen *screen = nouveau_screen(pipe->screen); if (fence) nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); - /* Try to emit before firing to avoid having to flush again right after - * in case we have to wait on this fence. - */ - nouveau_fence_emit(screen->fence.current); - - FIRE_RING(screen->channel); + PUSH_KICK(screen->pushbuf); } static void nv50_texture_barrier(struct pipe_context *pipe) { - struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel; + struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf; - BEGIN_RING(chan, RING_3D(SERIALIZE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0x20); + BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 0x20); } void -nv50_default_flush_notify(struct nouveau_channel *chan) +nv50_default_kick_notify(struct nouveau_pushbuf *push) { - struct nv50_screen *screen = chan->user_private; - - if (!screen) - return; + struct nv50_screen *screen = push->user_priv; - nouveau_fence_update(&screen->base, TRUE); - nouveau_fence_next(&screen->base); + if (screen) { + nouveau_fence_next(&screen->base); + nouveau_fence_update(&screen->base, TRUE); + if (screen->cur_ctx) + screen->cur_ctx->state.flushed = TRUE; + } } static void @@ -74,8 +70,8 @@ nv50_context_unreference_resources(struct nv50_context *nv50) { unsigned s, i; - for (i = 0; i < NV50_BUFCTX_COUNT; ++i) - nv50_bufctx_reset(nv50, i); + nouveau_bufctx_del(&nv50->bufctx_3d); + nouveau_bufctx_del(&nv50->bufctx); for (i = 0; i < nv50->num_vtxbufs; ++i) pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); @@ -96,13 +92,18 @@ nv50_destroy(struct pipe_context *pipe) { struct nv50_context *nv50 = nv50_context(pipe); + if (nv50_context_screen(nv50)->cur_ctx == nv50) { + nv50->base.pushbuf->kick_notify = NULL; + nv50_context_screen(nv50)->cur_ctx = NULL; + nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL); + } + /* need to flush before destroying the bufctx */ + nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel); + nv50_context_unreference_resources(nv50); draw_destroy(nv50->draw); - if (nv50->screen->cur_ctx == nv50) - nv50->screen->cur_ctx = NULL; - FREE(nv50); } @@ -112,17 +113,28 @@ nv50_create(struct pipe_screen *pscreen, void *priv) struct nv50_screen *screen = nv50_screen(pscreen); struct nv50_context *nv50; struct pipe_context *pipe; + int ret; + uint32_t flags; nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; pipe = &nv50->base.pipe; - nv50->screen = screen; + nv50->base.pushbuf = screen->base.pushbuf; + + ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT, + &nv50->bufctx_3d); + if (!ret) + ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx); + if (ret) + goto out_err; + nv50->base.screen = &screen->base; nv50->base.copy_data = nv50_m2mf_copy_linear; nv50->base.push_data = nv50_sifc_linear_u8; + nv50->screen = screen; pipe->screen = pscreen; pipe->priv = priv; @@ -134,9 +146,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv) pipe->flush = nv50_flush; pipe->texture_barrier = nv50_texture_barrier; - if (!screen->cur_ctx) + if (!screen->cur_ctx) { screen->cur_ctx = nv50; - screen->base.channel->flush_notify = nv50_default_flush_notify; + nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx); + } nv50_init_query_functions(nv50); nv50_init_surface_functions(nv50); @@ -149,72 +162,41 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nouveau_context_init_vdec(&nv50->base); - return pipe; -} + flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; -struct resident { - struct nv04_resource *res; - uint32_t flags; -}; + BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code); + BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms); + BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc); + BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo); -void -nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, - struct nv04_resource *resource, uint32_t flags) -{ - struct resident rsd = { resource, flags }; + flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR; - if (!resource->bo) - return; - nv50->residents_size += sizeof(struct resident); + BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo); + BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo); - /* We don't need to reference the resource here, it will be referenced - * in the context/state, and bufctx will be reset when state changes. - */ - util_dynarray_append(&nv50->residents[ctx], struct resident, rsd); -} + return pipe; -void -nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx, - struct nv04_resource *resource) -{ - struct resident *rsd, *top; - unsigned i; - - for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) { - rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i); - - if (rsd->res == resource) { - top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident); - if (rsd != top) - *rsd = *top; - nv50->residents_size -= sizeof(struct resident); - break; - } +out_err: + if (nv50) { + if (nv50->bufctx_3d) + nouveau_bufctx_del(&nv50->bufctx_3d); + if (nv50->bufctx) + nouveau_bufctx_del(&nv50->bufctx); + FREE(nv50); } + return NULL; } void -nv50_bufctx_emit_relocs(struct nv50_context *nv50) +nv50_bufctx_fence(struct nouveau_bufctx *bufctx, boolean on_flush) { - struct resident *rsd; - struct util_dynarray *array; - unsigned ctx, i, n; - - n = nv50->residents_size / sizeof(struct resident); - n += NV50_SCREEN_RESIDENT_BO_COUNT; - - MARK_RING(nv50->screen->base.channel, 0, n); - - for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) { - array = &nv50->residents[ctx]; - - n = array->size / sizeof(struct resident); - for (i = 0; i < n; ++i) { - rsd = util_dynarray_element(array, struct resident, i); - - nv50_resource_validate(rsd->res, rsd->flags); - } + struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending; + struct nouveau_list *it; + + for (it = list->next; it != list; it = it->next) { + struct nouveau_bufref *ref = (struct nouveau_bufref *)it; + struct nv04_resource *res = ref->priv; + if (res) + nv50_resource_validate(res, (unsigned)ref->priv_data); } - - nv50_screen_make_buffers_resident(nv50->screen); } diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 2bf634a8237..0dd6c16bb48 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -46,12 +46,20 @@ #define NV50_NEW_CONSTBUF (1 << 18) #define NV50_NEW_TEXTURES (1 << 19) #define NV50_NEW_SAMPLERS (1 << 20) - -#define NV50_BUFCTX_CONSTANT 0 -#define NV50_BUFCTX_FRAME 1 -#define NV50_BUFCTX_VERTEX 2 -#define NV50_BUFCTX_TEXTURES 3 -#define NV50_BUFCTX_COUNT 4 +#define NV50_NEW_CONTEXT (1 << 31) + +#define NV50_BIND_FB 0 +#define NV50_BIND_VERTEX 1 +#define NV50_BIND_VERTEX_TMP 2 +#define NV50_BIND_INDEX 3 +#define NV50_BIND_TEXTURES 4 +#define NV50_BIND_CB(s, i) (5 + 16 * (s) + (i)) +#define NV50_BIND_SCREEN 53 +#define NV50_BIND_TLS 54 +#define NV50_BIND_COUNT 55 +#define NV50_BIND_2D 0 +#define NV50_BIND_M2MF 0 +#define NV50_BIND_FENCE 1 #define NV50_CB_TMP 123 /* fixed constant buffer binding points - low indices for user's constbufs */ @@ -60,13 +68,14 @@ #define NV50_CB_PFP 125 #define NV50_CB_AUX 127 + struct nv50_context { struct nouveau_context base; struct nv50_screen *screen; - struct util_dynarray residents[NV50_BUFCTX_COUNT]; - unsigned residents_size; + struct nouveau_bufctx *bufctx_3d; + struct nouveau_bufctx *bufctx; uint32_t dirty; @@ -79,6 +88,9 @@ struct nv50_context { int32_t index_bias; boolean prim_restart; boolean point_sprite; + boolean rt_serialize; + boolean flushed; + uint8_t tls_required; uint8_t num_vtxbufs; uint8_t num_vtxelts; uint8_t num_textures[3]; @@ -97,6 +109,7 @@ struct nv50_context { struct pipe_resource *constbuf[3][16]; uint16_t constbuf_dirty[3]; + uint16_t constbuf_valid[3]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned num_vtxbufs; @@ -132,22 +145,19 @@ nv50_context(struct pipe_context *pipe) return (struct nv50_context *)pipe; } +static INLINE struct nv50_screen * +nv50_context_screen(struct nv50_context *nv50) +{ + return nv50_screen(&nv50->base.screen->base); +} + + /* nv50_context.c */ struct pipe_context *nv50_create(struct pipe_screen *, void *); -void nv50_default_flush_notify(struct nouveau_channel *); +void nv50_bufctx_fence(struct nouveau_bufctx *, boolean on_flush); -void nv50_bufctx_emit_relocs(struct nv50_context *); -void nv50_bufctx_add_resident(struct nv50_context *, int ctx, - struct nv04_resource *, uint32_t flags); -void nv50_bufctx_del_resident(struct nv50_context *, int ctx, - struct nv04_resource *); -static INLINE void -nv50_bufctx_reset(struct nv50_context *nv50, int ctx) -{ - nv50->residents_size -= nv50->residents[ctx].size; - util_dynarray_resize(&nv50->residents[ctx], 0); -} +void nv50_default_kick_notify(struct nouveau_pushbuf *); /* nv50_draw.c */ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *); @@ -194,7 +204,7 @@ nv50_create_sampler_view(struct pipe_context *, /* nv50_transfer.c */ void -nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, +nv50_m2mf_transfer_rect(struct nv50_context *, const struct nv50_m2mf_rect *dst, const struct nv50_m2mf_rect *src, uint32_t nblocksx, uint32_t nblocksy); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 76b60592bfb..bfadbc5ab28 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -31,7 +31,7 @@ static INLINE uint32_t nv50_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz) { - return nvc0_tex_choose_tile_dims(nx, ny * 2, nz) >> 4; + return nvc0_tex_choose_tile_dims(nx, ny * 2, nz); } static uint32_t @@ -41,58 +41,60 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed) uint32_t tile_flags; - if (mt->base.base.bind & PIPE_BIND_CURSOR) - return NOUVEAU_BO_TILE_SCANOUT; + if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR)) + return 0; + if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR)) + return 0; switch (mt->base.base.format) { case PIPE_FORMAT_Z16_UNORM: - tile_flags = 0x6c00 + (ms << 8); + tile_flags = 0x6c + (ms << 8); break; case PIPE_FORMAT_S8_UINT_Z24_UNORM: - tile_flags = 0x1800 + (ms << 8); + tile_flags = 0x18 + (ms << 8); break; case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: - tile_flags = 0x22800 + (ms << 8); + tile_flags = 0x128 + (ms << 8); break; case PIPE_FORMAT_Z32_FLOAT: - tile_flags = 0x4000 + (ms << 8); + tile_flags = 0x40 + (ms << 8); break; case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - tile_flags = 0x6000 + (ms << 8); + tile_flags = 0x60 + (ms << 8); break; default: switch (util_format_get_blocksizebits(mt->base.base.format)) { case 128: assert(ms < 3); - tile_flags = 0x7400; + tile_flags = 0x74; break; case 64: switch (ms) { - case 2: tile_flags = 0x17c00; break; - case 3: tile_flags = 0x17d00; break; + case 2: tile_flags = 0xfc; break; + case 3: tile_flags = 0xfd; break; default: - tile_flags = 0x7000; + tile_flags = 0x70; break; } break; case 32: if (mt->base.base.bind & PIPE_BIND_SCANOUT) { assert(ms == 0); - tile_flags = 0x7a00; + tile_flags = 0x7a; } else { switch (ms) { - case 2: tile_flags = 0x17800; break; - case 3: tile_flags = 0x17900; break; + case 2: tile_flags = 0xf8; break; + case 3: tile_flags = 0xf9; break; default: - tile_flags = 0x7000; + tile_flags = 0x70; break; } } break; case 16: case 8: - tile_flags = 0x7000; + tile_flags = 0x70; break; default: return 0; @@ -101,14 +103,8 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed) tile_flags = 0; } - if (mt->base.base.bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR)) - tile_flags |= NOUVEAU_BO_TILE_SCANOUT; - if (!compressed) - tile_flags &= ~0x30000; - - if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR)) - tile_flags &= ~0x3ff00; + tile_flags &= ~0x180; return tile_flags; } @@ -118,7 +114,7 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt) { struct nv50_miptree *mt = nv50_miptree(pt); - nouveau_screen_bo_release(pscreen, mt->base.bo); + nouveau_bo_ref(NULL, &mt->base.bo); FREE(mt); } @@ -260,7 +256,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); struct pipe_resource *pt = &mt->base.base; int ret; - uint32_t tile_flags; + union nouveau_bo_config bo_config; + uint32_t bo_flags; if (!mt) return NULL; @@ -270,30 +267,34 @@ nv50_miptree_create(struct pipe_screen *pscreen, pipe_reference_init(&pt->reference, 1); pt->screen = pscreen; - tile_flags = nv50_mt_choose_storage_type(mt, TRUE); + bo_config.nv50.memtype = nv50_mt_choose_storage_type(mt, TRUE); if (!nv50_miptree_init_ms_mode(mt)) { FREE(mt); return NULL; } - if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { + if (bo_config.nv50.memtype != 0) { nv50_miptree_init_layout_tiled(mt); } else if (!nv50_miptree_init_layout_linear(mt)) { FREE(mt); return NULL; } + bo_config.nv50.tile_mode = mt->level[0].tile_mode; + + bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP; + if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET)) + bo_flags |= NOUVEAU_BO_CONTIG; - ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096, - mt->total_size, - mt->level[0].tile_mode, tile_flags, - &mt->base.bo); + ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config, + &mt->base.bo); if (ret) { FREE(mt); return NULL; } mt->base.domain = NOUVEAU_BO_VRAM; + mt->base.address = mt->base.bo->offset; return pt; } @@ -323,6 +324,8 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, FREE(mt); return NULL; } + mt->base.domain = NOUVEAU_BO_VRAM; + mt->base.address = mt->base.bo->offset; mt->base.base = *templ; mt->base.vtbl = &nv50_miptree_vtbl; @@ -330,7 +333,7 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, mt->base.base.screen = pscreen; mt->level[0].pitch = stride; mt->level[0].offset = 0; - mt->level[0].tile_mode = mt->base.bo->tile_mode; + mt->level[0].tile_mode = mt->base.bo->config.nv50.tile_mode; /* no need to adjust bo reference count */ return &mt->base.base; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index c141a91eec2..776cecaeb7e 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -489,7 +489,8 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti) ++nintp; } - p->fp.colors = 4 << NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT; /* after HPOS */ + /* after HPOS */ + p->fp.colors = 4 << NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT; for (i = 0; i < p->in_nr; ++i) { int j = p->in[i].id; @@ -680,8 +681,8 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) const struct pipe_shader_state pipe = p->pipe; const ubyte type = p->type; - if (p->res) - nouveau_resource_free(&p->res); + if (p->mem) + nouveau_heap_free(&p->mem); if (p->code) FREE(p->code); diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 993e1691ab7..17aee97a024 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -87,7 +87,7 @@ struct nv50_program { void *fixups; unsigned num_fixups; - struct nouveau_resource *res; + struct nouveau_heap *mem; }; #define NV50_INTERP_LINEAR (1 << 0) diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index e8ad1ddd38a..04e32b7e8b9 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -11,7 +11,7 @@ #include "nv50_3d.xml.h" struct push_context { - struct nouveau_channel *chan; + struct nouveau_pushbuf *push; void *idxbuf; @@ -74,20 +74,20 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size); ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); + ctx->push->cur); - ctx->chan->cur += size; + ctx->push->cur += size; count -= nr; elts += nr; if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (ctx->chan, ctx->restart_index); + BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (ctx->push, ctx->restart_index); } } } @@ -107,20 +107,20 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size); ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); + ctx->push->cur); - ctx->chan->cur += size; + ctx->push->cur += size; count -= nr; elts += nr; if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (ctx->chan, ctx->restart_index); + BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (ctx->push, ctx->restart_index); } } } @@ -140,20 +140,20 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size); ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); + ctx->push->cur); - ctx->chan->cur += size; + ctx->push->cur += size; count -= nr; elts += nr; if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (ctx->chan, ctx->restart_index); + BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (ctx->push, ctx->restart_index); } } } @@ -165,11 +165,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count) unsigned push = MIN2(count, ctx->packet_vertex_limit); unsigned size = ctx->vertex_words * push; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size); ctx->translate->run(ctx->translate, start, push, ctx->instance_id, - ctx->chan->cur); - ctx->chan->cur += size; + ctx->push->cur); + ctx->push->cur += size; count -= push; start += push; } @@ -213,7 +213,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) unsigned inst = info->instance_count; boolean apply_bias = info->indexed && info->index_bias; - ctx.chan = nv50->screen->base.channel; + ctx.push = nv50->base.pushbuf; ctx.translate = nv50->vertex->translate; ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit; ctx.vertex_words = nv50->vertex->vertex_size; @@ -252,19 +252,19 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) ctx.prim = nv50_prim_gl(info->mode); if (info->primitive_restart) { - BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2); - OUT_RING (ctx.chan, 1); - OUT_RING (ctx.chan, info->restart_index); + BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 2); + PUSH_DATA (ctx.push, 1); + PUSH_DATA (ctx.push, info->restart_index); } else if (nv50->state.prim_restart) { - BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1); - OUT_RING (ctx.chan, 0); + BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 1); + PUSH_DATA (ctx.push, 0); } nv50->state.prim_restart = info->primitive_restart; while (inst--) { - BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (ctx.chan, ctx.prim); + BEGIN_NV04(ctx.push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (ctx.push, ctx.prim); switch (index_size) { case 0: emit_vertices_seq(&ctx, info->start, info->count); @@ -282,8 +282,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) assert(0); break; } - BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1); - OUT_RING (ctx.chan, 0); + BEGIN_NV04(ctx.push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (ctx.push, 0); ctx.instance_id++; ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 59d315aa475..220b166f985 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -22,6 +22,8 @@ * Authors: Christoph Bumiller */ +#define NV50_PUSH_EXPLICIT_SPACE_CHECKING + #include "nv50_context.h" #include "nouveau/nv_object.xml.h" @@ -64,7 +66,8 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) if (q->ready) nouveau_mm_free(q->mm); else - nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm); + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, + q->mm); } } if (size) { @@ -73,14 +76,12 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) return FALSE; q->offset = q->base; - ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD | - NOUVEAU_BO_NOSYNC); + ret = nouveau_bo_map(q->bo, 0, screen->base.client); if (ret) { nv50_query_allocate(nv50, q, 0); return FALSE; } - q->data = q->bo->map; - nouveau_bo_unmap(q->bo); + q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base); } return TRUE; } @@ -121,24 +122,25 @@ nv50_query_create(struct pipe_context *pipe, unsigned type) } static void -nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q, +nv50_query_get(struct nouveau_pushbuf *push, struct nv50_query *q, unsigned offset, uint32_t get) { offset += q->offset; - MARK_RING (chan, 5, 2); - BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, q->sequence); - OUT_RING (chan, get); + PUSH_SPACE(push, 5); + PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4); + PUSH_DATAh(push, q->bo->offset + offset); + PUSH_DATA (push, q->bo->offset + offset); + PUSH_DATA (push, q->sequence); + PUSH_DATA (push, get); } static void nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q = nv50_query(pq); /* For occlusion queries we have to change the storage, because a previous @@ -161,27 +163,31 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: - BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); - OUT_RING (chan, NV50_3D_COUNTER_RESET_SAMPLECNT); - BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1); - OUT_RING (chan, 1); + PUSH_SPACE(push, 4); + BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1); + PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT); + BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1); + PUSH_DATA (push, 1); break; case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */ - BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); - OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); + PUSH_SPACE(push, 2); + BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1); + PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); break; case PIPE_QUERY_PRIMITIVES_EMITTED: - BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); - OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); + PUSH_SPACE(push, 2); + BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1); + PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); break; case PIPE_QUERY_SO_STATISTICS: - BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2); - OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); - OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); + PUSH_SPACE(push, 3); + BEGIN_NI04(push, NV50_3D(COUNTER_RESET), 2); + PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK); + PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES); break; case PIPE_QUERY_TIMESTAMP_DISJOINT: case PIPE_QUERY_TIME_ELAPSED: - nv50_query_get(chan, q, 0x10, 0x00005002); + nv50_query_get(push, q, 0x10, 0x00005002); break; default: break; @@ -193,31 +199,32 @@ static void nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) { struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q = nv50_query(pq); switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: - nv50_query_get(chan, q, 0, 0x0100f002); - BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1); - OUT_RING (chan, 0); + nv50_query_get(push, q, 0, 0x0100f002); + PUSH_SPACE(push, 2); + BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1); + PUSH_DATA (push, 0); break; case PIPE_QUERY_PRIMITIVES_GENERATED: - nv50_query_get(chan, q, 0, 0x06805002); + nv50_query_get(push, q, 0, 0x06805002); break; case PIPE_QUERY_PRIMITIVES_EMITTED: - nv50_query_get(chan, q, 0, 0x05805002); + nv50_query_get(push, q, 0, 0x05805002); break; case PIPE_QUERY_SO_STATISTICS: - nv50_query_get(chan, q, 0x00, 0x05805002); - nv50_query_get(chan, q, 0x10, 0x06805002); + nv50_query_get(push, q, 0x00, 0x05805002); + nv50_query_get(push, q, 0x10, 0x06805002); break; case PIPE_QUERY_TIMESTAMP_DISJOINT: case PIPE_QUERY_TIME_ELAPSED: - nv50_query_get(chan, q, 0, 0x00005002); + nv50_query_get(push, q, 0, 0x00005002); break; case PIPE_QUERY_GPU_FINISHED: - nv50_query_get(chan, q, 0, 0x1000f010); + nv50_query_get(push, q, 0, 0x1000f010); break; default: assert(0); @@ -231,45 +238,33 @@ nv50_query_ready(struct nv50_query *q) return q->ready || (!q->is64bit && (q->data[0] == q->sequence)); } -static INLINE boolean -nv50_query_wait(struct nv50_query *q) -{ - int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD); - if (ret) - return FALSE; - nouveau_bo_unmap(q->bo); - return TRUE; -} - static boolean nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, boolean wait, union pipe_query_result *result) { + struct nv50_context *nv50 = nv50_context(pipe); struct nv50_query *q = nv50_query(pq); - uint64_t *res64 = (uint64_t*)result; - boolean *res8 = (boolean*)result; + uint64_t *res64 = (uint64_t *)result; + boolean *res8 = (boolean *)result; uint64_t *data64 = (uint64_t *)q->data; - if (q->type == PIPE_QUERY_GPU_FINISHED) { - res8[0] = nv50_query_ready(q); - return TRUE; - } - if (!q->ready) /* update ? */ q->ready = nv50_query_ready(q); if (!q->ready) { - struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel; if (!wait) { - if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */ - FIRE_RING(chan); + /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */ + PUSH_KICK(nv50->base.pushbuf); return FALSE; } - if (!nv50_query_wait(q)) + if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client)) return FALSE; } q->ready = TRUE; switch (q->type) { + case PIPE_QUERY_GPU_FINISHED: + res8[0] = TRUE; + break; case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */ res64[0] = q->data[1]; break; @@ -300,27 +295,28 @@ nv50_render_condition(struct pipe_context *pipe, struct pipe_query *pq, uint mode) { struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q; + PUSH_SPACE(push, 6); + if (!pq) { - BEGIN_RING(chan, RING_3D(COND_MODE), 1); - OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); return; } q = nv50_query(pq); if (mode == PIPE_RENDER_COND_WAIT || mode == PIPE_RENDER_COND_BY_REGION_WAIT) { - BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); + PUSH_DATA (push, 0); } - MARK_RING (chan, 4, 2); - BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RING (chan, NV50_3D_COND_MODE_RES_NON_ZERO); + BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3); + PUSH_DATAh(push, q->bo->offset + q->offset); + PUSH_DATA (push, q->bo->offset + q->offset); + PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO); } void diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index 50cc2afdbe1..5d5596ea6e3 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -4,10 +4,9 @@ #include "util/u_transfer.h" #include "util/u_double_list.h" -#define NOUVEAU_NVC0 + #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_buffer.h" -#undef NOUVEAU_NVC0 #ifndef __NVC0_RESOURCE_H__ /* make sure we don't use these in nvc0: */ @@ -19,12 +18,12 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen); #define NV50_TILE_SHIFT_X(m) 6 -#define NV50_TILE_SHIFT_Y(m) ((((m) >> 0) & 0xf) + 2) -#define NV50_TILE_SHIFT_Z(m) ((((m) >> 4) & 0xf) + 0) +#define NV50_TILE_SHIFT_Y(m) ((((m) >> 4) & 0xf) + 2) +#define NV50_TILE_SHIFT_Z(m) ((((m) >> 8) & 0xf) + 0) #define NV50_TILE_SIZE_X(m) 64 -#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 0) & 0xf)) -#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 4) & 0xf)) +#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 4) & 0xf)) +#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 8) & 0xf)) #define NV50_TILE_SIZE_2D(m) (NV50_TILE_SIZE_X(m) << NV50_TILE_SHIFT_Y(m)) diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 27566e24108..8a3c552784f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -33,9 +33,6 @@ # define NOUVEAU_GETPARAM_GRAPH_UNITS 13 #endif -extern int nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value); - static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, @@ -53,7 +50,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, switch (format) { case PIPE_FORMAT_Z16_UNORM: - if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D) + if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS) return FALSE; break; case PIPE_FORMAT_R8G8B8A8_UNORM: @@ -100,7 +97,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: case PIPE_CAP_SEAMLESS_CUBE_MAP: - return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D; + return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS; case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return 0; case PIPE_CAP_TWO_SIDED_STENCIL: @@ -131,7 +128,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_ENABLE: return 1; case PIPE_CAP_INDEP_BLEND_FUNC: - return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D; + return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; @@ -241,8 +238,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen) nouveau_fence_wait(screen->base.fence.current); nouveau_fence_ref (NULL, &screen->base.fence.current); } - if (screen->base.channel) - screen->base.channel->user_private = NULL; + if (screen->base.pushbuf) + screen->base.pushbuf->user_priv = NULL; + if (screen->blitctx) FREE(screen->blitctx); @@ -253,20 +251,17 @@ nv50_screen_destroy(struct pipe_screen *pscreen) nouveau_bo_ref(NULL, &screen->uniforms); nouveau_bo_ref(NULL, &screen->fence.bo); - nouveau_resource_destroy(&screen->vp_code_heap); - nouveau_resource_destroy(&screen->gp_code_heap); - nouveau_resource_destroy(&screen->fp_code_heap); + nouveau_heap_destroy(&screen->vp_code_heap); + nouveau_heap_destroy(&screen->gp_code_heap); + nouveau_heap_destroy(&screen->fp_code_heap); if (screen->tic.entries) FREE(screen->tic.entries); - nouveau_mm_destroy(screen->mm_VRAM_fe0); - - nouveau_grobj_free(&screen->tesla); - nouveau_grobj_free(&screen->eng2d); - nouveau_grobj_free(&screen->m2mf); - - nouveau_notifier_free(&screen->sync); + nouveau_object_del(&screen->tesla); + nouveau_object_del(&screen->eng2d); + nouveau_object_del(&screen->m2mf); + nouveau_object_del(&screen->sync); nouveau_screen_fini(&screen->base); @@ -277,18 +272,16 @@ static void nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) { struct nv50_screen *screen = nv50_screen(pscreen); - struct nouveau_channel *chan = screen->base.channel; - - MARK_RING (chan, 5, 2); + struct nouveau_pushbuf *push = screen->base.pushbuf; /* we need to do it after possible flush in MARK_RING */ *sequence = ++screen->base.fence.sequence; - BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RING (chan, *sequence); - OUT_RING (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | + PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4)); + PUSH_DATAh(push, screen->fence.bo->offset); + PUSH_DATA (push, screen->fence.bo->offset); + PUSH_DATA (push, *sequence); + PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | NV50_3D_QUERY_GET_UNK4 | NV50_3D_QUERY_GET_UNIT_CROP | NV50_3D_QUERY_GET_TYPE_QUERY | @@ -299,8 +292,205 @@ nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) static u32 nv50_screen_fence_update(struct pipe_screen *pscreen) { - struct nv50_screen *screen = nv50_screen(pscreen); - return screen->fence.map[0]; + return nv50_screen(pscreen)->fence.map[0]; +} + +static int +nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space) +{ + struct nouveau_pushbuf *push = screen->base.pushbuf; + struct nv04_fifo *fifo; + unsigned i; + + fifo = (struct nv04_fifo *)screen->base.channel->data; + + BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->m2mf->handle); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3); + PUSH_DATA (push, screen->sync->handle); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + + BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->eng2d->handle); + BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4); + PUSH_DATA (push, screen->sync->handle); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + BEGIN_NV04(push, NV50_2D(OPERATION), 1); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); + BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, SUBC_2D(0x0888), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->tesla->handle); + + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); + + BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); + PUSH_DATA (push, screen->sync->handle); + BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); + for (i = 0; i < 11; ++i) + PUSH_DATA(push, fifo->vram); + BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); + for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) + PUSH_DATA(push, fifo->vram); + + BEGIN_NV04(push, NV50_3D(REG_MODE), 1); + PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED); + BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1); + PUSH_DATA (push, 0xf); + + BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + + BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); + PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1); + BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1); + PUSH_DATA (push, 1); + + if (screen->tesla->oclass >= NVA0_3D_CLASS) { + BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1); + PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); + } + + BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1); + PUSH_DATA (push, 0x3f); + + BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); + PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); + PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); + + BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); + PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); + PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); + + BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2); + PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); + PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); + + BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->tls_bo->offset); + PUSH_DATA (push, screen->tls_bo->offset); + PUSH_DATA (push, util_logbase2(tls_space / 8)); + + BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->stack_bo->offset); + PUSH_DATA (push, screen->stack_bo->offset); + PUSH_DATA (push, 4); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->uniforms->offset + (0 << 16)); + PUSH_DATA (push, screen->uniforms->offset + (0 << 16)); + PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->uniforms->offset + (1 << 16)); + PUSH_DATA (push, screen->uniforms->offset + (1 << 16)); + PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->uniforms->offset + (2 << 16)); + PUSH_DATA (push, screen->uniforms->offset + (2 << 16)); + PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->uniforms->offset + (3 << 16)); + PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); + PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); + + BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6); + PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001); + PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021); + PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031); + PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); + PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); + PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); + + /* max TIC (bits 4:8) & TSC bindings, per program type */ + for (i = 0; i < 3; ++i) { + BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); + PUSH_DATA (push, 0x54); + } + + BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->txc->offset); + PUSH_DATA (push, screen->txc->offset); + PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1); + + BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->txc->offset + 65536); + PUSH_DATA (push, screen->txc->offset + 65536); + PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1); + + BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1); + PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); + BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2); + for (i = 0; i < 8 * 2; ++i) + PUSH_DATA(push, 0); + BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 1.0f); + + BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); +#ifdef NV50_SCISSORS_CLIPPING + PUSH_DATA (push, 0x0000); +#else + PUSH_DATA (push, 0x1080); +#endif + + BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1); + PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); + + /* We use scissors instead of exact view volume clipping, + * so they're always enabled. + */ + BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); + PUSH_DATA (push, 1); + PUSH_DATA (push, 8192 << 16); + PUSH_DATA (push, 8192 << 16); + + BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1); + PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL); + BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); + PUSH_DATA (push, 0x11111111); + BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); + PUSH_DATA (push, 1); + + PUSH_KICK (push); + + return 0; } #define FAIL_SCREEN_INIT(str, err) \ @@ -314,13 +504,12 @@ struct pipe_screen * nv50_screen_create(struct nouveau_device *dev) { struct nv50_screen *screen; - struct nouveau_channel *chan; struct pipe_screen *pscreen; + struct nouveau_object *chan; uint64_t value; uint32_t tesla_class; unsigned stack_size, max_warps, tls_space; int ret; - unsigned i, base; screen = CALLOC_STRUCT(nv50_screen); if (!screen) @@ -333,8 +522,10 @@ nv50_screen_create(struct nouveau_device *dev) if (ret) FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); + screen->base.pushbuf->user_priv = screen; + screen->base.pushbuf->rsvd_kick = 5; + chan = screen->base.channel; - chan->user_private = screen; pscreen->destroy = nv50_screen_destroy; pscreen->context_create = nv50_create; @@ -348,68 +539,52 @@ nv50_screen_create(struct nouveau_device *dev) nouveau_screen_init_vdec(&screen->base); ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, - &screen->fence.bo); + NULL, &screen->fence.bo); if (ret) goto fail; - nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); + nouveau_bo_map(screen->fence.bo, 0, NULL); screen->fence.map = screen->fence.bo->map; - nouveau_bo_unmap(screen->fence.bo); screen->base.fence.emit = nv50_screen_fence_emit; screen->base.fence.update = nv50_screen_fence_update; - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); + ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS, + &(struct nv04_notify){ .length = 32 }, + sizeof(struct nv04_notify), &screen->sync); if (ret) FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret); - ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf); + + ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS, + NULL, 0, &screen->m2mf); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); - BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3); - OUT_RING (chan, screen->sync->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); + ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS, + NULL, 0, &screen->eng2d); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); - BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D); - BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4); - OUT_RING (chan, screen->sync->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, RING_2D(OPERATION), 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_2D_(0x0888), 1); - OUT_RING (chan, 1); - switch (dev->chipset & 0xf0) { case 0x50: - tesla_class = NV50_3D; + tesla_class = NV50_3D_CLASS; break; case 0x80: case 0x90: - tesla_class = NV84_3D; + tesla_class = NV84_3D_CLASS; break; case 0xa0: switch (dev->chipset) { case 0xa0: case 0xaa: case 0xac: - tesla_class = NVA0_3D; + tesla_class = NVA0_3D_CLASS; break; case 0xaf: - tesla_class = NVAF_3D; + tesla_class = NVAF_3D_CLASS; break; default: - tesla_class = NVA3_3D; + tesla_class = NVA3_3D_CLASS; break; } break; @@ -418,98 +593,33 @@ nv50_screen_create(struct nouveau_device *dev) break; } - ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla); + ret = nouveau_object_new(chan, 0xbeef5097, tesla_class, + NULL, 0, &screen->tesla); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); - BIND_RING (chan, screen->tesla, NV50_SUBCH_3D); - - BEGIN_RING(chan, RING_3D(COND_MODE), 1); - OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); - - BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1); - OUT_RING (chan, screen->sync->handle); - BEGIN_RING(chan, RING_3D(DMA_ZETA), 11); - for (i = 0; i < 11; ++i) - OUT_RING(chan, chan->vram->handle); - BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); - for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) - OUT_RING(chan, chan->vram->handle); - - BEGIN_RING(chan, RING_3D(REG_MODE), 1); - OUT_RING (chan, NV50_3D_REG_MODE_STRIPED); - BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1); - OUT_RING (chan, 0xf); - - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - - BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); - OUT_RING (chan, NV50_3D_MULTISAMPLE_MODE_MS1); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); - OUT_RING (chan, 1); - - if (tesla_class >= NVA0_3D) { - BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1); - OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); - } - - BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */ - OUT_RING (chan, 0x3f); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, - 3 << NV50_CODE_BO_SIZE_LOG2, &screen->code); + 3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code); if (ret) goto fail; - nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); - nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); - nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); - - base = 1 << NV50_CODE_BO_SIZE_LOG2; - - BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2); - OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - - BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2); - OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - - BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2); - OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); - nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); + nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); max_warps = util_bitcount(value & 0xffff); max_warps *= util_bitcount((value >> 24) & 0xf) * 32; stack_size = max_warps * 64 * 8; - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL, &screen->stack_bo); if (ret) FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); - BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, 4); - tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16; screen->tls_size = tls_space * max_warps * 32; @@ -518,126 +628,32 @@ nv50_screen_create(struct nouveau_device *dev) debug_printf("max_warps = %i, tls_size = %"PRIu64" KiB\n", max_warps, screen->tls_size >> 10); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, NULL, &screen->tls_bo); if (ret) FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); - BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, util_logbase2(tls_space / 8)); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL, &screen->uniforms); if (ret) goto fail; - BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, (NV50_CB_PVP << 16) | 0x0000); - - BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, (NV50_CB_PGP << 16) | 0x0000); - - BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, (NV50_CB_PFP << 16) | 0x0000); - - BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200); - - BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6); - OUT_RING (chan, (NV50_CB_PVP << 12) | 0x001); - OUT_RING (chan, (NV50_CB_PGP << 12) | 0x021); - OUT_RING (chan, (NV50_CB_PFP << 12) | 0x031); - OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf01); - OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf21); - OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf31); - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL, &screen->txc); if (ret) FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret); - /* max TIC (bits 4:8) & TSC bindings, per program type */ - for (i = 0; i < 3; ++i) { - BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1); - OUT_RING (chan, 0x54); - } - - BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, NV50_TIC_MAX_ENTRIES - 1); - - BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, NV50_TSC_MAX_ENTRIES - 1); - - BEGIN_RING(chan, RING_3D(LINKED_TSC), 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1); - OUT_RING (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); - BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2); - for (i = 0; i < 8 * 2; ++i) - OUT_RING(chan, 0); - BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 1.0f); - - BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); -#ifdef NV50_SCISSORS_CLIPPING - OUT_RING (chan, 0x0000); -#else - OUT_RING (chan, 0x1080); -#endif - - BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1); - OUT_RING (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); - - /* We use scissors instead of exact view volume clipping, - * so they're always enabled. - */ - BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3); - OUT_RING (chan, 1); - OUT_RING (chan, 8192 << 16); - OUT_RING (chan, 8192 << 16); - - BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); - OUT_RING (chan, NV50_3D_POINT_RASTER_RULES_OGL); - BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); - OUT_RING (chan, 0x11111111); - BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); - OUT_RING (chan, 1); - - FIRE_RING (chan); - screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); if (!nv50_blitctx_create(screen)) goto fail; + if (nv50_screen_init_hwctx(screen, tls_space)) + goto fail; + nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); return pscreen; @@ -647,21 +663,6 @@ fail: return NULL; } -void -nv50_screen_make_buffers_resident(struct nv50_screen *screen) -{ - struct nouveau_channel *chan = screen->base.channel; - - const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; - - MARK_RING(chan, 0, 5); - nouveau_bo_validate(chan, screen->code, flags); - nouveau_bo_validate(chan, screen->uniforms, flags); - nouveau_bo_validate(chan, screen->txc, flags); - nouveau_bo_validate(chan, screen->tls_bo, flags); - nouveau_bo_validate(chan, screen->stack_bo, flags); -} - int nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry) { diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index cb7e956cd84..b7803cfed80 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -1,11 +1,11 @@ #ifndef __NV50_SCREEN_H__ #define __NV50_SCREEN_H__ -#define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" #include "nouveau/nouveau_fence.h" #include "nouveau/nouveau_mm.h" -#undef NOUVEAU_NVC0 +#include "nouveau/nouveau_heap.h" + #include "nv50_winsys.h" #include "nv50_stateobj.h" @@ -36,9 +36,9 @@ struct nv50_screen { uint64_t tls_size; - struct nouveau_resource *vp_code_heap; - struct nouveau_resource *gp_code_heap; - struct nouveau_resource *fp_code_heap; + struct nouveau_heap *vp_code_heap; + struct nouveau_heap *gp_code_heap; + struct nouveau_heap *fp_code_heap; struct nv50_blitctx *blitctx; @@ -59,13 +59,11 @@ struct nv50_screen { struct nouveau_bo *bo; } fence; - struct nouveau_notifier *sync; - - struct nouveau_mman *mm_VRAM_fe0; + struct nouveau_object *sync; - struct nouveau_grobj *tesla; - struct nouveau_grobj *eng2d; - struct nouveau_grobj *m2mf; + struct nouveau_object *tesla; + struct nouveau_object *eng2d; + struct nouveau_object *m2mf; }; static INLINE struct nv50_screen * @@ -76,8 +74,6 @@ nv50_screen(struct pipe_screen *screen) boolean nv50_blitctx_create(struct nv50_screen *); -void nv50_screen_make_buffers_resident(struct nv50_screen *); - int nv50_screen_tic_alloc(struct nv50_screen *, void *); int nv50_screen_tsc_alloc(struct nv50_screen *, void *); @@ -88,7 +84,6 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags) if (res->mm) { nouveau_fence_ref(screen->base.fence.current, &res->fence); - if (flags & NOUVEAU_BO_WR) nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); } @@ -97,11 +92,7 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags) static INLINE void nv50_resource_validate(struct nv04_resource *res, uint32_t flags) { - struct nv50_screen *screen = nv50_screen(res->base.screen); - if (likely(res->bo)) { - nouveau_bo_validate(screen->base.channel, res->bo, flags); - if (flags & NOUVEAU_BO_WR) res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; if (flags & NOUVEAU_BO_RD) diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index d3cdb697960..07d4e6bb0c5 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -31,7 +31,7 @@ void nv50_constbufs_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; unsigned s; for (s = 0; s < 3; ++s) { @@ -58,8 +58,8 @@ nv50_constbufs_validate(struct nv50_context *nv50) res = nv04_resource(nv50->constbuf[s][i]); if (!res) { if (i != 0) { - BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); - OUT_RING (chan, (i << 8) | p | 0); + BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); + PUSH_DATA (push, (i << 8) | p | 0); } continue; } @@ -78,43 +78,35 @@ nv50_constbufs_validate(struct nv50_context *nv50) if (!nouveau_resource_mapped_by_gpu(&res->base)) { nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM); - BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1); + PUSH_DATA (push, 0); } - MARK_RING (chan, 6, 2); - BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3); - OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD); - OUT_RING (chan, (b << 16) | (res->base.width0 & 0xffff)); - BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); - OUT_RING (chan, (b << 12) | (i << 8) | p | 1); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, res->address); + PUSH_DATA (push, res->address); + PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff)); + BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); + PUSH_DATA (push, (b << 12) | (i << 8) | p | 1); bo = res->bo; - - nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res, - res->domain | NOUVEAU_BO_RD); } - if (words) { - MARK_RING(chan, 8, 1); - - nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR); - } + if (bo != nv50->screen->uniforms) + BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD); while (words) { - unsigned nr = AVAIL_RING(chan); + unsigned nr; - if (nr < 16) { - FIRE_RING(chan); - nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR); - continue; - } + if (!PUSH_SPACE(push, 16)) + break; + nr = PUSH_AVAIL(push); + assert(nr >= 16); nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN); - BEGIN_RING(chan, RING_3D(CB_ADDR), 1); - OUT_RING (chan, (start << 8) | b); - BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr); - OUT_RINGp (chan, &res->data[start * 4], nr); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, (start << 8) | b); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr); + PUSH_DATAp(push, &res->data[start * 4], nr); start += nr; words -= nr; @@ -126,7 +118,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) static boolean nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) { - struct nouveau_resource *heap; + struct nouveau_heap *heap; int ret; unsigned size; @@ -135,7 +127,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) if (!prog->translated) return FALSE; } else - if (prog->res) + if (prog->mem) return TRUE; if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap; @@ -146,12 +138,12 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) size = align(prog->code_size, 0x100); - ret = nouveau_resource_alloc(heap, size, prog, &prog->res); + ret = nouveau_heap_alloc(heap, size, prog, &prog->mem); if (ret) { NOUVEAU_ERR("out of code space for shader type %i\n", prog->type); return FALSE; } - prog->code_base = prog->res->start; + prog->code_base = prog->mem->start; nv50_relocate_program(prog, prog->code_base, 0); @@ -159,80 +151,99 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) (prog->type << NV50_CODE_BO_SIZE_LOG2) + 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); + BEGIN_NV04(nv50->base.pushbuf, NV50_3D(CODE_CB_FLUSH), 1); + PUSH_DATA (nv50->base.pushbuf, 0); return TRUE; } +static INLINE void +nv50_program_update_context_state(struct nv50_context *nv50, + struct nv50_program *prog, int stage) +{ + const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (prog && prog->uses_lmem) { + if (!nv50->state.tls_required) + BCTX_REFN_bo(nv50->bufctx_3d, TLS, flags, nv50->screen->tls_bo); + nv50->state.tls_required |= 1 << stage; + } else { + if (nv50->state.tls_required == (1 << stage)) + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TLS); + nv50->state.tls_required &= ~(1 << stage); + } +} + void nv50_vertprog_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *vp = nv50->vertprog; if (!nv50_program_validate(nv50, vp)) return; - - BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2); - OUT_RING (chan, vp->vp.attrs[0]); - OUT_RING (chan, vp->vp.attrs[1]); - BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1); - OUT_RING (chan, vp->max_out); - BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1); - OUT_RING (chan, vp->max_gpr); - BEGIN_RING(chan, RING_3D(VP_START_ID), 1); - OUT_RING (chan, vp->code_base); + nv50_program_update_context_state(nv50, vp, 0); + + BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2); + PUSH_DATA (push, vp->vp.attrs[0]); + PUSH_DATA (push, vp->vp.attrs[1]); + BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_RESULT), 1); + PUSH_DATA (push, vp->max_out); + BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_TEMP), 1); + PUSH_DATA (push, vp->max_gpr); + BEGIN_NV04(push, NV50_3D(VP_START_ID), 1); + PUSH_DATA (push, vp->code_base); } void nv50_fragprog_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *fp = nv50->fragprog; if (!nv50_program_validate(nv50, fp)) return; - - BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1); - OUT_RING (chan, fp->max_gpr); - BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1); - OUT_RING (chan, fp->max_out); - BEGIN_RING(chan, RING_3D(FP_CONTROL), 1); - OUT_RING (chan, fp->fp.flags[0]); - BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1); - OUT_RING (chan, fp->fp.flags[1]); - BEGIN_RING(chan, RING_3D(FP_START_ID), 1); - OUT_RING (chan, fp->code_base); + nv50_program_update_context_state(nv50, fp, 1); + + BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1); + PUSH_DATA (push, fp->max_gpr); + BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1); + PUSH_DATA (push, fp->max_out); + BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1); + PUSH_DATA (push, fp->fp.flags[0]); + BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1); + PUSH_DATA (push, fp->fp.flags[1]); + BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); + PUSH_DATA (push, fp->code_base); } void nv50_gmtyprog_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *gp = nv50->gmtyprog; - if (!gp) /* GP_ENABLE is updated in linkage validation */ - return; - if (!nv50_program_validate(nv50, gp)) - return; + if (gp) { + BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_TEMP), 1); + PUSH_DATA (push, gp->max_gpr); + BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_RESULT), 1); + PUSH_DATA (push, gp->max_out); + BEGIN_NV04(push, NV50_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1); + PUSH_DATA (push, gp->gp.prim_type); + BEGIN_NV04(push, NV50_3D(GP_VERTEX_OUTPUT_COUNT), 1); + PUSH_DATA (push, gp->gp.vert_count); + BEGIN_NV04(push, NV50_3D(GP_START_ID), 1); + PUSH_DATA (push, gp->code_base); + } + nv50_program_update_context_state(nv50, gp, 2); - BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1); - OUT_RING (chan, gp->max_gpr); - BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1); - OUT_RING (chan, gp->max_out); - BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1); - OUT_RING (chan, gp->gp.prim_type); - BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1); - OUT_RING (chan, gp->gp.vert_count); - BEGIN_RING(chan, RING_3D(GP_START_ID), 1); - OUT_RING (chan, gp->code_base); + /* GP_ENABLE is updated in linkage validation */ } static void nv50_sprite_coords_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; uint32_t pntc[8], mode; struct nv50_program *fp = nv50->fragprog; unsigned i, c; @@ -240,9 +251,9 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) if (!nv50->rast->pipe.point_quad_rasterization) { if (nv50->state.point_sprite) { - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); + BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8); for (i = 0; i < 8; ++i) - OUT_RING(chan, 0); + PUSH_DATA(push, 0); nv50->state.point_sprite = FALSE; } @@ -278,43 +289,43 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) else mode = 0x10; - BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1); - OUT_RING (chan, mode); + BEGIN_NV04(push, NV50_3D(POINT_SPRITE_CTRL), 1); + PUSH_DATA (push, mode); - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); - OUT_RINGp (chan, pntc, 8); + BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8); + PUSH_DATAp(push, pntc, 8); } /* Validate state derived from shaders and the rasterizer cso. */ void nv50_validate_derived_rs(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; uint32_t color, psize; nv50_sprite_coords_validate(nv50); if (nv50->dirty & NV50_NEW_FRAGPROG) return; - psize = nv50->state.semantic_psize & ~NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK; - color = nv50->state.semantic_color & ~NV50_3D_MAP_SEMANTIC_0_CLMP_EN; + psize = nv50->state.semantic_psize & ~NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK; + color = nv50->state.semantic_color & ~NV50_3D_SEMANTIC_COLOR_CLMP_EN; if (nv50->rast->pipe.clamp_vertex_color) - color |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN; + color |= NV50_3D_SEMANTIC_COLOR_CLMP_EN; if (color != nv50->state.semantic_color) { nv50->state.semantic_color = color; - BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 1); - OUT_RING (chan, color); + BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 1); + PUSH_DATA (push, color); } if (nv50->rast->pipe.point_size_per_vertex) - psize |= NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK; + psize |= NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK; if (psize != nv50->state.semantic_psize) { nv50->state.semantic_psize = psize; - BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_3), 1); - OUT_RING (chan, psize); + BEGIN_NV04(push, NV50_3D(SEMANTIC_PTSZ), 1); + PUSH_DATA (push, psize); } } @@ -348,7 +359,7 @@ nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4], void nv50_fp_linkage_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog; struct nv50_program *fp = nv50->fragprog; struct nv50_varying dummy; @@ -409,48 +420,48 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) } if (nv50->rast->pipe.clamp_vertex_color) - colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN; + colors |= NV50_3D_SEMANTIC_COLOR_CLMP_EN; n = (m + 3) / 4; assert(m <= 64); if (unlikely(nv50->gmtyprog)) { - BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1); - OUT_RING (chan, m); - BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n); - OUT_RINGp (chan, map, n); + BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP_SIZE), 1); + PUSH_DATA (push, m); + BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP(0)), n); + PUSH_DATAp(push, map, n); } else { - BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1); - OUT_RING (chan, vp->vp.attrs[2]); + BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1); + PUSH_DATA (push, vp->vp.attrs[2]); - BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1); - OUT_RING (chan, primid); + BEGIN_NV04(push, NV50_3D(SEMANTIC_PRIM_ID), 1); + PUSH_DATA (push, primid); - BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1); - OUT_RING (chan, m); - BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n); - OUT_RINGp (chan, map, n); + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1); + PUSH_DATA (push, m); + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n); + PUSH_DATAp(push, map, n); } - BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4); - OUT_RING (chan, colors); - OUT_RING (chan, (vp->vp.clpd_nr << 8) | 4); - OUT_RING (chan, 0); - OUT_RING (chan, psiz); + BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4); + PUSH_DATA (push, colors); + PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, psiz); - BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1); - OUT_RING (chan, interp); + BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 1); + PUSH_DATA (push, interp); nv50->state.interpolant_ctrl = interp; nv50->state.semantic_color = colors; nv50->state.semantic_psize = psiz; - BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4); - OUT_RINGp (chan, lin, 4); + BEGIN_NV04(push, NV50_3D(NOPERSPECTIVE_BITMAP(0)), 4); + PUSH_DATAp(push, lin, 4); - BEGIN_RING(chan, RING_3D(GP_ENABLE), 1); - OUT_RING (chan, nv50->gmtyprog ? 1 : 0); + BEGIN_NV04(push, NV50_3D(GP_ENABLE), 1); + PUSH_DATA (push, nv50->gmtyprog ? 1 : 0); } static int @@ -486,7 +497,7 @@ nv50_vp_gp_mapping(uint8_t *map, int m, void nv50_gp_linkage_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *vp = nv50->vertprog; struct nv50_program *gp = nv50->gmtyprog; int m = 0; @@ -501,11 +512,11 @@ nv50_gp_linkage_validate(struct nv50_context *nv50) n = (m + 3) / 4; - BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1); - OUT_RING (chan, vp->vp.attrs[2] | gp->vp.attrs[2]); + BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1); + PUSH_DATA (push, vp->vp.attrs[2] | gp->vp.attrs[2]); - BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1); - OUT_RING (chan, m); - BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n); - OUT_RINGp (chan, map, n); + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1); + PUSH_DATA (push, m); + BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n); + PUSH_DATAp(push, map, n); } diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 0f46afb882b..e1e1af039bb 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -121,7 +121,7 @@ nv50_blend_state_create(struct pipe_context *pipe, boolean emit_common_func = cso->rt[0].blend_enable; uint32_t ms; - if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { + if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); SB_DATA (so, cso->independent_blend_enable); } @@ -142,7 +142,7 @@ nv50_blend_state_create(struct pipe_context *pipe, emit_common_func = TRUE; } - if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { + if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { emit_common_func = FALSE; for (i = 0; i < 8; ++i) { @@ -628,7 +628,7 @@ nv50_stage_set_sampler_views(struct nv50_context *nv50, int s, nv50->num_textures[s] = nr; - nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); nv50->dirty |= NV50_NEW_TEXTURES; } @@ -741,13 +741,15 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { struct nv50_context *nv50 = nv50_context(pipe); - if (nv50->constbuf[shader][index]) - nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT, - nv04_resource(nv50->constbuf[shader][index])); - pipe_resource_reference(&nv50->constbuf[shader][index], res); nv50->constbuf_dirty[shader] |= 1 << index; + if (res) + nv50->constbuf_valid[shader] |= 1 << index; + else + nv50->constbuf_valid[shader] &= ~(1 << index); + + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index)); nv50->dirty |= NV50_NEW_CONSTBUF; } @@ -802,6 +804,8 @@ nv50_set_framebuffer_state(struct pipe_context *pipe, { struct nv50_context *nv50 = nv50_context(pipe); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); + nv50->framebuffer = *fb; nv50->dirty |= NV50_NEW_FRAMEBUFFER; } @@ -852,7 +856,7 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count); nv50->num_vtxbufs = count; - nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX); nv50->dirty |= NV50_NEW_ARRAYS; } @@ -863,10 +867,15 @@ nv50_set_index_buffer(struct pipe_context *pipe, { struct nv50_context *nv50 = nv50_context(pipe); - if (ib) { - pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer); + if (nv50->idxbuf.buffer) + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX); - memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); + if (ib && ib->buffer) { + pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer); + nv50->idxbuf.offset = ib->offset; + nv50->idxbuf.index_size = ib->index_size; + if (nouveau_resource_mapped_by_gpu(ib->buffer)) + BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD); } else { pipe_resource_reference(&nv50->idxbuf.buffer, NULL); } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index c8a1c4ecb37..7af992076c7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -5,48 +5,44 @@ static void nv50_validate_fb(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1; - boolean serialize = FALSE; - nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs); - BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, fb->width << 16); - OUT_RING (chan, fb->height << 16); - - MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs); + BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); + PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs); + BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, fb->width << 16); + PUSH_DATA (push, fb->height << 16); for (i = 0; i < fb->nr_cbufs; ++i) { struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture); struct nv50_surface *sf = nv50_surface(fb->cbufs[i]); struct nouveau_bo *bo = mt->base.bo; - uint32_t offset = sf->offset; - - BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5); - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, nv50_format_table[sf->base.format].rt); - if (likely(nouveau_bo_tile_layout(bo))) { - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); - OUT_RING (chan, mt->layer_stride >> 2); - BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, sf->depth); + + BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5); + PUSH_DATAh(push, bo->offset + sf->offset); + PUSH_DATA (push, bo->offset + sf->offset); + PUSH_DATA (push, nv50_format_table[sf->base.format].rt); + if (likely(nouveau_bo_memtype(bo))) { + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, mt->layer_stride >> 2); + BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2); + PUSH_DATA (push, sf->width); + PUSH_DATA (push, sf->height); + BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); + PUSH_DATA (push, sf->depth); } else { - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); - OUT_RING (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); - OUT_RING (chan, sf->height); - BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2); + PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); + PUSH_DATA (push, sf->height); + BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); + PUSH_DATA (push, 0); assert(!fb->zsbuf); assert(!mt->ms_mode); @@ -55,13 +51,12 @@ nv50_validate_fb(struct nv50_context *nv50) ms_mode = mt->ms_mode; if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) - serialize = TRUE; + nv50->state.rt_serialize = TRUE; mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; /* only register for writing, otherwise we'd always serialize here */ - nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR); } if (fb->zsbuf) { @@ -69,87 +64,79 @@ nv50_validate_fb(struct nv50_context *nv50) struct nv50_surface *sf = nv50_surface(fb->zsbuf); struct nouveau_bo *bo = mt->base.bo; int unk = mt->base.base.target == PIPE_TEXTURE_2D; - uint32_t offset = sf->offset; - - MARK_RING (chan, 12, 2); - BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); - OUT_RING (chan, mt->layer_stride >> 2); - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - OUT_RING (chan, (unk << 16) | sf->depth); + + BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5); + PUSH_DATAh(push, bo->offset + sf->offset); + PUSH_DATA (push, bo->offset + sf->offset); + PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt); + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, mt->layer_stride >> 2); + BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3); + PUSH_DATA (push, sf->width); + PUSH_DATA (push, sf->height); + PUSH_DATA (push, (unk << 16) | sf->depth); ms_mode = mt->ms_mode; if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) - serialize = TRUE; + nv50->state.rt_serialize = TRUE; mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; - nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR); } else { - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 0); } - BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); - OUT_RING (chan, ms_mode); + BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); + PUSH_DATA (push, ms_mode); - BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, fb->width << 16); - OUT_RING (chan, fb->height << 16); - - if (serialize) { - BEGIN_RING(chan, RING_3D(SERIALIZE), 1); - OUT_RING (chan, 0); - } + BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, fb->width << 16); + PUSH_DATA (push, fb->height << 16); } static void nv50_validate_blend_colour(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; - BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4); - OUT_RINGf (chan, nv50->blend_colour.color[0]); - OUT_RINGf (chan, nv50->blend_colour.color[1]); - OUT_RINGf (chan, nv50->blend_colour.color[2]); - OUT_RINGf (chan, nv50->blend_colour.color[3]); + BEGIN_NV04(push, NV50_3D(BLEND_COLOR(0)), 4); + PUSH_DATAf(push, nv50->blend_colour.color[0]); + PUSH_DATAf(push, nv50->blend_colour.color[1]); + PUSH_DATAf(push, nv50->blend_colour.color[2]); + PUSH_DATAf(push, nv50->blend_colour.color[3]); } static void nv50_validate_stencil_ref(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; - BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1); - OUT_RING (chan, nv50->stencil_ref.ref_value[0]); - BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1); - OUT_RING (chan, nv50->stencil_ref.ref_value[1]); + BEGIN_NV04(push, NV50_3D(STENCIL_FRONT_FUNC_REF), 1); + PUSH_DATA (push, nv50->stencil_ref.ref_value[0]); + BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1); + PUSH_DATA (push, nv50->stencil_ref.ref_value[1]); } static void nv50_validate_stipple(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; unsigned i; - BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32); + BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_PATTERN(0)), 32); for (i = 0; i < 32; ++i) - OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i])); + PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i])); } static void nv50_validate_scissor(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct pipe_scissor_state *s = &nv50->scissor; #ifdef NV50_SCISSORS_CLIPPING struct pipe_viewport_state *vp = &nv50->viewport; @@ -178,38 +165,38 @@ nv50_validate_scissor(struct nv50_context *nv50) miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1]))); maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1]))); - BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (maxx << 16) | minx); - OUT_RING (chan, (maxy << 16) | miny); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (maxx << 16) | minx); + PUSH_DATA (push, (maxy << 16) | miny); #else - BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (s->maxx << 16) | s->minx); - OUT_RING (chan, (s->maxy << 16) | s->miny); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (s->maxx << 16) | s->minx); + PUSH_DATA (push, (s->maxy << 16) | s->miny); #endif } static void nv50_validate_viewport(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; float zmin, zmax; - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3); - OUT_RINGf (chan, nv50->viewport.translate[0]); - OUT_RINGf (chan, nv50->viewport.translate[1]); - OUT_RINGf (chan, nv50->viewport.translate[2]); - BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3); - OUT_RINGf (chan, nv50->viewport.scale[0]); - OUT_RINGf (chan, nv50->viewport.scale[1]); - OUT_RINGf (chan, nv50->viewport.scale[2]); + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3); + PUSH_DATAf(push, nv50->viewport.translate[0]); + PUSH_DATAf(push, nv50->viewport.translate[1]); + PUSH_DATAf(push, nv50->viewport.translate[2]); + BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3); + PUSH_DATAf(push, nv50->viewport.scale[0]); + PUSH_DATAf(push, nv50->viewport.scale[1]); + PUSH_DATAf(push, nv50->viewport.scale[2]); zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]); zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]); #ifdef NV50_SCISSORS_CLIPPING - BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); - OUT_RINGf (chan, zmin); - OUT_RINGf (chan, zmax); + BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); + PUSH_DATAf(push, zmin); + PUSH_DATAf(push, zmax); #endif } @@ -234,15 +221,15 @@ nv50_check_program_ucps(struct nv50_context *nv50, static void nv50_validate_clip(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *vp; uint8_t clip_enable; if (nv50->dirty & NV50_NEW_CLIP) { - BEGIN_RING(chan, RING_3D(CB_ADDR), 1); - OUT_RING (chan, (0 << 8) | NV50_CB_AUX); - BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4); - OUT_RINGp (chan, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, (0 << 8) | NV50_CB_AUX); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4); + PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4); } vp = nv50->gmtyprog; @@ -251,8 +238,8 @@ nv50_validate_clip(struct nv50_context *nv50) clip_enable = nv50->rast->pipe.clip_plane_enable; - BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1); - OUT_RING (chan, clip_enable); + BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1); + PUSH_DATA (push, clip_enable); if (clip_enable) nv50_check_program_ucps(nv50, vp, clip_enable); @@ -261,34 +248,34 @@ nv50_validate_clip(struct nv50_context *nv50) static void nv50_validate_blend(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; - WAIT_RING(chan, nv50->blend->size); - OUT_RINGp(chan, nv50->blend->state, nv50->blend->size); + PUSH_SPACE(push, nv50->blend->size); + PUSH_DATAp(push, nv50->blend->state, nv50->blend->size); } static void nv50_validate_zsa(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; - WAIT_RING(chan, nv50->zsa->size); - OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size); + PUSH_SPACE(push, nv50->zsa->size); + PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size); } static void nv50_validate_rasterizer(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; - WAIT_RING(chan, nv50->rast->size); - OUT_RINGp(chan, nv50->rast->state, nv50->rast->size); + PUSH_SPACE(push, nv50->rast->size); + PUSH_DATAp(push, nv50->rast->state, nv50->rast->size); } static void nv50_validate_sample_mask(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; unsigned mask[4] = { @@ -298,11 +285,11 @@ nv50_validate_sample_mask(struct nv50_context *nv50) nv50->sample_mask & 0xffff }; - BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4); - OUT_RING (chan, mask[0]); - OUT_RING (chan, mask[1]); - OUT_RING (chan, mask[2]); - OUT_RING (chan, mask[3]); + BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4); + PUSH_DATA (push, mask[0]); + PUSH_DATA (push, mask[1]); + PUSH_DATA (push, mask[2]); + PUSH_DATA (push, mask[3]); } static void @@ -378,6 +365,7 @@ boolean nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words) { uint32_t state_mask; + int ret; unsigned i; if (nv50->screen->cur_ctx != nv50) @@ -393,11 +381,21 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words) validate->func(nv50); } nv50->dirty &= ~state_mask; - } - MARK_RING(nv50->screen->base.channel, words, 0); + if (nv50->state.rt_serialize) { + nv50->state.rt_serialize = FALSE; + BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); + PUSH_DATA (nv50->base.pushbuf, 0); + } - nv50_bufctx_emit_relocs(nv50); + nv50_bufctx_fence(nv50->bufctx_3d, FALSE); + } + nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d); + ret = nouveau_pushbuf_validate(nv50->base.pushbuf); - return TRUE; + if (unlikely(nv50->state.flushed)) { + nv50->state.flushed = FALSE; + nv50_bufctx_fence(nv50->bufctx_3d, TRUE); + } + return !ret; } diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h index c443dfbfec6..b056e19ea50 100644 --- a/src/gallium/drivers/nv50/nv50_stateobj.h +++ b/src/gallium/drivers/nv50/nv50_stateobj.h @@ -6,13 +6,11 @@ #define NV50_SCISSORS_CLIPPING -#define SB_BEGIN_3D(so, m, s) \ - (so)->state[(so)->size++] = \ - ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m +#define SB_BEGIN_3D(so, m, s) \ + (so)->state[(so)->size++] = NV50_FIFO_PKHDR(NV50_3D(m), s) -#define SB_BEGIN_3D_(so, m, s) \ - (so)->state[(so)->size++] = \ - ((s) << 18) | (NV50_SUBCH_3D << 13) | m +#define SB_BEGIN_3D_(so, m, s) \ + (so)->state[(so)->size++] = NV50_FIFO_PKHDR(SUBC_3D(m), s) #define SB_DATA(so, u) (so)->state[(so)->size++] = (u) diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 28e34bd9ef6..0d29dcc8a2a 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -70,14 +70,13 @@ nv50_2d_format(enum pipe_format format) } static int -nv50_2d_texture_set(struct nouveau_channel *chan, int dst, +nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst, struct nv50_miptree *mt, unsigned level, unsigned layer) { struct nouveau_bo *bo = mt->base.bo; uint32_t width, height, depth; uint32_t format; uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); uint32_t offset = mt->level[level].offset; format = nv50_2d_format(mt->base.base.format); @@ -99,44 +98,44 @@ nv50_2d_texture_set(struct nouveau_channel *chan, int dst, depth = u_minify(mt->base.base.depth0, level); } - if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) { - BEGIN_RING(chan, RING_2D_(mthd), 2); - OUT_RING (chan, format); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5); - OUT_RING (chan, mt->level[level].pitch); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RELOCh(chan, bo, offset, flags); - OUT_RELOCl(chan, bo, offset, flags); + if (!nouveau_bo_memtype(bo)) { + BEGIN_NV04(push, SUBC_2D(mthd), 2); + PUSH_DATA (push, format); + PUSH_DATA (push, 1); + BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 5); + PUSH_DATA (push, mt->level[level].pitch); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); } else { - BEGIN_RING(chan, RING_2D_(mthd), 5); - OUT_RING (chan, format); - OUT_RING (chan, 0); - OUT_RING (chan, mt->level[level].tile_mode << 4); - OUT_RING (chan, depth); - OUT_RING (chan, layer); - BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RELOCh(chan, bo, offset, flags); - OUT_RELOCl(chan, bo, offset, flags); + BEGIN_NV04(push, SUBC_2D(mthd), 5); + PUSH_DATA (push, format); + PUSH_DATA (push, 0); + PUSH_DATA (push, mt->level[level].tile_mode); + PUSH_DATA (push, depth); + PUSH_DATA (push, layer); + BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); } #if 0 if (dst) { - BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, width); - OUT_RING (chan, height); + BEGIN_NV04(push, SUBC_2D(NV50_2D_CLIP_X), 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, width); + PUSH_DATA (push, height); } #endif return 0; } static int -nv50_2d_texture_do_copy(struct nouveau_channel *chan, +nv50_2d_texture_do_copy(struct nouveau_pushbuf *push, struct nv50_miptree *dst, unsigned dst_level, unsigned dx, unsigned dy, unsigned dz, struct nv50_miptree *src, unsigned src_level, @@ -150,16 +149,16 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan, int ret; uint32_t ctrl; - +#if 0 ret = MARK_RING(chan, 2 * 16 + 32, 4); if (ret) return ret; - - ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz); +#endif + ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz); if (ret) return ret; - ret = nv50_2d_texture_set(chan, 0, src, src_level, sz); + ret = nv50_2d_texture_set(push, 0, src, src_level, sz); if (ret) return ret; @@ -168,23 +167,23 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan, ctrl = 0x11; /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */ - BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1); - OUT_RING (chan, ctrl); - BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4); - OUT_RING (chan, dx << dst->ms_x); - OUT_RING (chan, dy << dst->ms_y); - OUT_RING (chan, w << dst->ms_x); - OUT_RING (chan, h << dst->ms_y); - BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); - BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx << src->ms_x); - OUT_RING (chan, 0); - OUT_RING (chan, sy << src->ms_y); + BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1); + PUSH_DATA (push, ctrl); + BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4); + PUSH_DATA (push, dx << dst->ms_x); + PUSH_DATA (push, dy << dst->ms_y); + PUSH_DATA (push, w << dst->ms_x); + PUSH_DATA (push, h << dst->ms_y); + BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); + BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, sx << src->ms_x); + PUSH_DATA (push, 0); + PUSH_DATA (push, sy << src->ms_y); return 0; } @@ -196,7 +195,7 @@ nv50_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { - struct nv50_screen *screen = nv50_context(pipe)->screen; + struct nv50_context *nv50 = nv50_context(pipe); int ret; boolean m2mf; unsigned dst_layer = dstz, src_layer = src_box->z; @@ -227,7 +226,7 @@ nv50_resource_copy_region(struct pipe_context *pipe, src_box->x, src_box->y, src_box->z); for (i = 0; i < src_box->depth; ++i) { - nv50_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny); + nv50_m2mf_transfer_rect(nv50, &drect, &srect, nx, ny); if (nv50_miptree(dst)->layout_3d) drect.z++; @@ -246,16 +245,22 @@ nv50_resource_copy_region(struct pipe_context *pipe, (nv50_2d_format_faithful(src->format) && nv50_2d_format_faithful(dst->format))); + BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD); + BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR); + nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx); + nouveau_pushbuf_validate(nv50->base.pushbuf); + for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { - ret = nv50_2d_texture_do_copy(screen->base.channel, + ret = nv50_2d_texture_do_copy(nv50->base.pushbuf, nv50_miptree(dst), dst_level, dstx, dsty, dst_layer, nv50_miptree(src), src_level, src_box->x, src_box->y, src_layer, src_box->width, src_box->height); if (ret) - return; + break; } + nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D); } static void @@ -266,51 +271,50 @@ nv50_clear_render_target(struct pipe_context *pipe, unsigned width, unsigned height) { struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_miptree *mt = nv50_miptree(dst->texture); struct nv50_surface *sf = nv50_surface(dst); struct nouveau_bo *bo = mt->base.bo; - BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); - OUT_RINGf (chan, color->f[0]); - OUT_RINGf (chan, color->f[1]); - OUT_RINGf (chan, color->f[2]); - OUT_RINGf (chan, color->f[3]); - + BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4); + PUSH_DATAf(push, color->f[0]); + PUSH_DATAf(push, color->f[1]); + PUSH_DATAf(push, color->f[2]); + PUSH_DATAf(push, color->f[3]); +#if 0 if (MARK_RING(chan, 18, 2)) return; - - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5); - OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, nv50_format_table[dst->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2); - if (nouveau_bo_tile_layout(bo)) - OUT_RING(chan, sf->width); +#endif + BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5); + PUSH_DATAh(push, bo->offset + sf->offset); + PUSH_DATA (push, bo->offset + sf->offset); + PUSH_DATA (push, nv50_format_table[dst->format].rt); + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2); + if (nouveau_bo_memtype(bo)) + PUSH_DATA(push, sf->width); else - OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); - OUT_RING (chan, sf->height); - BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, 1); - - if (!nouveau_bo_tile_layout(bo)) { - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 0); + PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); + PUSH_DATA (push, sf->height); + BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); + PUSH_DATA (push, 1); + + if (!nouveau_bo_memtype(bo)) { + BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 0); } /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */ - BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, (width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); + BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, (width << 16) | dstx); + PUSH_DATA (push, (height << 16) | dsty); - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, 0x3c); + BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, 0x3c); nv50->dirty |= NV50_NEW_FRAMEBUFFER; } @@ -325,49 +329,48 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, unsigned width, unsigned height) { struct nv50_context *nv50 = nv50_context(pipe); - struct nv50_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_miptree *mt = nv50_miptree(dst->texture); struct nv50_surface *sf = nv50_surface(dst); struct nouveau_bo *bo = mt->base.bo; uint32_t mode = 0; - assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */ + assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */ if (clear_flags & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); - OUT_RINGf (chan, depth); + BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1); + PUSH_DATAf(push, depth); mode |= NV50_3D_CLEAR_BUFFERS_Z; } if (clear_flags & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); - OUT_RING (chan, stencil & 0xff); + BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1); + PUSH_DATA (push, stencil & 0xff); mode |= NV50_3D_CLEAR_BUFFERS_S; } - +#if 0 if (MARK_RING(chan, 17, 2)) return; - - BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); - OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, nv50_format_table[dst->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - OUT_RING (chan, (1 << 16) | 1); - - BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, (width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); - - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, mode); +#endif + BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5); + PUSH_DATAh(push, bo->offset + sf->offset); + PUSH_DATA (push, bo->offset + sf->offset); + PUSH_DATA (push, nv50_format_table[dst->format].rt); + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3); + PUSH_DATA (push, sf->width); + PUSH_DATA (push, sf->height); + PUSH_DATA (push, (1 << 16) | 1); + + BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, (width << 16) | dstx); + PUSH_DATA (push, (height << 16) | dsty); + + BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, mode); nv50->dirty |= NV50_NEW_FRAMEBUFFER; } @@ -378,7 +381,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, double depth, unsigned stencil) { struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; uint32_t mode = 0; @@ -388,34 +391,34 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, return; if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { - BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); - OUT_RINGf (chan, color->f[0]); - OUT_RINGf (chan, color->f[1]); - OUT_RINGf (chan, color->f[2]); - OUT_RINGf (chan, color->f[3]); + BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4); + PUSH_DATAf(push, color->f[0]); + PUSH_DATAf(push, color->f[1]); + PUSH_DATAf(push, color->f[2]); + PUSH_DATAf(push, color->f[3]); mode = NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G | NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A; } if (buffers & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); - OUT_RING (chan, fui(depth)); + BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1); + PUSH_DATA (push, fui(depth)); mode |= NV50_3D_CLEAR_BUFFERS_Z; } if (buffers & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); - OUT_RING (chan, stencil & 0xff); + BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1); + PUSH_DATA (push, stencil & 0xff); mode |= NV50_3D_CLEAR_BUFFERS_S; } - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, mode); + BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, mode); for (i = 1; i < fb->nr_cbufs; i++) { - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, (i << 6) | 0x3c); + BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, (i << 6) | 0x3c); } } @@ -709,50 +712,50 @@ nv50_blit_set_src(struct nv50_context *nv50, static void nv50_blitctx_prepare_state(struct nv50_blitctx *blit) { - struct nouveau_channel *chan = blit->screen->base.channel; + struct nouveau_pushbuf *push = blit->screen->base.pushbuf; /* blend state */ - BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1); - OUT_RING (chan, blit->color_mask); - BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(LOGIC_OP_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1); + PUSH_DATA (push, blit->color_mask); + BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1); + PUSH_DATA (push, 0); /* rasterizer state */ #ifndef NV50_SCISSORS_CLIPPING - BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1); + PUSH_DATA (push, 1); #endif - BEGIN_RING(chan, RING_3D(VERTEX_TWO_SIDE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 3); - OUT_RING (chan, NV50_3D_POLYGON_MODE_FRONT_FILL); - OUT_RING (chan, NV50_3D_POLYGON_MODE_BACK_FILL); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(CULL_FACE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3); + PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL); + PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1); + PUSH_DATA (push, 0); /* zsa state */ - BEGIN_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(STENCIL_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1); + PUSH_DATA (push, 0); } static void @@ -834,7 +837,7 @@ nv50_resource_resolve(struct pipe_context *pipe, struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; struct nv50_blitctx *blit = screen->blitctx; - struct nouveau_channel *chan = screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct pipe_resource *src = info->src.res; struct pipe_resource *dst = info->dst.res; float x0, x1, y0, y1, z; @@ -873,12 +876,12 @@ nv50_resource_resolve(struct pipe_context *pipe, z = (float)info->src.layer; - BEGIN_RING(chan, RING_3D(FP_START_ID), 1); - OUT_RING (chan, + BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); + PUSH_DATA (push, blit->fp.code_base + blit->fp_offset); - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 0); /* Draw a large triangle in screen coordinates covering the whole * render target, with scissors defining the destination region. @@ -886,40 +889,40 @@ nv50_resource_resolve(struct pipe_context *pipe, * arranged in a way to yield the desired offset and scale. */ - BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (info->dst.x1 << 16) | info->dst.x0); - OUT_RING (chan, (info->dst.y1 << 16) | info->dst.y0); - - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); - BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3); - OUT_RINGf (chan, x0); - OUT_RINGf (chan, y0); - OUT_RINGf (chan, z); - BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 0.0f); - BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3); - OUT_RINGf (chan, x1); - OUT_RINGf (chan, y0); - OUT_RINGf (chan, z); - BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2); - OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x); - OUT_RINGf (chan, 0.0f); - BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3); - OUT_RINGf (chan, x0); - OUT_RINGf (chan, y1); - OUT_RINGf (chan, z); - BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y); - BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0); + PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0); + + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3); + PUSH_DATAf(push, x0); + PUSH_DATAf(push, y0); + PUSH_DATAf(push, z); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 0.0f); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3); + PUSH_DATAf(push, x1); + PUSH_DATAf(push, y0); + PUSH_DATAf(push, z); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2); + PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x); + PUSH_DATAf(push, 0.0f); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3); + PUSH_DATAf(push, x0); + PUSH_DATAf(push, y1); + PUSH_DATAf(push, z); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); /* re-enable normally constant state */ - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 1); nv50_blitctx_post_blit(nv50, blit); } diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 1be4e9aff19..4a769d5b810 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -75,6 +75,7 @@ nv50_create_sampler_view(struct pipe_context *pipe, const struct pipe_sampler_view *templ) { const struct util_format_description *desc; + uint64_t addr; uint32_t *tic; uint32_t swz[4]; uint32_t depth; @@ -115,15 +116,25 @@ nv50_create_sampler_view(struct pipe_context *pipe, (swz[2] << NV50_TIC_0_MAPB__SHIFT) | (swz[3] << NV50_TIC_0_MAPA__SHIFT); - tic[1] = /* mt->base.bo->offset; */ 0; - tic[2] = /* mt->base.bo->offset >> 32 */ 0; + addr = mt->base.address; + + if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY || + mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) { + addr += view->pipe.u.tex.first_layer * mt->layer_stride; + depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; + } else { + depth = mt->base.base.depth0; + } + + tic[1] = addr; + tic[2] = (addr >> 32) & 0xff; tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; - if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) { + if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { nv50_init_tic_entry_linear(tic, texture); return &view->pipe; } @@ -132,16 +143,8 @@ nv50_create_sampler_view(struct pipe_context *pipe, tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; tic[2] |= - ((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) | - ((mt->base.bo->tile_mode & 0xf0) << (25 - 4)); - - depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); - - if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY || - mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) { - tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride; - depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; - } + ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) | + ((mt->level[0].tile_mode & 0xf00) << (25 - 8)); switch (mt->base.base.target) { case PIPE_TEXTURE_1D: @@ -196,7 +199,7 @@ nv50_create_sampler_view(struct pipe_context *pipe, static boolean nv50_validate_tic(struct nv50_context *nv50, int s) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nouveau_bo *txc = nv50->screen->txc; unsigned i; boolean need_flush = FALSE; @@ -206,53 +209,46 @@ nv50_validate_tic(struct nv50_context *nv50, int s) struct nv04_resource *res; if (!tic) { - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (i << 1) | 0); + BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (i << 1) | 0); continue; } res = &nv50_miptree(tic->pipe.texture)->base; if (tic->id < 0) { - uint32_t offset = tic->tic[1]; - tic->id = nv50_screen_tic_alloc(nv50->screen, tic); - MARK_RING (chan, 24 + 8, 4); - BEGIN_RING(chan, RING_2D(DST_FORMAT), 2); - OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_2D(DST_PITCH), 5); - OUT_RING (chan, 262144); - OUT_RING (chan, 65536); - OUT_RING (chan, 1); - OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); - BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10); - OUT_RING (chan, 32); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, tic->id * 32); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8); - OUT_RING (chan, tic->tic[0]); - OUT_RELOCl(chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOC (chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]); - OUT_RINGp (chan, &tic->tic[3], 5); + BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2); + PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(DST_PITCH), 5); + PUSH_DATA (push, 262144); + PUSH_DATA (push, 65536); + PUSH_DATA (push, 1); + PUSH_DATAh(push, txc->offset); + PUSH_DATA (push, txc->offset); + BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM); + BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, 32); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, tic->id * 32); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NI04(push, NV50_2D(SIFC_DATA), 8); + PUSH_DATAp(push, &tic->tic[0], 8); need_flush = TRUE; } else if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { - BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0x20); //(tic->id << 4) | 1); + BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, 0x20); } nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); @@ -260,15 +256,14 @@ nv50_validate_tic(struct nv50_context *nv50, int s) res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING; res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; - nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BCTX_REFN(nv50->bufctx_3d, TEXTURES, res, RD); - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (tic->id << 9) | (i << 1) | 1); + BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1); } for (; i < nv50->state.num_textures[s]; ++i) { - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (i << 1) | 0); + BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (i << 1) | 0); } nv50->state.num_textures[s] = nv50->num_textures[s]; @@ -283,15 +278,15 @@ void nv50_validate_textures(struct nv50_context *nv50) need_flush |= nv50_validate_tic(nv50, 2); if (need_flush) { - BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1); - OUT_RING (nv50->screen->base.channel, 0); + BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TIC_FLUSH), 1); + PUSH_DATA (nv50->base.pushbuf, 0); } } static boolean nv50_validate_tsc(struct nv50_context *nv50, int s) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; unsigned i; boolean need_flush = FALSE; @@ -299,8 +294,8 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]); if (!tsc) { - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (i << 4) | 0); + BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (i << 4) | 0); continue; } if (tsc->id < 0) { @@ -313,12 +308,12 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) } nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1); + BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1); } for (; i < nv50->state.num_samplers[s]; ++i) { - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (i << 4) | 0); + BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (i << 4) | 0); } nv50->state.num_samplers[s] = nv50->num_samplers[s]; @@ -333,7 +328,7 @@ void nv50_validate_samplers(struct nv50_context *nv50) need_flush |= nv50_validate_tsc(nv50, 2); if (need_flush) { - BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1); - OUT_RING (nv50->screen->base.channel, 0); + BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TSC_FLUSH), 1); + PUSH_DATA (nv50->base.pushbuf, 0); } } diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 6f860e73348..b960dc0d191 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -50,12 +50,13 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect, } void -nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, +nv50_m2mf_transfer_rect(struct nv50_context *nv50, const struct nv50_m2mf_rect *dst, const struct nv50_m2mf_rect *src, uint32_t nblocksx, uint32_t nblocksy) { - struct nouveau_channel *chan = nouveau_screen(pscreen)->channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; + struct nouveau_bufctx *bctx = nv50->bufctx; const int cpp = dst->cpp; uint32_t src_ofst = src->base; uint32_t dst_ofst = dst->base; @@ -65,76 +66,81 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, assert(dst->cpp == src->cpp); - if (nouveau_bo_tile_layout(src->bo)) { - BEGIN_RING(chan, RING_MF(LINEAR_IN), 6); - OUT_RING (chan, 0); - OUT_RING (chan, src->tile_mode << 4); - OUT_RING (chan, src->width * cpp); - OUT_RING (chan, src->height); - OUT_RING (chan, src->depth); - OUT_RING (chan, src->z); + nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD); + nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); + + if (nouveau_bo_memtype(src->bo)) { + BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6); + PUSH_DATA (push, 0); + PUSH_DATA (push, src->tile_mode); + PUSH_DATA (push, src->width * cpp); + PUSH_DATA (push, src->height); + PUSH_DATA (push, src->depth); + PUSH_DATA (push, src->z); } else { src_ofst += src->y * src->pitch + src->x * cpp; - BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1); - OUT_RING (chan, src->pitch); + BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_IN), 1); + PUSH_DATA (push, src->pitch); } - if (nouveau_bo_tile_layout(dst->bo)) { - BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6); - OUT_RING (chan, 0); - OUT_RING (chan, dst->tile_mode << 4); - OUT_RING (chan, dst->width * cpp); - OUT_RING (chan, dst->height); - OUT_RING (chan, dst->depth); - OUT_RING (chan, dst->z); + if (nouveau_bo_memtype(dst->bo)) { + BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 6); + PUSH_DATA (push, 0); + PUSH_DATA (push, dst->tile_mode); + PUSH_DATA (push, dst->width * cpp); + PUSH_DATA (push, dst->height); + PUSH_DATA (push, dst->depth); + PUSH_DATA (push, dst->z); } else { dst_ofst += dst->y * dst->pitch + dst->x * cpp; - BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1); - OUT_RING (chan, dst->pitch); + BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_OUT), 1); + PUSH_DATA (push, dst->pitch); } while (height) { int line_count = height > 2047 ? 2047 : height; - MARK_RING (chan, 17, 4); + BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATAh(push, src->bo->offset + src_ofst); + PUSH_DATAh(push, dst->bo->offset + dst_ofst); - BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); - OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); - OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2); + PUSH_DATA (push, src->bo->offset + src_ofst); + PUSH_DATA (push, dst->bo->offset + dst_ofst); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2); - OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); - - if (nouveau_bo_tile_layout(src->bo)) { - BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1); - OUT_RING (chan, (sy << 16) | (src->x * cpp)); + if (nouveau_bo_memtype(src->bo)) { + BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_IN), 1); + PUSH_DATA (push, (sy << 16) | (src->x * cpp)); } else { src_ofst += line_count * src->pitch; } - if (nouveau_bo_tile_layout(dst->bo)) { - BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1); - OUT_RING (chan, (dy << 16) | (dst->x * cpp)); + if (nouveau_bo_memtype(dst->bo)) { + BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_OUT), 1); + PUSH_DATA (push, (dy << 16) | (dst->x * cpp)); } else { dst_ofst += line_count * dst->pitch; } - BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4); - OUT_RING (chan, nblocksx * cpp); - OUT_RING (chan, line_count); - OUT_RING (chan, (1 << 8) | (1 << 0)); - OUT_RING (chan, 0); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4); + PUSH_DATA (push, nblocksx * cpp); + PUSH_DATA (push, line_count); + PUSH_DATA (push, (1 << 8) | (1 << 0)); + PUSH_DATA (push, 0); height -= line_count; sy += line_count; dy += line_count; } + + nouveau_bufctx_reset(bctx, 0); } void @@ -142,55 +148,60 @@ nv50_sifc_linear_u8(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, const void *data) { - struct nouveau_channel *chan = nv->screen->channel; + struct nv50_context *nv50 = nv50_context(&nv->pipe); + struct nouveau_pushbuf *push = nv50->base.pushbuf; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; unsigned xcoord = offset & 0xff; + nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, nv50->bufctx); + nouveau_pushbuf_validate(push); + offset &= ~0xff; - MARK_RING (chan, 23, 4); - BEGIN_RING(chan, RING_2D(DST_FORMAT), 2); - OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_2D(DST_PITCH), 5); - OUT_RING (chan, 262144); - OUT_RING (chan, 65536); - OUT_RING (chan, 1); - OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2); - OUT_RING (chan, 0); - OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM); - BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10); - OUT_RING (chan, size); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, xcoord); - OUT_RING (chan, 0); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2); + PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(DST_PITCH), 5); + PUSH_DATA (push, 262144); + PUSH_DATA (push, 65536); + PUSH_DATA (push, 1); + PUSH_DATAh(push, dst->offset + offset); + PUSH_DATA (push, dst->offset + offset); + BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM); + BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, size); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, xcoord); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); while (count) { - unsigned nr = AVAIL_RING(chan); + unsigned nr; - if (nr < 9) { - FIRE_RING(chan); - nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR); - continue; - } + if (!PUSH_SPACE(push, 16)) + break; + nr = PUSH_AVAIL(push); + assert(nr >= 16); nr = MIN2(count, nr - 1); nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); - BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr); - OUT_RINGp (chan, src, nr); + BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr); + PUSH_DATAp(push, src, nr); src += nr; count -= nr; } + + nouveau_bufctx_reset(nv50->bufctx, 0); } void @@ -199,33 +210,40 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nouveau_channel *chan = nv->screen->channel; + struct nouveau_pushbuf *push = nv->pushbuf; + struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx; + + nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD); + nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); - BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1); + PUSH_DATA (push, 1); while (size) { unsigned bytes = MIN2(size, 1 << 17); - MARK_RING (chan, 11, 4); - BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); - OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); - OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2); - OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4); - OUT_RING (chan, bytes); - OUT_RING (chan, 1); - OUT_RING (chan, (1 << 8) | (1 << 0)); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATAh(push, src->offset + srcoff); + PUSH_DATAh(push, dst->offset + dstoff); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2); + PUSH_DATA (push, src->offset + srcoff); + PUSH_DATA (push, dst->offset + dstoff); + BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4); + PUSH_DATA (push, bytes); + PUSH_DATA (push, 1); + PUSH_DATA (push, (1 << 8) | (1 << 0)); + PUSH_DATA (push, 0); srcoff += bytes; dstoff += bytes; size -= bytes; } + + nouveau_bufctx_reset(bctx, 0); } struct pipe_transfer * @@ -236,7 +254,6 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, const struct pipe_box *box) { struct nv50_context *nv50 = nv50_context(pctx); - struct pipe_screen *pscreen = pctx->screen; struct nouveau_device *dev = nv50->screen->base.device; const struct nv50_miptree *mt = nv50_miptree(res); struct nv50_transfer *tx; @@ -272,7 +289,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, size = tx->base.layer_stride; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, - size * tx->base.box.depth, &tx->rect[1].bo); + size * tx->base.box.depth, NULL, &tx->rect[1].bo); if (ret) { FREE(tx); return NULL; @@ -290,7 +307,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, unsigned z = tx->rect[0].z; unsigned i; for (i = 0; i < box->depth; ++i) { - nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0], + nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0], tx->nblocksx, tx->nblocksy); if (mt->layout_3d) tx->rect[0].z++; @@ -310,14 +327,14 @@ void nv50_miptree_transfer_del(struct pipe_context *pctx, struct pipe_transfer *transfer) { - struct pipe_screen *pscreen = pctx->screen; + struct nv50_context *nv50 = nv50_context(pctx); struct nv50_transfer *tx = (struct nv50_transfer *)transfer; struct nv50_miptree *mt = nv50_miptree(tx->base.resource); unsigned i; if (tx->base.usage & PIPE_TRANSFER_WRITE) { for (i = 0; i < tx->base.box.depth; ++i) { - nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1], + nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1], tx->nblocksx, tx->nblocksy); if (mt->layout_3d) tx->rect[0].z++; @@ -337,6 +354,7 @@ void * nv50_miptree_transfer_map(struct pipe_context *pctx, struct pipe_transfer *transfer) { + struct nv50_screen *screen = nv50_screen(pctx->screen); struct nv50_transfer *tx = (struct nv50_transfer *)transfer; int ret; unsigned flags = 0; @@ -349,7 +367,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx, if (transfer->usage & PIPE_TRANSFER_WRITE) flags |= NOUVEAU_BO_WR; - ret = nouveau_bo_map(tx->rect[1].bo, flags); + ret = nouveau_bo_map(tx->rect[1].bo, flags, screen->base.client); if (ret) return NULL; return tx->rect[1].bo->map; @@ -359,9 +377,7 @@ void nv50_miptree_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer) { - struct nv50_transfer *tx = (struct nv50_transfer *)transfer; - - nouveau_bo_unmap(tx->rect[1].bo); + /* nothing to do */ } void @@ -370,30 +386,36 @@ nv50_cb_push(struct nouveau_context *nv, unsigned base, unsigned size, unsigned offset, unsigned words, const uint32_t *data) { - struct nouveau_channel *chan = nv->screen->channel; + struct nouveau_pushbuf *push = nv->pushbuf; + struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx; assert(!(offset & 3)); size = align(size, 0x100); + nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); + while (words) { unsigned nr; - MARK_RING(chan, 24, 2); - nr = AVAIL_RING(chan); + nr = PUSH_AVAIL(push); 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); + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, bo->offset + base); + PUSH_DATA (push, bo->offset + base); + PUSH_DATA (push, (NV50_CB_TMP << 16) | (size & 0xffff)); + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, (offset << 6) | NV50_CB_TMP); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr); + PUSH_DATAp(push, data, nr); words -= nr; data += nr; offset += nr * 4; } + + nouveau_bufctx_reset(bctx, 0); } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index cb3ea382f3d..9be43ef15d4 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -124,7 +124,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, struct pipe_vertex_element *ve, unsigned attr) { const void *data; - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv04_resource *res = nv04_resource(vb->buffer); float v[4]; const unsigned nc = util_format_get_nr_components(ve->src_format); @@ -136,30 +136,30 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, switch (nc) { case 4: - BEGIN_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4); - OUT_RINGf (chan, v[0]); - OUT_RINGf (chan, v[1]); - OUT_RINGf (chan, v[2]); - OUT_RINGf (chan, v[3]); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_4F_X(attr)), 4); + PUSH_DATAf(push, v[0]); + PUSH_DATAf(push, v[1]); + PUSH_DATAf(push, v[2]); + PUSH_DATAf(push, v[3]); break; case 3: - BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3); - OUT_RINGf (chan, v[0]); - OUT_RINGf (chan, v[1]); - OUT_RINGf (chan, v[2]); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(attr)), 3); + PUSH_DATAf(push, v[0]); + PUSH_DATAf(push, v[1]); + PUSH_DATAf(push, v[2]); break; case 2: - BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2); - OUT_RINGf (chan, v[0]); - OUT_RINGf (chan, v[1]); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(attr)), 2); + PUSH_DATAf(push, v[0]); + PUSH_DATAf(push, v[1]); break; case 1: if (attr == nv50->vertprog->vp.edgeflag) { - BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); - OUT_RING (chan, v[0] ? 1 : 0); + BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); + PUSH_DATA (push, v[0] ? 1 : 0); } - BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1); - OUT_RINGf (chan, v[0]); + BEGIN_NV04(push, NV50_3D(VTX_ATTR_1F(attr)), 1); + PUSH_DATAf(push, v[0]); break; default: assert(0); @@ -193,7 +193,7 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) nv50->vbo_fifo = nv50->vbo_user = 0; - nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX); for (i = 0; i < nv50->num_vtxbufs; ++i) { vb = &nv50->vtxbuf[i]; @@ -211,33 +211,37 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) nv50->vbo_user |= 1 << i; assert(vb->stride > vb->buffer_offset); nv50_vbuf_range(nv50, i, &base, &size); - nouveau_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(&nv50->base, buf, base, size); } else { nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART); } nv50->base.vbo_dirty = TRUE; } } - nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); + BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD); } } static void nv50_update_user_vbufs(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; uint32_t base, offset, size; int i; uint32_t written = 0; + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX); + for (i = 0; i < nv50->vertex->num_elements; ++i) { 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 nv04_resource *buf = nv04_resource(vb->buffer); - if (!(nv50->vbo_user & (1 << b))) + if (!(nv50->vbo_user & (1 << b))) { + BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD); continue; + } if (!vb->stride) { nv50_emit_vtxattr(nv50, vb, ve, i); @@ -247,17 +251,18 @@ nv50_update_user_vbufs(struct nv50_context *nv50) if (!(written & (1 << b))) { written |= 1 << b; - nouveau_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(&nv50->base, buf, base, size); } offset = vb->buffer_offset + ve->src_offset; - MARK_RING (chan, 6, 4); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); - OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD); - OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2); - OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); - OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); + PUSH_DATAh(push, buf->address + base + size - 1); + PUSH_DATA (push, buf->address + base + size - 1); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2); + PUSH_DATAh(push, buf->address + offset); + PUSH_DATA (push, buf->address + offset); + + BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD); } nv50->base.vbo_dirty = TRUE; } @@ -278,7 +283,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50) void nv50_vertex_arrays_validate(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_vertex_stateobj *vertex = nv50->vertex; struct pipe_vertex_buffer *vb; struct nv50_vertex_element *ve; @@ -291,15 +296,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) nv50_prevalidate_vbufs(nv50); } - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements); for (i = 0; i < vertex->num_elements; ++i) { ve = &vertex->element[i]; vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index]; if (likely(vb->stride) || nv50->vbo_fifo) { - OUT_RING(chan, ve->state); + PUSH_DATA(push, ve->state); } else { - OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST); + PUSH_DATA(push, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST); nv50->vbo_fifo &= ~(1 << i); } } @@ -313,15 +318,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) if (unlikely(ve->pipe.instance_divisor)) { if (!(nv50->state.instance_elts & (1 << i))) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); - OUT_RING (chan, 1); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + PUSH_DATA (push, 1); } - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1); - OUT_RING (chan, ve->pipe.instance_divisor); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_DIVISOR(i)), 1); + PUSH_DATA (push, ve->pipe.instance_divisor); } else if (unlikely(nv50->state.instance_elts & (1 << i))) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + PUSH_DATA (push, 0); } res = nv04_resource(vb->buffer); @@ -329,33 +334,32 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) if (nv50->vbo_fifo || unlikely(vb->stride == 0)) { if (!nv50->vbo_fifo) nv50_emit_vtxattr(nv50, vb, &ve->pipe, i); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, 0); continue; } size = vb->buffer->width0; offset = ve->pipe.src_offset + vb->buffer_offset; - MARK_RING (chan, 8, 4); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); - OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2); - OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2); + PUSH_DATAh(push, res->address + size - 1); + PUSH_DATA (push, res->address + size - 1); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2); + PUSH_DATAh(push, res->address + offset); + PUSH_DATA (push, res->address + offset); } for (; i < nv50->state.num_vtxelts; ++i) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1); - OUT_RING (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(i)), 1); + PUSH_DATA (push, NV50_3D_VERTEX_ATTRIB_INACTIVE); if (unlikely(nv50->state.instance_elts & (1 << i))) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + PUSH_DATA (push, 0); } - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, 0); } nv50->state.num_vtxelts = vertex->num_elements; @@ -389,65 +393,55 @@ nv50_prim_gl(unsigned prim) } } -static void -nv50_draw_vbo_flush_notify(struct nouveau_channel *chan) -{ - struct nv50_screen *screen = chan->user_private; - - nouveau_fence_update(&screen->base, TRUE); - - nv50_bufctx_emit_relocs(screen->cur_ctx); -} - static void nv50_draw_arrays(struct nv50_context *nv50, unsigned mode, unsigned start, unsigned count, unsigned instance_count) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; unsigned prim; if (nv50->state.index_bias) { - BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1); + PUSH_DATA (push, 0); nv50->state.index_bias = 0; } prim = nv50_prim_gl(mode); while (instance_count--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, prim); - BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2); - OUT_RING (chan, start); - OUT_RING (chan, count); - BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, prim); + BEGIN_NV04(push, NV50_3D(VERTEX_BUFFER_FIRST), 2); + PUSH_DATA (push, start); + PUSH_DATA (push, count); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } static void -nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, +nv50_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map, unsigned start, unsigned count) { map += start; if (count & 3) { unsigned i; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3); + BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), count & 3); for (i = 0; i < (count & 3); ++i) - OUT_RING(chan, *map++); + PUSH_DATA(push, *map++); count &= ~3; } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr); + BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U8), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, - (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]); + PUSH_DATA(push, + (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]); map += 4; } count -= nr * 4; @@ -455,22 +449,22 @@ nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, } static void -nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, +nv50_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map, unsigned start, unsigned count) { map += start; if (count & 1) { count &= ~1; - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (chan, *map++); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (push, *map++); } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, (map[1] << 16) | map[0]); + PUSH_DATA(push, (map[1] << 16) | map[0]); map += 2; } count -= nr * 2; @@ -478,7 +472,7 @@ nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, } static void -nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, +nv50_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map, unsigned start, unsigned count) { map += start; @@ -486,8 +480,8 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, while (count) { const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN); - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr); - OUT_RINGp (chan, map, nr); + BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), nr); + PUSH_DATAp(push, map, nr); map += nr; count -= nr; @@ -495,22 +489,22 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, } static void -nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map, +nv50_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map, unsigned start, unsigned count) { map += start; if (count & 1) { count--; - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (chan, *map++); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (push, *map++); } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, (map[1] << 16) | map[0]); + PUSH_DATA(push, (map[1] << 16) | map[0]); map += 2; } count -= nr * 2; @@ -522,121 +516,116 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, unsigned mode, unsigned start, unsigned count, unsigned instance_count, int32_t index_bias) { - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; void *data; + struct nv04_resource *buf = nv04_resource(nv50->idxbuf.buffer); unsigned prim; const unsigned index_size = nv50->idxbuf.index_size; prim = nv50_prim_gl(mode); if (index_bias != nv50->state.index_bias) { - BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1); - OUT_RING (chan, index_bias); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1); + PUSH_DATA (push, index_bias); nv50->state.index_bias = index_bias; } if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) { - struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); + unsigned pb_start; + unsigned pb_bytes; + const unsigned base = buf->offset; start += nv50->idxbuf.offset >> (index_size >> 1); while (instance_count--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, mode); + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, prim); + + nouveau_pushbuf_space(push, 8, 0, 1); switch (index_size) { case 4: - { - WAIT_RING (chan, 2); - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0); - OUT_RING (chan, count); - nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4, - count * 4); - } + BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U32), count); + nouveau_pushbuf_data(push, buf->bo, base + start * 4, count * 4); break; case 2: - { - unsigned pb_start = (start & ~1); - unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1; - - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); - OUT_RING (chan, (start << 31) | count); - WAIT_RING (chan, 2); - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0); - OUT_RING (chan, pb_words); - nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2, - pb_words * 4); - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); - OUT_RING (chan, 0); - break; - } - case 1: - { - unsigned pb_start = (start & ~3); - unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1; - - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); - OUT_RING (chan, (start << 30) | count); - WAIT_RING (chan, 2); - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0); - OUT_RING (chan, pb_words); - nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start, - pb_words * 4); - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); - OUT_RING (chan, 0); + pb_start = (start & ~1) * 2; + pb_bytes = ((start + count + 1) & ~1) * 2 - pb_start; + + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1); + PUSH_DATA (push, (start << 31) | count); + BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U16), pb_bytes / 4); + nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1); + PUSH_DATA (push, 0); break; - } default: - assert(0); - return; + assert(index_size == 1); + pb_start = start & ~3; + pb_bytes = ((start + count + 3) & ~3) - pb_start; + + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1); + PUSH_DATA (push, (start << 30) | count); + BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U8), pb_bytes / 4); + nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes); + BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1); + PUSH_DATA (push, 0); + break; } - BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); - nv50_resource_fence(res, NOUVEAU_BO_RD); - - mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; + prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nouveau_resource_map_offset(&nv50->base, - nv04_resource(nv50->idxbuf.buffer), + data = nouveau_resource_map_offset(&nv50->base, buf, nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!data) return; while (instance_count--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, prim); + BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, prim); switch (index_size) { case 1: - nv50_draw_elements_inline_u08(chan, data, start, count); + nv50_draw_elements_inline_u08(push, data, start, count); break; case 2: - nv50_draw_elements_inline_u16(chan, data, start, count); + nv50_draw_elements_inline_u16(push, data, start, count); break; case 4: if (shorten) - nv50_draw_elements_inline_u32_short(chan, data, start, count); + nv50_draw_elements_inline_u32_short(push, data, start, count); else - nv50_draw_elements_inline_u32(chan, data, start, count); + nv50_draw_elements_inline_u32(push, data, start, count); break; default: assert(0); return; } - BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); + PUSH_DATA (push, 0); prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } } +static void +nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan) +{ + struct nv50_screen *screen = chan->user_priv; + + nouveau_fence_update(&screen->base, TRUE); + + nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE); +} + void nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_pushbuf *push = nv50->base.pushbuf; /* For picking only a few vertices from a large user buffer, push is better, * if index count is larger and we expect repeated vertices, suggest upload. @@ -656,24 +645,25 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */ - chan->flush_notify = nv50_draw_vbo_flush_notify; + push->kick_notify = nv50_draw_vbo_kick_notify; if (nv50->vbo_fifo) { nv50_push_vbo(nv50, info); - chan->flush_notify = nv50_default_flush_notify; + push->kick_notify = nv50_default_kick_notify; + nouveau_pushbuf_bufctx(push, NULL); return; } if (nv50->state.instance_base != info->start_instance) { nv50->state.instance_base = info->start_instance; /* NOTE: this does not affect the shader input, should it ? */ - BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1); - OUT_RING (chan, info->start_instance); + BEGIN_NV04(push, NV50_3D(VB_INSTANCE_BASE), 1); + PUSH_DATA (push, info->start_instance); } if (nv50->base.vbo_dirty) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1); + PUSH_DATA (push, 0); nv50->base.vbo_dirty = FALSE; } @@ -688,21 +678,21 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (info->primitive_restart != nv50->state.prim_restart) { if (info->primitive_restart) { - BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2); - OUT_RING (chan, 1); - OUT_RING (chan, info->restart_index); + BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 2); + PUSH_DATA (push, 1); + PUSH_DATA (push, info->restart_index); if (info->restart_index > 65535) shorten = FALSE; } else { - BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 1); + PUSH_DATA (push, 0); } nv50->state.prim_restart = info->primitive_restart; } else if (info->primitive_restart) { - BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1); - OUT_RING (chan, info->restart_index); + BEGIN_NV04(push, NV50_3D(PRIM_RESTART_INDEX), 1); + PUSH_DATA (push, info->restart_index); if (info->restart_index > 65535) shorten = FALSE; @@ -712,7 +702,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, info->instance_count, info->index_bias); } - chan->flush_notify = nv50_default_flush_notify; + push->kick_notify = nv50_default_kick_notify; nv50_release_user_vbufs(nv50); + + nouveau_pushbuf_bufctx(push, NULL); } diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index 694c78a2fbd..b36898dabe6 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -7,100 +7,118 @@ #include "pipe/p_defines.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" -#include "nouveau/nouveau_reloc.h" -#include "nouveau/nouveau_notifier.h" - +#include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_buffer.h" + #ifndef NV04_PFIFO_MAX_PACKET_LEN #define NV04_PFIFO_MAX_PACKET_LEN 2047 #endif -#define NV50_SUBCH_3D 5 -#define NV50_SUBCH_2D 6 -#define NV50_SUBCH_MF 7 -#define NV50_MF_(n) NV50_M2MF_##n +static INLINE void +nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin, + unsigned flags, struct nouveau_bo *bo) +{ + nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL; +} + +static INLINE void +nv50_add_bufctx_resident(struct nouveau_bufctx *bufctx, int bin, + struct nv04_resource *res, unsigned flags) +{ + struct nouveau_bufref *ref = + nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain); + ref->priv = res; + ref->priv_data = flags; +} + +#define BCTX_REFN_bo(ctx, bin, fl, bo) \ + nv50_add_bufctx_resident_bo(ctx, NV50_BIND_##bin, fl, bo); + +#define BCTX_REFN(bctx, bin, res, acc) \ + nv50_add_bufctx_resident(bctx, NV50_BIND_##bin, res, NOUVEAU_BO_##acc) + +static INLINE void +PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_pushbuf_refn ref = { bo, flags }; + nouveau_pushbuf_refn(push, &ref, 1); +} + + +#define SUBC_3D(m) 3, (m) +#define NV50_3D(n) SUBC_3D(NV50_3D_##n) -#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n) -#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n) -#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n)) +#define SUBC_2D(m) 4, (m) +#define NV50_2D(n) SUBC_2D(NV50_2D_##n) -#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m)) -#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m)) -#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m)) +#define SUBC_M2MF(m) 5, (m) +#define NV50_M2MF(n) SUBC_M2MF(NV50_M2MF_##n) -#define RING_GR(gr, m) (((gr)->subc << 13) | (m)) +#define SUBC_COMPUTE(m) 6, (m) +#define NV50_COMPUTE(n) SUBC_COMPUTE(NV50_COMPUTE_##n) -int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); -static inline uint32_t -nouveau_bo_tile_layout(const struct nouveau_bo *bo) +static INLINE uint32_t +NV50_FIFO_PKHDR(int subc, int mthd, unsigned size) { - return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK; + return 0x00000000 | (size << 18) | (subc << 13) | mthd; } -static INLINE void -nouveau_bo_validate(struct nouveau_channel *chan, - struct nouveau_bo *bo, unsigned flags) +static INLINE uint32_t +NV50_FIFO_PKHDR_NI(int subc, int mthd, unsigned size) { - nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0); + return 0x40000000 | (size << 18) | (subc << 13) | mthd; } -/* incremental methods */ -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size) +static INLINE uint32_t +NV50_FIFO_PKHDR_L(int subc, int mthd) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, (size << 18) | mthd); + return 0x00030000 | (subc << 13) | mthd; } -/* non-incremental */ -static INLINE void -BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size) + +static INLINE uint32_t +nouveau_bo_memtype(const struct nouveau_bo *bo) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd); + return bo->config.nv50.memtype; } -static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res, - unsigned delta, unsigned flags) + +static INLINE void +PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data) { - return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags); + *push->cur++ = (uint32_t)(data >> 32); } -static INLINE int -OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, - unsigned delta, unsigned flags) +static INLINE void +BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) { - if (flags & NOUVEAU_BO_WR) - res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; - return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); +#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, size + 1); +#endif + PUSH_DATA (push, NV50_FIFO_PKHDR(subc, mthd, size)); } static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s) +BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) { - struct nouveau_subchannel *subc = &gr->channel->subc[s]; - - assert(s < 8); - if (subc->gr) { - assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT); - subc->gr->bound = NOUVEAU_GROBJ_UNBOUND; - } - subc->gr = gr; - subc->gr->subc = s; - subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; - - BEGIN_RING(chan, RING_GR(gr, 0x0000), 1); - OUT_RING (chan, gr->handle); +#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, size + 1); +#endif + PUSH_DATA (push, NV50_FIFO_PKHDR_NI(subc, mthd, size)); } +/* long, non-incremental, nv50-only */ +static INLINE void +BEGIN_NL50(struct nouveau_pushbuf *push, int subc, int mthd, uint32_t size) +{ +#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, 2); #endif + PUSH_DATA (push, NV50_FIFO_PKHDR_L(subc, mthd)); + PUSH_DATA (push, size); +} + +#endif /* __NV50_WINSYS_H__ */ diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 6a1dff70f76..18d27865d71 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -153,13 +153,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_LOCAL_BASE 0x0000077c -#define NVC0_3D_LOCAL_ADDRESS_HIGH 0x00000790 +#define NVC0_3D_TEMP_ADDRESS_HIGH 0x00000790 -#define NVC0_3D_LOCAL_ADDRESS_LOW 0x00000794 +#define NVC0_3D_TEMP_ADDRESS_LOW 0x00000794 -#define NVC0_3D_LOCAL_SIZE_HIGH 0x00000798 +#define NVC0_3D_TEMP_SIZE_HIGH 0x00000798 -#define NVC0_3D_LOCAL_SIZE_LOW 0x0000079c +#define NVC0_3D_TEMP_SIZE_LOW 0x0000079c + +#define NVC0_3D_WARP_TEMP_ALLOC 0x000007a0 + +#define NVC0_3D_ZCULL_WIDTH 0x000007c0 + +#define NVC0_3D_ZCULL_HEIGHT 0x000007c4 + +#define NVC0_3D_ZCULL_ADDRESS_HIGH 0x000007e8 + +#define NVC0_3D_ZCULL_ADDRESS_LOW 0x000007ec + +#define NVC0_3D_ZCULL_LIMIT_HIGH 0x000007f0 + +#define NVC0_3D_ZCULL_LIMIT_LOW 0x000007f4 #define NVC0_3D_RT(i0) (0x00000800 + 0x40*(i0)) #define NVC0_3D_RT__ESIZE 0x00000040 @@ -772,6 +786,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_TIC_LIMIT 0x0000157c +#define NVC0_3D_ZCULL_REGION 0x00001590 + #define NVC0_3D_STENCIL_TWO_SIDE_ENABLE 0x00001594 #define NVC0_3D_STENCIL_BACK_OP_FAIL 0x00001598 @@ -856,7 +872,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_END_D3D_UNK0 0x00000001 #define NVC0_3D_VERTEX_END_D3D_UNK1 0x00000002 -#define NVC0_3D_EDGEFLAG_ENABLE 0x000015e4 +#define NVC0_3D_EDGEFLAG 0x000015e4 #define NVC0_3D_VB_ELEMENT_U32 0x000015e8 @@ -876,6 +892,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_BASE_LOW 0x000015f8 +#define NVC0_3D_ZCULL_WINDOW_OFFSET_X 0x000015fc + +#define NVC0_3D_ZCULL_WINDOW_OFFSET_Y 0x00001600 + #define NVC0_3D_POINT_COORD_REPLACE 0x00001604 #define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__MASK 0x00000004 #define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__SHIFT 2 @@ -1070,6 +1090,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_CLIP_RECTS_MODE_OUTSIDE_ALL 0x00000001 #define NVC0_3D_CLIP_RECTS_MODE_NEVER 0x00000002 +#define NVC0_3D_ZCULL_INVALIDATE 0x00001958 + +#define NVC0_3D_ZCULL_TEST_MASK 0x0000196c +#define NVC0_3D_ZCULL_TEST_MASK_FAIL_GT_PASS_LT 0x00000001 +#define NVC0_3D_ZCULL_TEST_MASK_PASS_GT_FAIL_LT 0x00000010 + #define NVC0_3D_FP_ZORDER_CTRL 0x0000196c #define NVC0_3D_FP_ZORDER_CTRL_0 0x00000001 #define NVC0_3D_FP_ZORDER_CTRL_1 0x00000010 @@ -1082,11 +1108,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_CLIPID_ID 0x00001984 -#define NVC0_3D_FP_CONTROL 0x000019a8 -#define NVC0_3D_FP_CONTROL_MULTIPLE_RESULTS 0x00000001 -#define NVC0_3D_FP_CONTROL_EXPORTS_Z 0x00000100 -#define NVC0_3D_FP_CONTROL_USES_KIL 0x00100000 - #define NVC0_3D_DEPTH_BOUNDS_EN 0x000019bc #define NVC0_3D_LOGIC_OP_ENABLE 0x000019c4 diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index 1b3a06dfa33..c15d0256c60 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -33,26 +33,22 @@ static void nvc0_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { - struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base; + struct nvc0_context *nvc0 = nvc0_context(pipe); + struct nouveau_screen *screen = &nvc0->screen->base; if (fence) nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); - /* Try to emit before firing to avoid having to flush again right after - * in case we have to wait on this fence. - */ - nouveau_fence_emit(screen->fence.current); - - FIRE_RING(screen->channel); + PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */ } static void nvc0_texture_barrier(struct pipe_context *pipe) { - struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel; + struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf; - IMMED_RING(chan, RING_3D(SERIALIZE), 0); - IMMED_RING(chan, RING_3D(TEX_CACHE_CTL), 0); + IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0); + IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0); } static void @@ -60,8 +56,8 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0) { unsigned s, i; - for (i = 0; i < NVC0_BUFCTX_COUNT; ++i) - nvc0_bufctx_reset(nvc0, i); + nouveau_bufctx_del(&nvc0->bufctx_3d); + nouveau_bufctx_del(&nvc0->bufctx); for (i = 0; i < nvc0->num_vtxbufs; ++i) pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL); @@ -85,26 +81,31 @@ nvc0_destroy(struct pipe_context *pipe) { struct nvc0_context *nvc0 = nvc0_context(pipe); + if (nvc0->screen->cur_ctx == nvc0) { + nvc0->base.pushbuf->kick_notify = NULL; + nvc0->screen->cur_ctx = NULL; + nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL); + } + nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel); + nvc0_context_unreference_resources(nvc0); draw_destroy(nvc0->draw); - if (nvc0->screen->cur_ctx == nvc0) - nvc0->screen->cur_ctx = NULL; - FREE(nvc0); } void -nvc0_default_flush_notify(struct nouveau_channel *chan) +nvc0_default_kick_notify(struct nouveau_pushbuf *push) { - struct nvc0_screen *screen = chan->user_private; - - if (!screen) - return; + struct nvc0_screen *screen = push->user_priv; - nouveau_fence_update(&screen->base, TRUE); - nouveau_fence_next(&screen->base); + if (screen) { + nouveau_fence_next(&screen->base); + nouveau_fence_update(&screen->base, TRUE); + if (screen->cur_ctx) + screen->cur_ctx->state.flushed = TRUE; + } } struct pipe_context * @@ -113,12 +114,23 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; struct pipe_context *pipe; + int ret; + uint32_t flags; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; pipe = &nvc0->base.pipe; + nvc0->base.pushbuf = screen->base.pushbuf; + + ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT, + &nvc0->bufctx_3d); + if (!ret) + nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx); + if (ret) + goto out_err; + nvc0->screen = screen; nvc0->base.screen = &screen->base; nvc0->base.copy_data = nvc0_m2mf_copy_linear; @@ -136,9 +148,11 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) pipe->flush = nvc0_flush; pipe->texture_barrier = nvc0_texture_barrier; - if (!screen->cur_ctx) + if (!screen->cur_ctx) { screen->cur_ctx = nvc0; - screen->base.channel->flush_notify = nvc0_default_flush_notify; + nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx); + } + screen->base.pushbuf->kick_notify = nvc0_default_kick_notify; nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); @@ -154,72 +168,43 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) /* shader builtin library is per-screen, but we need a context for m2mf */ nvc0_program_library_upload(nvc0); - return pipe; -} + /* add permanently resident buffers to bufctxts */ -struct resident { - struct nv04_resource *res; - uint32_t flags; -}; + flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; -void -nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, - struct nv04_resource *resource, uint32_t flags) -{ - struct resident rsd = { resource, flags }; + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text); + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniforms); + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc); - if (!resource->bo) - return; - nvc0->residents_size += sizeof(struct resident); + flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR; - /* We don't need to reference the resource here, it will be referenced - * in the context/state, and bufctx will be reset when state changes. - */ - util_dynarray_append(&nvc0->residents[ctx], struct resident, rsd); -} + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo); + BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo); -void -nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx, - struct nv04_resource *resource) -{ - struct resident *rsd, *top; - unsigned i; - - for (i = 0; i < nvc0->residents[ctx].size / sizeof(struct resident); ++i) { - rsd = util_dynarray_element(&nvc0->residents[ctx], struct resident, i); - - if (rsd->res == resource) { - top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident); - if (rsd != top) - *rsd = *top; - nvc0->residents_size -= sizeof(struct resident); - break; - } + return pipe; + +out_err: + if (nvc0) { + if (nvc0->bufctx_3d) + nouveau_bufctx_del(&nvc0->bufctx_3d); + if (nvc0->bufctx) + nouveau_bufctx_del(&nvc0->bufctx); + FREE(nvc0); } + return NULL; } void -nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0) +nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx, + boolean on_flush) { - struct resident *rsd; - struct util_dynarray *array; - unsigned ctx, i, n; - - n = nvc0->residents_size / sizeof(struct resident); - n += NVC0_SCREEN_RESIDENT_BO_COUNT; - - MARK_RING(nvc0->screen->base.channel, 0, n); - - for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) { - array = &nvc0->residents[ctx]; - - n = array->size / sizeof(struct resident); - for (i = 0; i < n; ++i) { - rsd = util_dynarray_element(array, struct resident, i); - - nvc0_resource_validate(rsd->res, rsd->flags); - } + struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending; + struct nouveau_list *it; + + for (it = list->next; it != list; it = it->next) { + struct nouveau_bufref *ref = (struct nouveau_bufref *)it; + struct nv04_resource *res = ref->priv; + if (res) + nvc0_resource_validate(res, (unsigned)ref->priv_data); } - - nvc0_screen_make_buffers_resident(nvc0->screen); } diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index b8f0d92b6b4..4b35330ef8a 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -50,32 +50,40 @@ #define NVC0_NEW_TEXTURES (1 << 19) #define NVC0_NEW_SAMPLERS (1 << 20) #define NVC0_NEW_TFB_TARGETS (1 << 21) - -#define NVC0_BUFCTX_CONSTANT 0 -#define NVC0_BUFCTX_FRAME 1 -#define NVC0_BUFCTX_VERTEX 2 -#define NVC0_BUFCTX_TEXTURES 3 -#define NVC0_BUFCTX_TFB 4 -#define NVC0_BUFCTX_COUNT 5 +#define NVC0_NEW_IDXBUF (1 << 22) + +#define NVC0_BIND_FB 0 +#define NVC0_BIND_VTX 1 +#define NVC0_BIND_IDX 2 +#define NVC0_BIND_TEX 3 +#define NVC0_BIND_CB(s, i) (4 + 16 * (s) + (i)) +#define NVC0_BIND_TFB 84 +#define NVC0_BIND_SCREEN 85 +#define NVC0_BIND_TLS 86 +#define NVC0_BIND_COUNT 87 +#define NVC0_BIND_2D 0 +#define NVC0_BIND_M2MF 0 +#define NVC0_BIND_FENCE 1 struct nvc0_context { struct nouveau_context base; - struct nvc0_screen *screen; + struct nouveau_bufctx *bufctx_3d; + struct nouveau_bufctx *bufctx; - struct util_dynarray residents[NVC0_BUFCTX_COUNT]; - unsigned residents_size; + struct nvc0_screen *screen; uint32_t dirty; struct { + boolean flushed; + boolean rasterizer_discard; + boolean early_z; + boolean prim_restart; uint32_t instance_elts; /* bitmask of per-instance elements */ uint32_t instance_base; int32_t index_bias; - boolean prim_restart; - boolean early_z; uint16_t scissor; - boolean rasterizer_discard; uint8_t num_vtxbufs; uint8_t num_vtxelts; uint8_t num_textures[5]; @@ -142,20 +150,9 @@ nvc0_context(struct pipe_context *pipe) /* nvc0_context.c */ struct pipe_context *nvc0_create(struct pipe_screen *, void *); - -void nvc0_default_flush_notify(struct nouveau_channel *); - -void nvc0_bufctx_emit_relocs(struct nvc0_context *); -void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx, - struct nv04_resource *, uint32_t flags); -void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx, - struct nv04_resource *); -static INLINE void -nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx) -{ - nvc0->residents_size -= nvc0->residents[ctx].size; - util_dynarray_resize(&nvc0->residents[ctx], 0); -} +void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *, + boolean on_flush); +void nvc0_default_kick_notify(struct nouveau_pushbuf *); /* nvc0_draw.c */ extern struct draw_stage *nvc0_draw_render_stage(struct nvc0_context *); @@ -168,9 +165,9 @@ void nvc0_program_library_upload(struct nvc0_context *); /* nvc0_query.c */ void nvc0_init_query_functions(struct nvc0_context *); -void nvc0_query_pushbuf_submit(struct nouveau_channel *, +void nvc0_query_pushbuf_submit(struct nouveau_pushbuf *, struct pipe_query *, unsigned result_offset); -void nvc0_query_fifo_wait(struct nouveau_channel *, struct pipe_query *); +void nvc0_query_fifo_wait(struct nouveau_pushbuf *, struct pipe_query *); void nvc0_so_target_save_offset(struct pipe_context *, struct pipe_stream_output_target *, unsigned i, boolean *serialize); @@ -210,7 +207,7 @@ nvc0_create_sampler_view(struct pipe_context *, /* nvc0_transfer.c */ void -nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, +nvc0_m2mf_transfer_rect(struct nvc0_context *, const struct nv50_m2mf_rect *dst, const struct nv50_m2mf_rect *src, uint32_t nblocksx, uint32_t nblocksy); @@ -241,8 +238,9 @@ nvc0_vertex_state_delete(struct pipe_context *pipe, void *hwcso); void nvc0_vertex_arrays_validate(struct nvc0_context *nvc0); +void nvc0_idxbuf_validate(struct nvc0_context *); + /* nvc0_push.c */ void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *); -void nvc0_push_vbo2(struct nvc0_context *, const struct pipe_draw_info *); #endif diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c index b180fc8db37..591ac4402db 100644 --- a/src/gallium/drivers/nvc0/nvc0_miptree.c +++ b/src/gallium/drivers/nvc0/nvc0_miptree.c @@ -65,80 +65,82 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed) compressed = FALSE; /* not yet supported */ - if (mt->base.base.bind & PIPE_BIND_CURSOR) - return NOUVEAU_BO_TILE_SCANOUT; + if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR)) + return 0; + if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR)) + return 0; switch (mt->base.base.format) { case PIPE_FORMAT_Z16_UNORM: if (compressed) - tile_flags = 0x0200 + (ms << 8); + tile_flags = 0x02 + ms; else - tile_flags = 0x0100; + tile_flags = 0x01; break; case PIPE_FORMAT_S8_UINT_Z24_UNORM: if (compressed) - tile_flags = 0x5100 + (ms << 8); + tile_flags = 0x51 + ms; else - tile_flags = 0x4600; + tile_flags = 0x46; break; case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: if (compressed) - tile_flags = 0x1700 + (ms << 8); + tile_flags = 0x17 + ms; else - tile_flags = 0x1100; + tile_flags = 0x11; break; case PIPE_FORMAT_Z32_FLOAT: if (compressed) - tile_flags = 0x8600 + (ms << 8); + tile_flags = 0x86 + ms; else - tile_flags = 0x7b00; + tile_flags = 0x7b; break; case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: if (compressed) - tile_flags = 0xce00 + (ms << 8); + tile_flags = 0xce + ms; else - tile_flags = 0xc300; + tile_flags = 0xc3; break; default: switch (util_format_get_blocksizebits(mt->base.base.format)) { case 128: if (compressed) - tile_flags = 0xf400 + (ms << 9); + tile_flags = 0xf4 + ms; else - tile_flags = 0xfe00; + tile_flags = 0xfe; break; case 64: if (compressed) { switch (ms) { - case 0: tile_flags = 0xe600; break; - case 1: tile_flags = 0xeb00; break; - case 2: tile_flags = 0xed00; break; - case 3: tile_flags = 0xf200; break; + case 0: tile_flags = 0xe6; break; + case 1: tile_flags = 0xeb; break; + case 2: tile_flags = 0xed; break; + case 3: tile_flags = 0xf2; break; default: return 0; } } else { - tile_flags = 0xfe00; + tile_flags = 0xfe; } break; case 32: if (compressed) { switch (ms) { - case 0: tile_flags = 0xdb00; break; - case 1: tile_flags = 0xdd00; break; - case 2: tile_flags = 0xdf00; break; - case 3: tile_flags = 0xe400; break; + case 0: tile_flags = 0xdb; break; + case 1: tile_flags = 0xdd; break; + case 2: tile_flags = 0xdf; break; + case 3: tile_flags = 0xe4; break; default: return 0; } } else { - tile_flags = 0xfe00; + tile_flags = 0xfe; } break; case 16: case 8: - tile_flags = 0xfe00; + tile_flags = 0xfe; break; default: return 0; @@ -146,12 +148,6 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed) break; } - if (mt->base.base.bind & PIPE_BIND_SCANOUT) - tile_flags |= NOUVEAU_BO_TILE_SCANOUT; - - if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR)) - tile_flags &= ~0xff00; - return tile_flags; } @@ -279,7 +275,8 @@ nvc0_miptree_create(struct pipe_screen *pscreen, struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); struct pipe_resource *pt = &mt->base.base; int ret; - uint32_t tile_flags; + union nouveau_bo_config bo_config; + uint32_t bo_flags; if (!mt) return NULL; @@ -289,7 +286,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen, pipe_reference_init(&pt->reference, 1); pt->screen = pscreen; - tile_flags = nvc0_mt_choose_storage_type(mt, TRUE); + bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, TRUE); if (!nvc0_miptree_init_ms_mode(mt)) { FREE(mt); @@ -299,23 +296,29 @@ nvc0_miptree_create(struct pipe_screen *pscreen, if (unlikely(pt->flags & NVC0_RESOURCE_FLAG_VIDEO)) { nvc0_miptree_init_layout_video(mt); } else - if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) { + if (likely(bo_config.nvc0.memtype)) { nvc0_miptree_init_layout_tiled(mt); } else if (!nv50_miptree_init_layout_linear(mt)) { FREE(mt); return NULL; } + bo_config.nvc0.tile_mode = mt->level[0].tile_mode; - ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096, - mt->total_size, - mt->level[0].tile_mode, tile_flags, - &mt->base.bo); + mt->base.domain = NOUVEAU_BO_VRAM; + + bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP; + + if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET)) + bo_flags |= NOUVEAU_BO_CONTIG; + + ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config, + &mt->base.bo); if (ret) { FREE(mt); return NULL; } - mt->base.domain = NOUVEAU_BO_VRAM; + mt->base.address = mt->base.bo->offset; return pt; } diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 44c7a65e3c9..b403e2ee9f2 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -618,7 +618,17 @@ nvc0_program_translate(struct nvc0_program *prog) assert(info->bin.tlsSpace < (1 << 24)); prog->hdr[0] |= 1 << 26; prog->hdr[1] |= info->bin.tlsSpace; /* l[] size */ + prog->need_tls = TRUE; } + /* TODO: factor 2 only needed where joinat/precont is used, + * and we only have to count non-uniform branches + */ + /* + if ((info->maxCFDepth * 2) > 16) { + prog->hdr[2] |= (((info->maxCFDepth * 2) + 47) / 48) * 0x200; + prog->need_tls = TRUE; + } + */ if (info->io.globalAccess) prog->hdr[0] |= 1 << 16; @@ -649,15 +659,15 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog) } size = align(size, 0x40); /* required by SP_START_ID */ - ret = nouveau_resource_alloc(screen->text_heap, size, prog, &prog->res); + ret = nouveau_heap_alloc(screen->text_heap, size, prog, &prog->mem); if (ret) { NOUVEAU_ERR("out of code space\n"); return FALSE; } - prog->code_base = prog->res->start; - prog->immd_base = align(prog->res->start + prog->immd_base, 0x100); + prog->code_base = prog->mem->start; + prog->immd_base = align(prog->mem->start + prog->immd_base, 0x100); assert((prog->immd_size == 0) || (prog->immd_base + prog->immd_size <= - prog->res->start + prog->res->size)); + prog->mem->start + prog->mem->size)); code_pos = prog->code_base + NVC0_SHADER_HEADER_SIZE; @@ -679,8 +689,8 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog) screen->text, prog->immd_base, NOUVEAU_BO_VRAM, prog->immd_size, prog->immd_data); - BEGIN_RING(screen->base.channel, RING_3D(MEM_BARRIER), 1); - OUT_RING (screen->base.channel, 0x1111); + BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1); + PUSH_DATA (nvc0->base.pushbuf, 0x1111); return TRUE; } @@ -701,8 +711,8 @@ nvc0_program_library_upload(struct nvc0_context *nvc0) if (!size) return; - ret = nouveau_resource_alloc(screen->text_heap, align(size, 0x100), NULL, - &screen->lib_code); + ret = nouveau_heap_alloc(screen->text_heap, align(size, 0x100), NULL, + &screen->lib_code); if (ret) return; @@ -718,8 +728,8 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog) const struct pipe_shader_state pipe = prog->pipe; const ubyte type = prog->type; - if (prog->res) - nouveau_resource_free(&prog->res); + if (prog->mem) + nouveau_heap_free(&prog->mem); if (prog->code) FREE(prog->code); diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h index c90f364ab9f..f6d1121c6dd 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.h +++ b/src/gallium/drivers/nvc0/nvc0_program.h @@ -21,6 +21,7 @@ struct nvc0_program { ubyte type; boolean translated; + boolean need_tls; uint8_t max_gpr; uint32_t *code; @@ -54,7 +55,7 @@ struct nvc0_program { struct nvc0_transform_feedback_state *tfb; - struct nouveau_resource *res; + struct nouveau_heap *mem; }; #endif diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index cea58b447a2..78cc5c20641 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -11,7 +11,7 @@ #include "nvc0_3d.xml.h" struct push_context { - struct nouveau_channel *chan; + struct nouveau_pushbuf *push; void *idxbuf; @@ -40,7 +40,7 @@ init_push_context(struct nvc0_context *nvc0, struct push_context *ctx) { struct pipe_vertex_element *ve; - ctx->chan = nvc0->screen->base.channel; + ctx->push = nvc0->base.pushbuf; ctx->translate = nvc0->vertex->translate; if (likely(nvc0->vertex->num_elements < 32)) @@ -72,7 +72,7 @@ set_edgeflag(struct push_context *ctx, unsigned vtx_id) if (ctx->edgeflag.value != f) { ctx->edgeflag.value = f; - IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0); + IMMED_NVC0(ctx->push, NVC0_3D(EDGEFLAG), f ? 1 : 0); } } @@ -80,11 +80,11 @@ static INLINE void set_vertexid(struct push_context *ctx, uint32_t vtx_id) { #if 0 - BEGIN_RING(ctx->chan, RING_3D(VERTEX_ID), 1); /* broken on nvc0 */ + BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_ID), 1); /* broken on nvc0 */ #else - BEGIN_RING(ctx->chan, RING_3D(VERTEX_DATA), 1); /* as last attribute */ + BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_DATA), 1); /* as last attribute */ #endif - OUT_RING (ctx->chan, vtx_id); + PUSH_DATA (ctx->push, vtx_id); } static INLINE unsigned @@ -135,11 +135,11 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size); ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); - ctx->chan->cur += size; + ctx->push->cur); + ctx->push->cur += size; if (unlikely(ctx->need_vertex_id) && likely(size)) set_vertexid(ctx, elts[0]); @@ -150,9 +150,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2); - OUT_RING (ctx->chan, 0); - OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | + BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2); + PUSH_DATA (ctx->push, 0); + PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT)); } } @@ -176,11 +176,11 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size); ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); - ctx->chan->cur += size; + ctx->push->cur); + ctx->push->cur += size; if (unlikely(ctx->need_vertex_id)) set_vertexid(ctx, elts[0]); @@ -191,9 +191,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2); - OUT_RING (ctx->chan, 0); - OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | + BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2); + PUSH_DATA (ctx->push, 0); + PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT)); } } @@ -217,11 +217,11 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) size = ctx->vertex_words * nr; - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size); ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id, - ctx->chan->cur); - ctx->chan->cur += size; + ctx->push->cur); + ctx->push->cur += size; if (unlikely(ctx->need_vertex_id)) set_vertexid(ctx, elts[0]); @@ -232,9 +232,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) if (nr != push) { count--; elts++; - BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2); - OUT_RING (ctx->chan, 0); - OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | + BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2); + PUSH_DATA (ctx->push, 0); + PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT | (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT)); } } @@ -250,11 +250,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count) if (unlikely(ctx->edgeflag.buffer >= 0)) set_edgeflag(ctx, start); - BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size); ctx->translate->run(ctx->translate, start, push, ctx->instance_id, - ctx->chan->cur); - ctx->chan->cur += size; + ctx->push->cur); + ctx->push->cur += size; if (unlikely(ctx->need_vertex_id)) set_vertexid(ctx, start); @@ -354,17 +354,17 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) if (unlikely(ctx.need_vertex_id)) { const unsigned a = nvc0->vertex->num_elements; - BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1); - OUT_RING (ctx.chan, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) | + BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1); + PUSH_DATA (ctx.push, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) | NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32); - BEGIN_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 1); - OUT_RING (ctx.chan, (((0x80 + a * 0x10) / 4) << 4) | 1); + BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 1); + PUSH_DATA (ctx.push, (((0x80 + a * 0x10) / 4) << 4) | 1); } while (inst_count--) { - BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (ctx.chan, ctx.prim); + BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (ctx.push, ctx.prim); switch (index_size) { case 0: emit_vertices_seq(&ctx, info->start, vert_count); @@ -382,20 +382,20 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) assert(0); break; } - IMMED_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0); + IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0); ctx.instance_id++; ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } if (unlikely(ctx.edgeflag.value == 0.0f)) - IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1); + IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1); if (unlikely(ctx.need_vertex_id)) { const unsigned a = nvc0->vertex->num_elements; - IMMED_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 0); - BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1); - OUT_RING (ctx.chan, + IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0); + BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1); + PUSH_DATA (ctx.push, NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST | NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT | NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32); diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c index 699d582fe3d..b0ef83a1df2 100644 --- a/src/gallium/drivers/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nvc0/nvc0_query.c @@ -22,6 +22,8 @@ * Authors: Christoph Bumiller */ +#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING + #include "nvc0_context.h" #include "nouveau/nv_object.xml.h" @@ -71,14 +73,12 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size) return FALSE; q->offset = q->base; - ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD | - NOUVEAU_BO_NOSYNC); + ret = nouveau_bo_map(q->bo, 0, screen->base.client); if (ret) { nvc0_query_allocate(nvc0, q, 0); return FALSE; } - q->data = q->bo->map; - nouveau_bo_unmap(q->bo); + q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base); } return TRUE; } @@ -150,17 +150,18 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type) } static void -nvc0_query_get(struct nouveau_channel *chan, struct nvc0_query *q, +nvc0_query_get(struct nouveau_pushbuf *push, struct nvc0_query *q, unsigned offset, uint32_t get) { offset += q->offset; - MARK_RING (chan, 5, 2); - BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (chan, q->sequence); - OUT_RING (chan, get); + PUSH_SPACE(push, 5); + PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4); + PUSH_DATAh(push, q->bo->offset + offset); + PUSH_DATA (push, q->bo->offset + offset); + PUSH_DATA (push, q->sequence); + PUSH_DATA (push, get); } static void @@ -176,7 +177,7 @@ static void nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_query *q = nvc0_query(pq); /* For occlusion queries we have to change the storage, because a previous @@ -201,41 +202,42 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq) case PIPE_QUERY_OCCLUSION_PREDICATE: q->nesting = nvc0->screen->num_occlusion_queries_active++; if (q->nesting) { - nvc0_query_get(chan, q, 0x10, 0x0100f002); + nvc0_query_get(push, q, 0x10, 0x0100f002); } else { - BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1); - OUT_RING (chan, NVC0_3D_COUNTER_RESET_SAMPLECNT); - IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1); + PUSH_SPACE(push, 3); + BEGIN_NVC0(push, NVC0_3D(COUNTER_RESET), 1); + PUSH_DATA (push, NVC0_3D_COUNTER_RESET_SAMPLECNT); + IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1); } break; case PIPE_QUERY_PRIMITIVES_GENERATED: - nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5)); break; case PIPE_QUERY_PRIMITIVES_EMITTED: - nvc0_query_get(chan, q, 0x10, 0x05805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x10, 0x05805002 | (q->index << 5)); break; case PIPE_QUERY_SO_STATISTICS: - nvc0_query_get(chan, q, 0x20, 0x05805002 | (q->index << 5)); - nvc0_query_get(chan, q, 0x30, 0x06805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x20, 0x05805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x30, 0x06805002 | (q->index << 5)); break; case PIPE_QUERY_SO_OVERFLOW_PREDICATE: - nvc0_query_get(chan, q, 0x10, 0x03005002 | (q->index << 5)); + nvc0_query_get(push, q, 0x10, 0x03005002 | (q->index << 5)); break; case PIPE_QUERY_TIMESTAMP_DISJOINT: case PIPE_QUERY_TIME_ELAPSED: - nvc0_query_get(chan, q, 0x10, 0x00005002); + nvc0_query_get(push, q, 0x10, 0x00005002); break; case PIPE_QUERY_PIPELINE_STATISTICS: - nvc0_query_get(chan, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */ - nvc0_query_get(chan, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */ - nvc0_query_get(chan, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */ - nvc0_query_get(chan, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */ - nvc0_query_get(chan, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */ - nvc0_query_get(chan, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */ - nvc0_query_get(chan, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */ - nvc0_query_get(chan, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */ - nvc0_query_get(chan, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */ - nvc0_query_get(chan, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */ + nvc0_query_get(push, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */ + nvc0_query_get(push, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */ + nvc0_query_get(push, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */ + nvc0_query_get(push, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */ + nvc0_query_get(push, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */ + nvc0_query_get(push, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */ + nvc0_query_get(push, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */ + nvc0_query_get(push, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */ + nvc0_query_get(push, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */ + nvc0_query_get(push, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */ break; default: break; @@ -248,7 +250,7 @@ static void nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq) { struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_query *q = nvc0_query(pq); if (!q->active) { @@ -263,49 +265,51 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: - nvc0_query_get(chan, q, 0, 0x0100f002); - if (--nvc0->screen->num_occlusion_queries_active == 0) - IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 0); + nvc0_query_get(push, q, 0, 0x0100f002); + if (--nvc0->screen->num_occlusion_queries_active == 0) { + PUSH_SPACE(push, 1); + IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0); + } break; case PIPE_QUERY_PRIMITIVES_GENERATED: - nvc0_query_get(chan, q, 0, 0x06805002 | (q->index << 5)); + nvc0_query_get(push, q, 0, 0x06805002 | (q->index << 5)); break; case PIPE_QUERY_PRIMITIVES_EMITTED: - nvc0_query_get(chan, q, 0, 0x05805002 | (q->index << 5)); + nvc0_query_get(push, q, 0, 0x05805002 | (q->index << 5)); break; case PIPE_QUERY_SO_STATISTICS: - nvc0_query_get(chan, q, 0x00, 0x05805002 | (q->index << 5)); - nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x00, 0x05805002 | (q->index << 5)); + nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5)); break; case PIPE_QUERY_SO_OVERFLOW_PREDICATE: /* TODO: How do we sum over all streams for render condition ? */ /* PRIMS_DROPPED doesn't write sequence, use a ZERO query to sync on */ - nvc0_query_get(chan, q, 0x00, 0x03005002 | (q->index << 5)); - nvc0_query_get(chan, q, 0x20, 0x00005002); + nvc0_query_get(push, q, 0x00, 0x03005002 | (q->index << 5)); + nvc0_query_get(push, q, 0x20, 0x00005002); break; case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIMESTAMP_DISJOINT: case PIPE_QUERY_TIME_ELAPSED: - nvc0_query_get(chan, q, 0, 0x00005002); + nvc0_query_get(push, q, 0, 0x00005002); break; case PIPE_QUERY_GPU_FINISHED: - nvc0_query_get(chan, q, 0, 0x1000f010); + nvc0_query_get(push, q, 0, 0x1000f010); break; case PIPE_QUERY_PIPELINE_STATISTICS: - nvc0_query_get(chan, q, 0x00, 0x00801002); /* VFETCH, VERTICES */ - nvc0_query_get(chan, q, 0x10, 0x01801002); /* VFETCH, PRIMS */ - nvc0_query_get(chan, q, 0x20, 0x02802002); /* VP, LAUNCHES */ - nvc0_query_get(chan, q, 0x30, 0x03806002); /* GP, LAUNCHES */ - nvc0_query_get(chan, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */ - nvc0_query_get(chan, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */ - nvc0_query_get(chan, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */ - nvc0_query_get(chan, q, 0x70, 0x0980a002); /* ROP, PIXELS */ - nvc0_query_get(chan, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */ - nvc0_query_get(chan, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */ + nvc0_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */ + nvc0_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */ + nvc0_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */ + nvc0_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */ + nvc0_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */ + nvc0_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */ + nvc0_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */ + nvc0_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */ + nvc0_query_get(push, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */ + nvc0_query_get(push, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */ break; case NVC0_QUERY_TFB_BUFFER_OFFSET: /* indexed by TFB buffer instead of by vertex stream */ - nvc0_query_get(chan, q, 0x00, 0x0d005002 | (q->index << 5)); + nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5)); break; default: assert(0); @@ -314,32 +318,20 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq) } static INLINE boolean -nvc0_query_ready(struct nvc0_query *q) +nvc0_query_ready(struct nouveau_client *cli, struct nvc0_query *q) { if (q->is64bit) { - if (nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOWAIT)) - return FALSE; - nouveau_bo_unmap(q->bo); - return TRUE; + return !nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli); } else { return q->data[0] == q->sequence; } } -static INLINE boolean -nvc0_query_wait(struct nvc0_query *q) -{ - int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD); - if (ret) - return FALSE; - nouveau_bo_unmap(q->bo); - return TRUE; -} - static boolean nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq, boolean wait, union pipe_query_result *result) { + struct nvc0_context *nvc0 = nvc0_context(pipe); struct nvc0_query *q = nvc0_query(pq); uint64_t *res64 = (uint64_t*)result; uint32_t *res32 = (uint32_t*)result; @@ -348,15 +340,15 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq, unsigned i; if (!q->ready) /* update ? */ - q->ready = nvc0_query_ready(q); + q->ready = nvc0_query_ready(nvc0->screen->base.client, q); if (!q->ready) { - struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel; if (!wait) { - if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */ - FIRE_RING(chan); + /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */ + if (nouveau_pushbuf_refd(nvc0->base.pushbuf, q->bo) & NOUVEAU_BO_WR) + PUSH_KICK(nvc0->base.pushbuf); return FALSE; } - if (!nvc0_query_wait(q)) + if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client)) return FALSE; } q->ready = TRUE; @@ -407,19 +399,20 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq, } void -nvc0_query_fifo_wait(struct nouveau_channel *chan, struct pipe_query *pq) +nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq) { struct nvc0_query *q = nvc0_query(pq); unsigned offset = q->offset; if (q->type == PIPE_QUERY_SO_OVERFLOW_PREDICATE) offset += 0x20; - MARK_RING (chan, 5, 2); - BEGIN_RING(chan, RING_3D_(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RING (chan, q->sequence); - OUT_RING (chan, (1 << 12) | + PUSH_SPACE(push, 5); + PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4); + PUSH_DATAh(push, q->bo->offset + offset); + PUSH_DATA (push, q->bo->offset + offset); + PUSH_DATA (push, q->sequence); + PUSH_DATA (push, (1 << 12) | NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); } @@ -428,7 +421,7 @@ nvc0_render_condition(struct pipe_context *pipe, struct pipe_query *pq, uint mode) { struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_query *q; uint32_t cond; boolean negated = FALSE; @@ -437,7 +430,8 @@ nvc0_render_condition(struct pipe_context *pipe, mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT; if (!pq) { - IMMED_RING(chan, RING_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); + PUSH_SPACE(push, 1); + IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS); return; } q = nvc0_query(pq); @@ -468,25 +462,27 @@ nvc0_render_condition(struct pipe_context *pipe, } if (wait) - nvc0_query_fifo_wait(chan, pq); - - MARK_RING (chan, 4, 2); - BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RING (chan, cond); + nvc0_query_fifo_wait(push, pq); + + PUSH_SPACE(push, 4); + PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3); + PUSH_DATAh(push, q->bo->offset + q->offset); + PUSH_DATA (push, q->bo->offset + q->offset); + PUSH_DATA (push, cond); } void -nvc0_query_pushbuf_submit(struct nouveau_channel *chan, +nvc0_query_pushbuf_submit(struct nouveau_pushbuf *push, struct pipe_query *pq, unsigned result_offset) { struct nvc0_query *q = nvc0_query(pq); #define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8)) - nouveau_pushbuf_submit(chan, q->bo, q->offset + result_offset, 4 | - NVC0_IB_ENTRY_1_NO_PREFETCH); + nouveau_pushbuf_space(push, 0, 0, 1); + nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 | + NVC0_IB_ENTRY_1_NO_PREFETCH); } void @@ -497,9 +493,9 @@ nvc0_so_target_save_offset(struct pipe_context *pipe, struct nvc0_so_target *targ = nvc0_so_target(ptarg); if (*serialize) { - struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel; *serialize = FALSE; - IMMED_RING(chan, RING_3D(SERIALIZE), 0); + PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1); + IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0); } nvc0_query(targ->pq)->index = index; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index f7637eedc43..f314cb631f2 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -238,8 +238,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) nouveau_fence_wait(screen->base.fence.current); nouveau_fence_ref(NULL, &screen->base.fence.current); } - if (screen->base.channel) - screen->base.channel->user_private = NULL; + if (screen->base.pushbuf) + screen->base.pushbuf->user_priv = NULL; if (screen->blitctx) FREE(screen->blitctx); @@ -250,17 +250,17 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) nouveau_bo_ref(NULL, &screen->fence.bo); nouveau_bo_ref(NULL, &screen->vfetch_cache); - nouveau_resource_destroy(&screen->lib_code); - nouveau_resource_destroy(&screen->text_heap); + nouveau_heap_destroy(&screen->lib_code); + nouveau_heap_destroy(&screen->text_heap); if (screen->tic.entries) FREE(screen->tic.entries); nouveau_mm_destroy(screen->mm_VRAM_fe0); - nouveau_grobj_free(&screen->fermi); - nouveau_grobj_free(&screen->eng2d); - nouveau_grobj_free(&screen->m2mf); + nouveau_object_del(&screen->fermi); + nouveau_object_del(&screen->eng2d); + nouveau_object_del(&screen->m2mf); nouveau_screen_fini(&screen->base); @@ -271,102 +271,100 @@ static int nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, unsigned size, const uint32_t *data) { - struct nouveau_channel *chan = screen->base.channel; + struct nouveau_pushbuf *push = screen->base.pushbuf; size /= 4; - BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2); - OUT_RING (chan, (m - 0x3800) / 8); - OUT_RING (chan, pos); - BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1); - OUT_RING (chan, pos); - OUT_RINGp (chan, data, size); + BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2); + PUSH_DATA (push, (m - 0x3800) / 8); + PUSH_DATA (push, pos); + BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1); + PUSH_DATA (push, pos); + PUSH_DATAp(push, data, size); return pos + size; } static void -nvc0_magic_3d_init(struct nouveau_channel *chan) +nvc0_magic_3d_init(struct nouveau_pushbuf *push) { - BEGIN_RING(chan, RING_3D_(0x10cc), 1); - OUT_RING (chan, 0xff); - BEGIN_RING(chan, RING_3D_(0x10e0), 2); - OUT_RING(chan, 0xff); - OUT_RING(chan, 0xff); - BEGIN_RING(chan, RING_3D_(0x10ec), 2); - OUT_RING(chan, 0xff); - OUT_RING(chan, 0xff); - BEGIN_RING(chan, RING_3D_(0x074c), 1); - OUT_RING (chan, 0x3f); - - BEGIN_RING(chan, RING_3D_(0x16a8), 1); - OUT_RING (chan, (3 << 16) | 3); - BEGIN_RING(chan, RING_3D_(0x1794), 1); - OUT_RING (chan, (2 << 16) | 2); - BEGIN_RING(chan, RING_3D_(0x0de8), 1); - OUT_RING (chan, 1); + BEGIN_NVC0(push, SUBC_3D(0x10cc), 1); + PUSH_DATA (push, 0xff); + BEGIN_NVC0(push, SUBC_3D(0x10e0), 2); + PUSH_DATA(push, 0xff); + PUSH_DATA(push, 0xff); + BEGIN_NVC0(push, SUBC_3D(0x10ec), 2); + PUSH_DATA(push, 0xff); + PUSH_DATA(push, 0xff); + BEGIN_NVC0(push, SUBC_3D(0x074c), 1); + PUSH_DATA (push, 0x3f); + + BEGIN_NVC0(push, SUBC_3D(0x16a8), 1); + PUSH_DATA (push, (3 << 16) | 3); + BEGIN_NVC0(push, SUBC_3D(0x1794), 1); + PUSH_DATA (push, (2 << 16) | 2); + BEGIN_NVC0(push, SUBC_3D(0x0de8), 1); + PUSH_DATA (push, 1); #if 0 /* software method */ - BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */ - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_3D(0x1528), 1); /* MP poke */ + PUSH_DATA (push, 0); #endif - BEGIN_RING(chan, RING_3D_(0x12ac), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D_(0x0218), 1); - OUT_RING (chan, 0x10); - BEGIN_RING(chan, RING_3D_(0x10fc), 1); - OUT_RING (chan, 0x10); - BEGIN_RING(chan, RING_3D_(0x1290), 1); - OUT_RING (chan, 0x10); - BEGIN_RING(chan, RING_3D_(0x12d8), 2); - OUT_RING (chan, 0x10); - OUT_RING (chan, 0x10); - BEGIN_RING(chan, RING_3D_(0x06d4), 1); - OUT_RING (chan, 8); - BEGIN_RING(chan, RING_3D_(0x1140), 1); - OUT_RING (chan, 0x10); - BEGIN_RING(chan, RING_3D_(0x1610), 1); - OUT_RING (chan, 0xe); - - BEGIN_RING(chan, RING_3D_(0x164c), 1); - OUT_RING (chan, 1 << 12); - BEGIN_RING(chan, RING_3D_(0x151c), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D_(0x030c), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D_(0x0300), 1); - OUT_RING (chan, 3); + BEGIN_NVC0(push, SUBC_3D(0x12ac), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x0218), 1); + PUSH_DATA (push, 0x10); + BEGIN_NVC0(push, SUBC_3D(0x10fc), 1); + PUSH_DATA (push, 0x10); + BEGIN_NVC0(push, SUBC_3D(0x1290), 1); + PUSH_DATA (push, 0x10); + BEGIN_NVC0(push, SUBC_3D(0x12d8), 2); + PUSH_DATA (push, 0x10); + PUSH_DATA (push, 0x10); + BEGIN_NVC0(push, SUBC_3D(0x06d4), 1); + PUSH_DATA (push, 8); + BEGIN_NVC0(push, SUBC_3D(0x1140), 1); + PUSH_DATA (push, 0x10); + BEGIN_NVC0(push, SUBC_3D(0x1610), 1); + PUSH_DATA (push, 0xe); + + BEGIN_NVC0(push, SUBC_3D(0x164c), 1); + PUSH_DATA (push, 1 << 12); + BEGIN_NVC0(push, SUBC_3D(0x151c), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, SUBC_3D(0x030c), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_3D(0x0300), 1); + PUSH_DATA (push, 3); #if 0 /* software method */ - BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */ - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_3D(0x1280), 1); /* PGRAPH poke */ + PUSH_DATA (push, 0); #endif - BEGIN_RING(chan, RING_3D_(0x02d0), 1); - OUT_RING (chan, 0x1f40); - BEGIN_RING(chan, RING_3D_(0x00fdc), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D_(0x19c0), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D_(0x075c), 1); - OUT_RING (chan, 3); + BEGIN_NVC0(push, SUBC_3D(0x02d0), 1); + PUSH_DATA (push, 0x1f40); + BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, SUBC_3D(0x19c0), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, SUBC_3D(0x075c), 1); + PUSH_DATA (push, 3); } static void nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) { struct nvc0_screen *screen = nvc0_screen(pscreen); - struct nouveau_channel *chan = screen->base.channel; - - MARK_RING (chan, 5, 2); + struct nouveau_pushbuf *push = screen->base.pushbuf; /* we need to do it after possible flush in MARK_RING */ *sequence = ++screen->base.fence.sequence; - BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); - OUT_RING (chan, *sequence); - OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | + BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4); + PUSH_DATAh(push, screen->fence.bo->offset); + PUSH_DATA (push, screen->fence.bo->offset); + PUSH_DATA (push, *sequence); + PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); } @@ -388,10 +386,12 @@ struct pipe_screen * nvc0_screen_create(struct nouveau_device *dev) { struct nvc0_screen *screen; - struct nouveau_channel *chan; struct pipe_screen *pscreen; + struct nouveau_object *chan; + struct nouveau_pushbuf *push; int ret; unsigned i; + union nouveau_bo_config mm_config; screen = CALLOC_STRUCT(nvc0_screen); if (!screen) @@ -406,7 +406,8 @@ nvc0_screen_create(struct nouveau_device *dev) return NULL; } chan = screen->base.channel; - chan->user_private = screen; + push = screen->base.pushbuf; + push->user_priv = screen; pscreen->destroy = nvc0_screen_destroy; pscreen->context_create = nvc0_create; @@ -419,203 +420,210 @@ nvc0_screen_create(struct nouveau_device *dev) nouveau_screen_init_vdec(&screen->base); - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, NULL, &screen->fence.bo); if (ret) goto fail; - nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); + nouveau_bo_map(screen->fence.bo, 0, NULL); screen->fence.map = screen->fence.bo->map; - nouveau_bo_unmap(screen->fence.bo); screen->base.fence.emit = nvc0_screen_fence_emit; screen->base.fence.update = nvc0_screen_fence_update; for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, NULL, &screen->scratch.bo[i]); if (ret) goto fail; } - ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf); + ret = nouveau_object_new(chan, 0xbeef9039, NVC0_M2MF_CLASS, NULL, 0, + &screen->m2mf); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); - BIND_RING (chan, screen->m2mf, NVC0_SUBCH_MF); - BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->m2mf->oclass); + BEGIN_NVC0(push, NVC0_M2MF(NOTIFY_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->fence.bo->offset + 16); + PUSH_DATA (push, screen->fence.bo->offset + 16); + PUSH_DATA (push, 0); - ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d); + ret = nouveau_object_new(chan, 0xbeef902d, NVC0_2D_CLASS, NULL, 0, + &screen->eng2d); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); - BIND_RING (chan, screen->eng2d, NVC0_SUBCH_2D); - BEGIN_RING(chan, RING_2D(OPERATION), 1); - OUT_RING (chan, NVC0_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_2D_(0x0884), 1); - OUT_RING (chan, 0x3f); - BEGIN_RING(chan, RING_2D_(0x0888), 1); - OUT_RING (chan, 1); - - ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi); + BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->eng2d->oclass); + BEGIN_NVC0(push, NVC0_2D(OPERATION), 1); + PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY); + BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, SUBC_2D(0x0884), 1); + PUSH_DATA (push, 0x3f); + BEGIN_NVC0(push, SUBC_2D(0x0888), 1); + PUSH_DATA (push, 1); + + ret = nouveau_object_new(chan, 0xbeef9097, NVC0_3D_CLASS, NULL, 0, + &screen->fermi); if (ret) FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); - BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D); - BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RING (chan, 0); + BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); + PUSH_DATA (push, screen->fermi->oclass); + BEGIN_NVC0(push, NVC0_3D(NOTIFY_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->fence.bo->offset + 32); + PUSH_DATA (push, screen->fence.bo->offset + 32); + PUSH_DATA (push, 0); - BEGIN_RING(chan, RING_3D(COND_MODE), 1); - OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS); + BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1); + PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS); if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) { /* kill shaders after about 1 second (at 100 MHz) */ - BEGIN_RING(chan, RING_3D(WATCHDOG_TIMER), 1); - OUT_RING (chan, 0x17); + BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1); + PUSH_DATA (push, 0x17); } - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - - BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); - OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_MS1); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(TEX_MISC), 1); - OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); - - nvc0_magic_3d_init(chan); - - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text); + BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + + BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1); + PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1); + BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TEX_MISC), 1); + PUSH_DATA (push, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); + + nvc0_magic_3d_init(push); + + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL, + &screen->text); if (ret) goto fail; /* XXX: getting a page fault at the end of the code buffer every few * launches, don't use the last 256 bytes to work around them - prefetch ? */ - nouveau_resource_init(&screen->text_heap, 0, (1 << 20) - 0x100); + nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL, &screen->uniforms); if (ret) goto fail; /* auxiliary constants (6 user clip planes, base instance id) */ - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, 256); - OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, 256); + PUSH_DATAh(push, screen->uniforms->offset + (5 << 16)); + PUSH_DATA (push, screen->uniforms->offset + (5 << 16)); for (i = 0; i < 5; ++i) { - BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1); - OUT_RING (chan, (15 << 4) | 1); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1); + PUSH_DATA (push, (15 << 4) | 1); } screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, - screen->tls_size, &screen->tls); + screen->tls_size, NULL, &screen->tls); if (ret) goto fail; - BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2); - OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4); - OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, screen->tls_size >> 32); - OUT_RING (chan, screen->tls_size); - BEGIN_RING(chan, RING_3D_(0x07a0), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2); + PUSH_DATAh(push, screen->text->offset); + PUSH_DATA (push, screen->text->offset); + BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4); + PUSH_DATAh(push, screen->tls->offset); + PUSH_DATA (push, screen->tls->offset); + PUSH_DATA (push, screen->tls_size >> 32); + PUSH_DATA (push, screen->tls_size); + BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1); + PUSH_DATA (push, 0); for (i = 0; i < 5; ++i) { - BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1); - OUT_RING (chan, 0x54); + BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1); + PUSH_DATA (push, 0x54); } - BEGIN_RING(chan, RING_3D(LINKED_TSC), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); + PUSH_DATA (push, 0); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL, &screen->vfetch_cache); if (ret) goto fail; - BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, 3); + BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->vfetch_cache->offset); + PUSH_DATA (push, screen->vfetch_cache->offset); + PUSH_DATA (push, 3); - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL, + &screen->txc); if (ret) goto fail; - BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, NVC0_TIC_MAX_ENTRIES - 1); - - BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3); - OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1); - - BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D_(0x1590), 1); /* deactivate ZCULL */ - OUT_RING (chan, 0x3f); - - BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1); - OUT_RING (chan, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY); - BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2); + BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->txc->offset); + PUSH_DATA (push, screen->txc->offset); + PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1); + + BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3); + PUSH_DATAh(push, screen->txc->offset + 65536); + PUSH_DATA (push, screen->txc->offset + 65536); + PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1); + + BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */ + PUSH_DATA (push, 0x3f); + + BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1); + PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY); + BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2); for (i = 0; i < 8 * 2; ++i) - OUT_RING(chan, 0); - BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1); - OUT_RING (chan, 0); + PUSH_DATA(push, 0); + BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1); + PUSH_DATA (push, 0); /* neither scissors, viewport nor stencil mask should affect clears */ - BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1); + PUSH_DATA (push, 0); - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 1.0f); - BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); - OUT_RING (chan, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1); + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 1.0f); + BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1); + PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1); /* We use scissors instead of exact view volume clipping, * so they're always enabled. */ - BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3); - OUT_RING (chan, 1); - OUT_RING (chan, 8192 << 16); - OUT_RING (chan, 8192 << 16); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3); + PUSH_DATA (push, 1); + PUSH_DATA (push, 8192 << 16); + PUSH_DATA (push, 8192 << 16); #define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n); @@ -627,41 +635,42 @@ nvc0_screen_create(struct nouveau_device *dev) MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front); MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back); - BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(RT_SEPARATE_FRAG_DATA), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(GP_SELECT), 1); - OUT_RING (chan, 0x40); - BEGIN_RING(chan, RING_3D(LAYER), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(TEP_SELECT), 1); - OUT_RING (chan, 0x30); - BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1); - OUT_RING (chan, 3); - BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1); - OUT_RING (chan, 0x20); - BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1); - OUT_RING (chan, 0x00); - - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); - OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL); - - BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); - OUT_RING (chan, 1); - - BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); - OUT_RING (chan, 0xab); - OUT_RING (chan, 0x00000000); - - FIRE_RING (chan); + BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1); + PUSH_DATA (push, 0x40); + BEGIN_NVC0(push, NVC0_3D(LAYER), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1); + PUSH_DATA (push, 0x30); + BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1); + PUSH_DATA (push, 3); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1); + PUSH_DATA (push, 0x20); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1); + PUSH_DATA (push, 0x00); + + BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1); + PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL); + + IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1); + + BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); + PUSH_DATA (push, 0xab); + PUSH_DATA (push, 0x00000000); + + PUSH_KICK (push); screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); + mm_config.nvc0.tile_mode = 0; + mm_config.nvc0.memtype = 0xfe0; + screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config); if (!nvc0_blitctx_create(screen)) goto fail; @@ -675,23 +684,6 @@ fail: return NULL; } -void -nvc0_screen_make_buffers_resident(struct nvc0_screen *screen) -{ - struct nouveau_channel *chan = screen->base.channel; - - const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; - - MARK_RING(chan, 0, 5); - nouveau_bo_validate(chan, screen->text, flags); - nouveau_bo_validate(chan, screen->uniforms, flags); - nouveau_bo_validate(chan, screen->txc, flags); - nouveau_bo_validate(chan, screen->vfetch_cache, flags); - - if (screen->cur_ctx && screen->cur_ctx->state.tls_required) - nouveau_bo_validate(chan, screen->tls, flags); -} - int nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry) { diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index be42970ca39..9abf4b1fd3d 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -1,11 +1,11 @@ #ifndef __NVC0_SCREEN_H__ #define __NVC0_SCREEN_H__ -#define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" #include "nouveau/nouveau_mm.h" #include "nouveau/nouveau_fence.h" -#undef NOUVEAU_NVC0 +#include "nouveau/nouveau_heap.h" + #include "nvc0_winsys.h" #include "nvc0_stateobj.h" @@ -36,8 +36,8 @@ struct nvc0_screen { uint64_t tls_size; - struct nouveau_resource *text_heap; - struct nouveau_resource *lib_code; /* allocated from text_heap */ + struct nouveau_heap *text_heap; + struct nouveau_heap *lib_code; /* allocated from text_heap */ struct nvc0_blitctx *blitctx; @@ -67,9 +67,10 @@ struct nvc0_screen { struct nouveau_mman *mm_VRAM_fe0; - struct nouveau_grobj *fermi; - struct nouveau_grobj *eng2d; - struct nouveau_grobj *m2mf; + struct nouveau_object *fermi; + struct nouveau_object *eng2d; + struct nouveau_object *m2mf; + struct nouveau_object *dijkstra; }; static INLINE struct nvc0_screen * @@ -92,7 +93,6 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags) if (res->mm) { nouveau_fence_ref(screen->base.fence.current, &res->fence); - if (flags & NOUVEAU_BO_WR) nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); } @@ -101,11 +101,7 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags) static INLINE void nvc0_resource_validate(struct nv04_resource *res, uint32_t flags) { - struct nvc0_screen *screen = nvc0_screen(res->base.screen); - if (likely(res->bo)) { - nouveau_bo_validate(screen->base.channel, res->bo, flags); - if (flags & NOUVEAU_BO_WR) res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; if (flags & NOUVEAU_BO_RD) diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 9945b8e7b1f..9d688843473 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -31,29 +31,33 @@ static INLINE void nvc0_program_update_context_state(struct nvc0_context *nvc0, struct nvc0_program *prog, int stage) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; - if (prog->hdr[1]) + if (prog && prog->need_tls) { + const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + if (!nvc0->state.tls_required) + BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls); nvc0->state.tls_required |= 1 << stage; - else + } else { + if (nvc0->state.tls_required == (1 << stage)) + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS); nvc0->state.tls_required &= ~(1 << stage); + } - if (prog->immd_size) { - const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; - - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); + if (prog && prog->immd_size) { + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); /* NOTE: may overlap code of a different shader */ - OUT_RING (chan, align(prog->immd_size, 0x100)); - OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl); - OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl); - BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1); - OUT_RING (chan, (14 << 4) | 1); + PUSH_DATA (push, align(prog->immd_size, 0x100)); + PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base); + PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1); + PUSH_DATA (push, (14 << 4) | 1); nvc0->state.c14_bound |= 1 << stage; } else if (nvc0->state.c14_bound & (1 << stage)) { - BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1); - OUT_RING (chan, (14 << 4) | 0); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1); + PUSH_DATA (push, (14 << 4) | 0); nvc0->state.c14_bound &= ~(1 << stage); } @@ -62,7 +66,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0, static INLINE boolean nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) { - if (prog->res) + if (prog->mem) return TRUE; if (!prog->translated) { @@ -79,133 +83,129 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) void nvc0_vertprog_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *vp = nvc0->vertprog; if (!nvc0_program_validate(nvc0, vp)) return; nvc0_program_update_context_state(nvc0, vp, 0); - BEGIN_RING(chan, RING_3D(SP_SELECT(1)), 2); - OUT_RING (chan, 0x11); - OUT_RING (chan, vp->code_base); - BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(1)), 1); - OUT_RING (chan, vp->max_gpr); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2); + PUSH_DATA (push, 0x11); + PUSH_DATA (push, vp->code_base); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1); + PUSH_DATA (push, vp->max_gpr); - // BEGIN_RING(chan, RING_3D_(0x163c), 1); - // OUT_RING (chan, 0); + // BEGIN_NVC0(push, NVC0_3D_(0x163c), 1); + // PUSH_DATA (push, 0); } void nvc0_fragprog_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *fp = nvc0->fragprog; if (!nvc0_program_validate(nvc0, fp)) return; nvc0_program_update_context_state(nvc0, fp, 4); - BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2); - OUT_RING (chan, 0x51); - OUT_RING (chan, fp->code_base); - BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(5)), 1); - OUT_RING (chan, fp->max_gpr); - - BEGIN_RING(chan, RING_3D_(0x0360), 2); - OUT_RING (chan, 0x20164010); - OUT_RING (chan, 0x20); - BEGIN_RING(chan, RING_3D_(0x196c), 1); - OUT_RING (chan, fp->flags[0]); + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2); + PUSH_DATA (push, 0x51); + PUSH_DATA (push, fp->code_base); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1); + PUSH_DATA (push, fp->max_gpr); + + BEGIN_NVC0(push, SUBC_3D(0x0360), 2); + PUSH_DATA (push, 0x20164010); + PUSH_DATA (push, 0x20); + BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1); + PUSH_DATA (push, fp->flags[0]); } void nvc0_tctlprog_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *tp = nvc0->tctlprog; - if (!tp) { - BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1); - OUT_RING (chan, 0x20); - return; + if (tp && nvc0_program_validate(nvc0, tp)) { + if (tp->tp.tess_mode != ~0) { + BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1); + PUSH_DATA (push, tp->tp.tess_mode); + } + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2); + PUSH_DATA (push, 0x21); + PUSH_DATA (push, tp->code_base); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1); + PUSH_DATA (push, tp->max_gpr); + + if (tp->tp.input_patch_size <= 32) + IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), tp->tp.input_patch_size); + } else { + BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1); + PUSH_DATA (push, 0x20); } - if (!nvc0_program_validate(nvc0, tp)) - return; nvc0_program_update_context_state(nvc0, tp, 1); - - if (tp->tp.tess_mode != ~0) { - BEGIN_RING(chan, RING_3D(TESS_MODE), 1); - OUT_RING (chan, tp->tp.tess_mode); - } - BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 2); - OUT_RING (chan, 0x21); - OUT_RING (chan, tp->code_base); - BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(2)), 1); - OUT_RING (chan, tp->max_gpr); - - if (tp->tp.input_patch_size <= 32) - IMMED_RING(chan, RING_3D(PATCH_VERTICES), tp->tp.input_patch_size); } void nvc0_tevlprog_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *tp = nvc0->tevlprog; - if (!tp) { - BEGIN_RING(chan, RING_3D(TEP_SELECT), 1); - OUT_RING (chan, 0x30); - return; + if (tp && nvc0_program_validate(nvc0, tp)) { + if (tp->tp.tess_mode != ~0) { + BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1); + PUSH_DATA (push, tp->tp.tess_mode); + } + BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1); + PUSH_DATA (push, 0x31); + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1); + PUSH_DATA (push, tp->code_base); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1); + PUSH_DATA (push, tp->max_gpr); + } else { + BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1); + PUSH_DATA (push, 0x30); } - if (!nvc0_program_validate(nvc0, tp)) - return; nvc0_program_update_context_state(nvc0, tp, 2); - - if (tp->tp.tess_mode != ~0) { - BEGIN_RING(chan, RING_3D(TESS_MODE), 1); - OUT_RING (chan, tp->tp.tess_mode); - } - BEGIN_RING(chan, RING_3D(TEP_SELECT), 1); - OUT_RING (chan, 0x31); - BEGIN_RING(chan, RING_3D(SP_START_ID(3)), 1); - OUT_RING (chan, tp->code_base); - BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(3)), 1); - OUT_RING (chan, tp->max_gpr); } void nvc0_gmtyprog_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *gp = nvc0->gmtyprog; if (gp) nvc0_program_validate(nvc0, gp); + /* we allow GPs with no code for specifying stream output state only */ - if (!gp || !gp->code_size) { - BEGIN_RING(chan, RING_3D(GP_SELECT), 1); - OUT_RING (chan, 0x40); - IMMED_RING(chan, RING_3D(LAYER), 0); - return; + if (gp && gp->code_size) { + const boolean gp_selects_layer = gp->hdr[13] & (1 << 9); + + BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1); + PUSH_DATA (push, 0x41); + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1); + PUSH_DATA (push, gp->code_base); + BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1); + PUSH_DATA (push, gp->max_gpr); + BEGIN_NVC0(push, NVC0_3D(LAYER), 1); + PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0); + } else { + IMMED_NVC0(push, NVC0_3D(LAYER), 0); + BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1); + PUSH_DATA (push, 0x40); } nvc0_program_update_context_state(nvc0, gp, 3); - - BEGIN_RING(chan, RING_3D(GP_SELECT), 1); - OUT_RING (chan, 0x41); - BEGIN_RING(chan, RING_3D(SP_START_ID(4)), 1); - OUT_RING (chan, gp->code_base); - BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(4)), 1); - OUT_RING (chan, gp->max_gpr); - BEGIN_RING(chan, RING_3D(LAYER), 1); - OUT_RING (chan, (gp->hdr[13] & (1 << 9)) ? NVC0_3D_LAYER_USE_GP : 0); } void nvc0_tfb_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_transform_feedback_state *tfb; unsigned b; @@ -215,24 +215,24 @@ nvc0_tfb_validate(struct nvc0_context *nvc0) else tfb = nvc0->vertprog->tfb; - IMMED_RING(chan, RING_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0); + IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0); if (tfb && tfb != nvc0->state.tfb) { for (b = 0; b < 4; ++b) { if (tfb->varying_count[b]) { unsigned n = (tfb->varying_count[b] + 3) / 4; - BEGIN_RING(chan, RING_3D(TFB_STREAM(b)), 3); - OUT_RING (chan, 0); - OUT_RING (chan, tfb->varying_count[b]); - OUT_RING (chan, tfb->stride[b]); - BEGIN_RING(chan, RING_3D(TFB_VARYING_LOCS(b, 0)), n); - OUT_RINGp (chan, tfb->varying_index[b], n); + BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3); + PUSH_DATA (push, 0); + PUSH_DATA (push, tfb->varying_count[b]); + PUSH_DATA (push, tfb->stride[b]); + BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n); + PUSH_DATAp(push, tfb->varying_index[b], n); if (nvc0->tfbbuf[b]) nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b]; } else { - IMMED_RING(chan, RING_3D(TFB_VARYING_COUNT(b)), 0); + IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0); } } } @@ -240,7 +240,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0) if (!(nvc0->dirty & NVC0_NEW_TFB_TARGETS)) return; - nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TFB); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TFB); for (b = 0; b < nvc0->num_tfbbufs; ++b) { struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]); @@ -253,20 +253,20 @@ nvc0_tfb_validate(struct nvc0_context *nvc0) continue; if (!targ->clean) - nvc0_query_fifo_wait(chan, targ->pq); - BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5); - OUT_RING (chan, 1); - OUT_RESRCh(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR); - OUT_RESRCl(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR); - OUT_RING (chan, targ->pipe.buffer_size); + nvc0_query_fifo_wait(push, targ->pq); + BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5); + PUSH_DATA (push, 1); + PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset); + PUSH_DATA (push, buf->address + targ->pipe.buffer_offset); + PUSH_DATA (push, targ->pipe.buffer_size); if (!targ->clean) { - nvc0_query_pushbuf_submit(chan, targ->pq, 0x4); + nvc0_query_pushbuf_submit(push, targ->pq, 0x4); } else { - OUT_RING(chan, 0); /* TFB_BUFFER_OFFSET */ + PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */ targ->clean = FALSE; } - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TFB, buf, NOUVEAU_BO_WR); + BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR); } for (; b < 4; ++b) - IMMED_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 0); + IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0); } diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 32b7a8a8ecf..e349491b66e 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -489,7 +489,7 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s, nvc0->num_textures[s] = nr; - nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX); nvc0->dirty |= NVC0_NEW_TEXTURES; } @@ -621,8 +621,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, } if (nvc0->constbuf[shader][index]) - nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT, - nv04_resource(nvc0->constbuf[shader][index])); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index)); pipe_resource_reference(&nvc0->constbuf[shader][index], res); @@ -681,6 +680,8 @@ nvc0_set_framebuffer_state(struct pipe_context *pipe, { struct nvc0_context *nvc0 = nvc0_context(pipe); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB); + nvc0->framebuffer = *fb; nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; } @@ -731,7 +732,7 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe, memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count); nvc0->num_vtxbufs = count; - nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX); nvc0->dirty |= NVC0_NEW_ARRAYS; } @@ -742,11 +743,16 @@ nvc0_set_index_buffer(struct pipe_context *pipe, { struct nvc0_context *nvc0 = nvc0_context(pipe); - if (ib) { - pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer); + if (nvc0->idxbuf.buffer) + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX); - memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf)); + if (ib && ib->buffer) { + nvc0->dirty |= NVC0_NEW_IDXBUF; + pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer); + nvc0->idxbuf.offset = ib->offset; + nvc0->idxbuf.index_size = ib->index_size; } else { + nvc0->dirty &= ~NVC0_NEW_IDXBUF; pipe_resource_reference(&nvc0->idxbuf.buffer, NULL); } } diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 6307b3a3de6..f235ba57e36 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -6,7 +6,7 @@ static void nvc0_validate_zcull(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct pipe_framebuffer_state *fb = &nvc0->framebuffer; struct nv50_surface *sf = nv50_surface(fb->zsbuf); struct nv50_miptree *mt = nv50_miptree(sf->base.texture); @@ -26,89 +26,85 @@ nvc0_validate_zcull(struct nvc0_context *nvc0) else width = fb->width; - MARK_RING (chan, 23, 4); - BEGIN_RING(chan, RING_3D_(0x1590), 1); /* ZCULL_REGION_INDEX (bits 0x3f) */ - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D_(0x07e8), 2); /* ZCULL_ADDRESS_A_HIGH */ - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(ZCULL_ADDRESS_HIGH), 2); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); offset += 1 << 17; - BEGIN_RING(chan, RING_3D_(0x07f0), 2); /* ZCULL_ADDRESS_B_HIGH */ - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - BEGIN_RING(chan, RING_3D_(0x07e0), 2); - OUT_RING (chan, size); - OUT_RING (chan, size >> 16); - BEGIN_RING(chan, RING_3D_(0x15c8), 1); /* bits 0x3 */ - OUT_RING (chan, 2); - BEGIN_RING(chan, RING_3D_(0x07c0), 4); /* ZCULL dimensions */ - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D_(0x15fc), 2); - OUT_RING (chan, 0); /* bits 0xffff */ - OUT_RING (chan, 0); /* bits 0xffff */ - BEGIN_RING(chan, RING_3D_(0x1958), 1); - OUT_RING (chan, 0); /* bits ~0 */ + BEGIN_NVC0(push, NVC0_3D(ZCULL_LIMIT_HIGH), 2); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); + BEGIN_NVC0(push, SUBC_3D(0x07e0), 2); + PUSH_DATA (push, size); + PUSH_DATA (push, size >> 16); + BEGIN_NVC0(push, SUBC_3D(0x15c8), 1); /* bits 0x3 */ + PUSH_DATA (push, 2); + BEGIN_NVC0(push, NVC0_3D(ZCULL_WIDTH), 4); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(ZCULL_WINDOW_OFFSET_X), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(ZCULL_INVALIDATE), 1); + PUSH_DATA (push, 0); } static void nvc0_validate_fb(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct pipe_framebuffer_state *fb = &nvc0->framebuffer; unsigned i; unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1; boolean serialize = FALSE; - nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB); - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs); - BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, fb->width << 16); - OUT_RING (chan, fb->height << 16); - - MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs); + BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); + PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs); + BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, fb->width << 16); + PUSH_DATA (push, fb->height << 16); for (i = 0; i < fb->nr_cbufs; ++i) { struct nv50_surface *sf = nv50_surface(fb->cbufs[i]); struct nv04_resource *res = nv04_resource(sf->base.texture); struct nouveau_bo *bo = res->bo; - uint32_t offset = sf->offset + res->offset; - BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 9); - OUT_RELOCh(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR); - if (likely(nouveau_bo_tile_layout(bo))) { + BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 9); + PUSH_DATAh(push, res->address + sf->offset); + PUSH_DATA (push, res->address + sf->offset); + if (likely(nouveau_bo_memtype(bo))) { struct nv50_miptree *mt = nv50_miptree(sf->base.texture); assert(sf->base.texture->target != PIPE_BUFFER); - OUT_RING(chan, sf->width); - OUT_RING(chan, sf->height); - OUT_RING(chan, nvc0_format_table[sf->base.format].rt); - OUT_RING(chan, (mt->layout_3d << 16) | + PUSH_DATA(push, sf->width); + PUSH_DATA(push, sf->height); + PUSH_DATA(push, nvc0_format_table[sf->base.format].rt); + PUSH_DATA(push, (mt->layout_3d << 16) | mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING(chan, sf->base.u.tex.first_layer + sf->depth); - OUT_RING(chan, mt->layer_stride >> 2); - OUT_RING(chan, sf->base.u.tex.first_layer); + PUSH_DATA(push, sf->base.u.tex.first_layer + sf->depth); + PUSH_DATA(push, mt->layer_stride >> 2); + PUSH_DATA(push, sf->base.u.tex.first_layer); ms_mode = mt->ms_mode; } else { if (res->base.target == PIPE_BUFFER) { - OUT_RING(chan, 262144); - OUT_RING(chan, 1); + PUSH_DATA(push, 262144); + PUSH_DATA(push, 1); } else { - OUT_RING(chan, nv50_miptree(sf->base.texture)->level[0].pitch); - OUT_RING(chan, sf->height); + PUSH_DATA(push, nv50_miptree(sf->base.texture)->level[0].pitch); + PUSH_DATA(push, sf->height); } - OUT_RING(chan, nvc0_format_table[sf->base.format].rt); - OUT_RING(chan, 1 << 12); - OUT_RING(chan, 1); - OUT_RING(chan, 0); - OUT_RING(chan, 0); + PUSH_DATA(push, nvc0_format_table[sf->base.format].rt); + PUSH_DATA(push, 1 << 12); + PUSH_DATA(push, 1); + PUSH_DATA(push, 0); + PUSH_DATA(push, 0); nvc0_resource_fence(res, NOUVEAU_BO_WR); @@ -121,33 +117,29 @@ nvc0_validate_fb(struct nvc0_context *nvc0) res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; /* only register for writing, otherwise we'd always serialize here */ - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, res, - res->domain | NOUVEAU_BO_WR); + BCTX_REFN(nvc0->bufctx_3d, FB, res, WR); } if (fb->zsbuf) { struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture); struct nv50_surface *sf = nv50_surface(fb->zsbuf); - struct nouveau_bo *bo = mt->base.bo; int unk = mt->base.base.target == PIPE_TEXTURE_2D; - uint32_t offset = sf->offset; - - MARK_RING (chan, 12, 2); - BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, nvc0_format_table[fb->zsbuf->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING (chan, mt->layer_stride >> 2); - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - OUT_RING (chan, (unk << 16) | + + BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5); + PUSH_DATAh(push, mt->base.address + sf->offset); + PUSH_DATA (push, mt->base.address + sf->offset); + PUSH_DATA (push, nvc0_format_table[fb->zsbuf->format].rt); + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, mt->layer_stride >> 2); + BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3); + PUSH_DATA (push, sf->width); + PUSH_DATA (push, sf->height); + PUSH_DATA (push, (unk << 16) | (sf->base.u.tex.first_layer + sf->depth)); - BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1); - OUT_RING (chan, sf->base.u.tex.first_layer); + BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1); + PUSH_DATA (push, sf->base.u.tex.first_layer); ms_mode = mt->ms_mode; @@ -156,58 +148,55 @@ nvc0_validate_fb(struct nvc0_context *nvc0) mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BCTX_REFN(nvc0->bufctx_3d, FB, &mt->base, WR); } else { - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 0); } - IMMED_RING(chan, RING_3D(MULTISAMPLE_MODE), ms_mode); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), ms_mode); - if (serialize) { - BEGIN_RING(chan, RING_3D(SERIALIZE), 1); - OUT_RING (chan, 0); - } + if (serialize) + IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0); } static void nvc0_validate_blend_colour(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; - BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4); - OUT_RINGf (chan, nvc0->blend_colour.color[0]); - OUT_RINGf (chan, nvc0->blend_colour.color[1]); - OUT_RINGf (chan, nvc0->blend_colour.color[2]); - OUT_RINGf (chan, nvc0->blend_colour.color[3]); + BEGIN_NVC0(push, NVC0_3D(BLEND_COLOR(0)), 4); + PUSH_DATAf(push, nvc0->blend_colour.color[0]); + PUSH_DATAf(push, nvc0->blend_colour.color[1]); + PUSH_DATAf(push, nvc0->blend_colour.color[2]); + PUSH_DATAf(push, nvc0->blend_colour.color[3]); } static void nvc0_validate_stencil_ref(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; const ubyte *ref = &nvc0->stencil_ref.ref_value[0]; - IMMED_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), ref[0]); - IMMED_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), ref[1]); + IMMED_NVC0(push, NVC0_3D(STENCIL_FRONT_FUNC_REF), ref[0]); + IMMED_NVC0(push, NVC0_3D(STENCIL_BACK_FUNC_REF), ref[1]); } static void nvc0_validate_stipple(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; unsigned i; - BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32); + BEGIN_NVC0(push, NVC0_3D(POLYGON_STIPPLE_PATTERN(0)), 32); for (i = 0; i < 32; ++i) - OUT_RING(chan, util_bswap32(nvc0->stipple.stipple[i])); + PUSH_DATA(push, util_bswap32(nvc0->stipple.stipple[i])); } static void nvc0_validate_scissor(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct pipe_scissor_state *s = &nvc0->scissor; if (!(nvc0->dirty & NVC0_NEW_SCISSOR) && @@ -215,32 +204,32 @@ nvc0_validate_scissor(struct nvc0_context *nvc0) return; nvc0->state.scissor = nvc0->rast->pipe.scissor; - BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); if (nvc0->rast->pipe.scissor) { - OUT_RING(chan, (s->maxx << 16) | s->minx); - OUT_RING(chan, (s->maxy << 16) | s->miny); + PUSH_DATA(push, (s->maxx << 16) | s->minx); + PUSH_DATA(push, (s->maxy << 16) | s->miny); } else { - OUT_RING(chan, (0xffff << 16) | 0); - OUT_RING(chan, (0xffff << 16) | 0); + PUSH_DATA(push, (0xffff << 16) | 0); + PUSH_DATA(push, (0xffff << 16) | 0); } } static void nvc0_validate_viewport(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct pipe_viewport_state *vp = &nvc0->viewport; int x, y, w, h; float zmin, zmax; - BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3); - OUT_RINGf (chan, vp->translate[0]); - OUT_RINGf (chan, vp->translate[1]); - OUT_RINGf (chan, vp->translate[2]); - BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3); - OUT_RINGf (chan, vp->scale[0]); - OUT_RINGf (chan, vp->scale[1]); - OUT_RINGf (chan, vp->scale[2]); + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3); + PUSH_DATAf(push, vp->translate[0]); + PUSH_DATAf(push, vp->translate[1]); + PUSH_DATAf(push, vp->translate[2]); + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(0)), 3); + PUSH_DATAf(push, vp->scale[0]); + PUSH_DATAf(push, vp->scale[1]); + PUSH_DATAf(push, vp->scale[2]); /* now set the viewport rectangle to viewport dimensions for clipping */ @@ -252,28 +241,27 @@ nvc0_validate_viewport(struct nvc0_context *nvc0) zmin = vp->translate[2] - fabsf(vp->scale[2]); zmax = vp->translate[2] + fabsf(vp->scale[2]); - BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); - OUT_RING (chan, (w << 16) | x); - OUT_RING (chan, (h << 16) | y); - BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); - OUT_RINGf (chan, zmin); - OUT_RINGf (chan, zmax); + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, (w << 16) | x); + PUSH_DATA (push, (h << 16) | y); + BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2); + PUSH_DATAf(push, zmin); + PUSH_DATAf(push, zmax); } static INLINE void nvc0_upload_uclip_planes(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nouveau_bo *bo = nvc0->screen->uniforms; - MARK_RING (chan, 6 + PIPE_MAX_CLIP_PLANES * 4, 2); - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, 256); - OUT_RELOCh(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING_1I(chan, RING_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1); - OUT_RING (chan, 0); - OUT_RINGp (chan, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4); + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, 256); + PUSH_DATAh(push, bo->offset + (5 << 16)); + PUSH_DATA (push, bo->offset + (5 << 16)); + BEGIN_1IC0(push, NVC0_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1); + PUSH_DATA (push, 0); + PUSH_DATAp(push, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4); } static INLINE void @@ -299,7 +287,7 @@ nvc0_check_program_ucps(struct nvc0_context *nvc0, static void nvc0_validate_clip(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *vp; uint8_t clip_enable = nvc0->rast->pipe.clip_plane_enable; @@ -320,46 +308,46 @@ nvc0_validate_clip(struct nvc0_context *nvc0) if (nvc0->state.clip_enable != clip_enable) { nvc0->state.clip_enable = clip_enable; - IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), clip_enable); + IMMED_NVC0(push, NVC0_3D(CLIP_DISTANCE_ENABLE), clip_enable); } if (nvc0->state.clip_mode != vp->vp.clip_mode) { nvc0->state.clip_mode = vp->vp.clip_mode; - BEGIN_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 1); - OUT_RING (chan, vp->vp.clip_mode); + BEGIN_NVC0(push, NVC0_3D(CLIP_DISTANCE_MODE), 1); + PUSH_DATA (push, vp->vp.clip_mode); } } static void nvc0_validate_blend(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; - WAIT_RING(chan, nvc0->blend->size); - OUT_RINGp(chan, nvc0->blend->state, nvc0->blend->size); + PUSH_SPACE(push, nvc0->blend->size); + PUSH_DATAp(push, nvc0->blend->state, nvc0->blend->size); } static void nvc0_validate_zsa(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; - WAIT_RING(chan, nvc0->zsa->size); - OUT_RINGp(chan, nvc0->zsa->state, nvc0->zsa->size); + PUSH_SPACE(push, nvc0->zsa->size); + PUSH_DATAp(push, nvc0->zsa->state, nvc0->zsa->size); } static void nvc0_validate_rasterizer(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; - WAIT_RING(chan, nvc0->rast->size); - OUT_RINGp(chan, nvc0->rast->state, nvc0->rast->size); + PUSH_SPACE(push, nvc0->rast->size); + PUSH_DATAp(push, nvc0->rast->state, nvc0->rast->size); } static void nvc0_constbufs_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nouveau_bo *bo; unsigned s; @@ -377,8 +365,8 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) res = nv04_resource(nvc0->constbuf[s][i]); if (!res) { - BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); - OUT_RING (chan, (i << 4) | 0); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); + PUSH_DATA (push, (i << 4) | 0); if (i == 0) nvc0->state.uniform_buffer_bound[s] = 0; continue; @@ -409,17 +397,15 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) } if (bo != nvc0->screen->uniforms) - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD); if (rebind) { - MARK_RING (chan, 4, 2); - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, align(res->base.width0, 0x100)); - OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); - OUT_RING (chan, (i << 4) | 1); + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, align(res->base.width0, 0x100)); + PUSH_DATAh(push, bo->offset + base); + PUSH_DATA (push, bo->offset + base); + BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); + PUSH_DATA (push, (i << 4) | 1); } if (words) @@ -433,7 +419,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) static void nvc0_validate_sample_mask(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; unsigned mask[4] = { @@ -443,19 +429,19 @@ nvc0_validate_sample_mask(struct nvc0_context *nvc0) nvc0->sample_mask & 0xffff }; - BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4); - OUT_RING (chan, mask[0]); - OUT_RING (chan, mask[1]); - OUT_RING (chan, mask[2]); - OUT_RING (chan, mask[3]); - BEGIN_RING(chan, RING_3D(SAMPLE_SHADING), 1); - OUT_RING (chan, 0x01); + BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4); + PUSH_DATA (push, mask[0]); + PUSH_DATA (push, mask[1]); + PUSH_DATA (push, mask[2]); + PUSH_DATA (push, mask[3]); + BEGIN_NVC0(push, NVC0_3D(SAMPLE_SHADING), 1); + PUSH_DATA (push, 0x01); } static void nvc0_validate_derived_1(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; boolean early_z; boolean rasterizer_discard; @@ -463,7 +449,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0) if (early_z != nvc0->state.early_z) { nvc0->state.early_z = early_z; - IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z); + IMMED_NVC0(push, NVC0_3D(EARLY_FRAGMENT_TESTS), early_z); } rasterizer_discard = (!nvc0->fragprog || !nvc0->fragprog->hdr[18]) && @@ -473,7 +459,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0) if (rasterizer_discard != nvc0->state.rasterizer_discard) { nvc0->state.rasterizer_discard = rasterizer_discard; - IMMED_RING(chan, RING_3D(RASTERIZE_ENABLE), !rasterizer_discard); + IMMED_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), !rasterizer_discard); } } @@ -534,6 +520,7 @@ static struct state_validate { { nvc0_validate_textures, NVC0_NEW_TEXTURES }, { nvc0_validate_samplers, NVC0_NEW_SAMPLERS }, { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS }, + { nvc0_idxbuf_validate, NVC0_NEW_IDXBUF }, { nvc0_tfb_validate, NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG } }; #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) @@ -542,6 +529,7 @@ boolean nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words) { uint32_t state_mask; + int ret; unsigned i; if (nvc0->screen->cur_ctx != nvc0) @@ -557,11 +545,17 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words) validate->func(nvc0); } nvc0->dirty &= ~state_mask; + + nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, FALSE); } - MARK_RING(nvc0->screen->base.channel, words, 0); + nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_3d); + ret = nouveau_pushbuf_validate(nvc0->base.pushbuf); + if (unlikely(ret)) + return FALSE; - nvc0_bufctx_emit_relocs(nvc0); + if (unlikely(nvc0->state.flushed)) + nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, TRUE); return TRUE; } diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h index dc5771a03aa..bd543029705 100644 --- a/src/gallium/drivers/nvc0/nvc0_stateobj.h +++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h @@ -5,12 +5,10 @@ #include "pipe/p_state.h" #define SB_BEGIN_3D(so, m, s) \ - (so)->state[(so)->size++] = \ - (0x2 << 28) | ((s) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2) + (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_SQ(NVC0_3D(m), s) #define SB_IMMED_3D(so, m, d) \ - (so)->state[(so)->size++] = \ - (0x8 << 28) | ((d) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2) + (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_IL(NVC0_3D(m), d) #define SB_DATA(so, u) (so)->state[(so)->size++] = (u) diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 46b5da551db..cb5091ae376 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -73,14 +73,13 @@ nvc0_2d_format(enum pipe_format format) } static int -nvc0_2d_texture_set(struct nouveau_channel *chan, int dst, +nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst, struct nv50_miptree *mt, unsigned level, unsigned layer) { struct nouveau_bo *bo = mt->base.bo; uint32_t width, height, depth; uint32_t format; uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT; - uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); uint32_t offset = mt->level[level].offset; format = nvc0_2d_format(mt->base.base.format); @@ -106,44 +105,44 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst, layer = 0; } - if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) { - BEGIN_RING(chan, RING_2D_(mthd), 2); - OUT_RING (chan, format); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5); - OUT_RING (chan, mt->level[level].pitch); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RELOCh(chan, bo, offset, flags); - OUT_RELOCl(chan, bo, offset, flags); + if (nouveau_bo_memtype(bo)) { + BEGIN_NVC0(push, SUBC_2D(mthd), 2); + PUSH_DATA (push, format); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 5); + PUSH_DATA (push, mt->level[level].pitch); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); } else { - BEGIN_RING(chan, RING_2D_(mthd), 5); - OUT_RING (chan, format); - OUT_RING (chan, 0); - OUT_RING (chan, mt->level[level].tile_mode); - OUT_RING (chan, depth); - OUT_RING (chan, layer); - BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4); - OUT_RING (chan, width); - OUT_RING (chan, height); - OUT_RELOCh(chan, bo, offset, flags); - OUT_RELOCl(chan, bo, offset, flags); + BEGIN_NVC0(push, SUBC_2D(mthd), 5); + PUSH_DATA (push, format); + PUSH_DATA (push, 0); + PUSH_DATA (push, mt->level[level].tile_mode); + PUSH_DATA (push, depth); + PUSH_DATA (push, layer); + BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4); + PUSH_DATA (push, width); + PUSH_DATA (push, height); + PUSH_DATAh(push, bo->offset + offset); + PUSH_DATA (push, bo->offset + offset); } #if 0 if (dst) { - BEGIN_RING(chan, RING_2D_(NVC0_2D_CLIP_X), 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, width); - OUT_RING (chan, height); + BEGIN_NVC0(push, SUBC_2D(NVC0_2D_CLIP_X), 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + PUSH_DATA (push, width); + PUSH_DATA (push, height); } #endif return 0; } static int -nvc0_2d_texture_do_copy(struct nouveau_channel *chan, +nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, struct nv50_miptree *dst, unsigned dst_level, unsigned dx, unsigned dy, unsigned dz, struct nv50_miptree *src, unsigned src_level, @@ -158,15 +157,15 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan, int ret; uint32_t ctrl = 0x00; - ret = MARK_RING(chan, 2 * 16 + 32, 4); + ret = PUSH_SPACE(push, 2 * 16 + 32); if (ret) return ret; - ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz); + ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz); if (ret) return ret; - ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz); + ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz); if (ret) return ret; @@ -175,23 +174,23 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan, ctrl = 0x11; /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */ - BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1); - OUT_RING (chan, ctrl); - BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4); - OUT_RING (chan, dx << dst->ms_x); - OUT_RING (chan, dy << dst->ms_y); - OUT_RING (chan, w << dst->ms_x); - OUT_RING (chan, h << dst->ms_y); - BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); - OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); - BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx << src->ms_x); - OUT_RING (chan, 0); - OUT_RING (chan, sy << src->ms_x); + BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1); + PUSH_DATA (push, ctrl); + BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4); + PUSH_DATA (push, dx << dst->ms_x); + PUSH_DATA (push, dy << dst->ms_y); + PUSH_DATA (push, w << dst->ms_x); + PUSH_DATA (push, h << dst->ms_y); + BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); + PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); + BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4); + PUSH_DATA (push, 0); + PUSH_DATA (push, sx << src->ms_x); + PUSH_DATA (push, 0); + PUSH_DATA (push, sy << src->ms_x); return 0; } @@ -203,7 +202,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { - struct nvc0_screen *screen = nvc0_context(pipe)->screen; + struct nvc0_context *nvc0 = nvc0_context(pipe); int ret; boolean m2mf; unsigned dst_layer = dstz, src_layer = src_box->z; @@ -234,7 +233,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe, src_box->x, src_box->y, src_box->z); for (i = 0; i < src_box->depth; ++i) { - nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny); + nvc0_m2mf_transfer_rect(nvc0, &drect, &srect, nx, ny); if (nv50_miptree(dst)->layout_3d) drect.z++; @@ -252,16 +251,22 @@ nvc0_resource_copy_region(struct pipe_context *pipe, assert(nvc0_2d_format_faithful(src->format)); assert(nvc0_2d_format_faithful(dst->format)); + BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD); + BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR); + nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx); + nouveau_pushbuf_validate(nvc0->base.pushbuf); + for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { - ret = nvc0_2d_texture_do_copy(screen->base.channel, + ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf, nv50_miptree(dst), dst_level, dstx, dsty, dst_layer, nv50_miptree(src), src_level, src_box->x, src_box->y, src_layer, src_box->width, src_box->height); if (ret) - return; + break; } + nouveau_bufctx_reset(nvc0->bufctx, 0); } static void @@ -271,69 +276,65 @@ nvc0_clear_render_target(struct pipe_context *pipe, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { - struct nvc0_context *nv50 = nvc0_context(pipe); - struct nvc0_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; + struct nvc0_context *nvc0 = nvc0_context(pipe); + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nv50_surface *sf = nv50_surface(dst); struct nv04_resource *res = nv04_resource(sf->base.texture); unsigned z; - BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); - OUT_RINGf (chan, color->f[0]); - OUT_RINGf (chan, color->f[1]); - OUT_RINGf (chan, color->f[2]); - OUT_RINGf (chan, color->f[3]); - - if (MARK_RING(chan, 18, 2)) - return; - - BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, ( width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); - - BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 9); - OUT_RESRCh(chan, res, sf->offset, NOUVEAU_BO_WR); - OUT_RESRCl(chan, res, sf->offset, NOUVEAU_BO_WR); - if (likely(nouveau_bo_tile_layout(res->bo))) { + BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); + PUSH_DATAf(push, color->f[0]); + PUSH_DATAf(push, color->f[1]); + PUSH_DATAf(push, color->f[2]); + PUSH_DATAf(push, color->f[3]); + + BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, ( width << 16) | dstx); + PUSH_DATA (push, (height << 16) | dsty); + + BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9); + PUSH_DATAh(push, res->address + sf->offset); + PUSH_DATA (push, res->address + sf->offset); + if (likely(nouveau_bo_memtype(res->bo))) { struct nv50_miptree *mt = nv50_miptree(dst->texture); - OUT_RING(chan, sf->width); - OUT_RING(chan, sf->height); - OUT_RING(chan, nvc0_format_table[dst->format].rt); - OUT_RING(chan, (mt->layout_3d << 16) | + PUSH_DATA(push, sf->width); + PUSH_DATA(push, sf->height); + PUSH_DATA(push, nvc0_format_table[dst->format].rt); + PUSH_DATA(push, (mt->layout_3d << 16) | mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING(chan, dst->u.tex.first_layer + sf->depth); - OUT_RING(chan, mt->layer_stride >> 2); - OUT_RING(chan, dst->u.tex.first_layer); + PUSH_DATA(push, dst->u.tex.first_layer + sf->depth); + PUSH_DATA(push, mt->layer_stride >> 2); + PUSH_DATA(push, dst->u.tex.first_layer); } else { if (res->base.target == PIPE_BUFFER) { - OUT_RING(chan, 262144); - OUT_RING(chan, 1); + PUSH_DATA(push, 262144); + PUSH_DATA(push, 1); } else { - OUT_RING(chan, nv50_miptree(&res->base)->level[0].pitch); - OUT_RING(chan, sf->height); + PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch); + PUSH_DATA(push, sf->height); } - OUT_RING(chan, nvc0_format_table[sf->base.format].rt); - OUT_RING(chan, 1 << 12); - OUT_RING(chan, 1); - OUT_RING(chan, 0); - OUT_RING(chan, 0); + PUSH_DATA(push, nvc0_format_table[sf->base.format].rt); + PUSH_DATA(push, 1 << 12); + PUSH_DATA(push, 1); + PUSH_DATA(push, 0); + PUSH_DATA(push, 0); - IMMED_RING(chan, RING_3D(ZETA_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0); /* tiled textures don't have to be fenced, they're not mapped directly */ nvc0_resource_fence(res, NOUVEAU_BO_WR); } for (z = 0; z < sf->depth; ++z) { - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, 0x3c | + BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, 0x3c | (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); } - nv50->dirty |= NVC0_NEW_FRAMEBUFFER; + nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; } static void @@ -345,57 +346,52 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { - struct nvc0_context *nv50 = nvc0_context(pipe); - struct nvc0_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->base.channel; + struct nvc0_context *nvc0 = nvc0_context(pipe); + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nv50_miptree *mt = nv50_miptree(dst->texture); struct nv50_surface *sf = nv50_surface(dst); - struct nouveau_bo *bo = mt->base.bo; uint32_t mode = 0; int unk = mt->base.base.target == PIPE_TEXTURE_2D; unsigned z; if (clear_flags & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); - OUT_RINGf (chan, depth); + BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); + PUSH_DATAf(push, depth); mode |= NVC0_3D_CLEAR_BUFFERS_Z; } if (clear_flags & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); - OUT_RING (chan, stencil & 0xff); + BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); + PUSH_DATA (push, stencil & 0xff); mode |= NVC0_3D_CLEAR_BUFFERS_S; } - if (MARK_RING(chan, 20, 2)) - return; - - BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2); - OUT_RING (chan, ( width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); - - BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5); - OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RING (chan, nvc0_format_table[dst->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING (chan, mt->layer_stride >> 2); - BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - OUT_RING (chan, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); - BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1); - OUT_RING (chan, dst->u.tex.first_layer); + BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); + PUSH_DATA (push, ( width << 16) | dstx); + PUSH_DATA (push, (height << 16) | dsty); + + BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5); + PUSH_DATAh(push, mt->base.address + sf->offset); + PUSH_DATA (push, mt->base.address + sf->offset); + PUSH_DATA (push, nvc0_format_table[dst->format].rt); + PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode); + PUSH_DATA (push, mt->layer_stride >> 2); + BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3); + PUSH_DATA (push, sf->width); + PUSH_DATA (push, sf->height); + PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); + BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1); + PUSH_DATA (push, dst->u.tex.first_layer); for (z = 0; z < sf->depth; ++z) { - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, mode | + BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, mode | (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); } - nv50->dirty |= NVC0_NEW_FRAMEBUFFER; + nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; } void @@ -404,7 +400,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, double depth, unsigned stencil) { struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct pipe_framebuffer_state *fb = &nvc0->framebuffer; unsigned i; uint32_t mode = 0; @@ -414,34 +410,34 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, return; if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { - BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4); - OUT_RINGf (chan, color->f[0]); - OUT_RINGf (chan, color->f[1]); - OUT_RINGf (chan, color->f[2]); - OUT_RINGf (chan, color->f[3]); + BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4); + PUSH_DATAf(push, color->f[0]); + PUSH_DATAf(push, color->f[1]); + PUSH_DATAf(push, color->f[2]); + PUSH_DATAf(push, color->f[3]); mode = NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G | NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A; } if (buffers & PIPE_CLEAR_DEPTH) { - BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); - OUT_RING (chan, fui(depth)); + BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1); + PUSH_DATA (push, fui(depth)); mode |= NVC0_3D_CLEAR_BUFFERS_Z; } if (buffers & PIPE_CLEAR_STENCIL) { - BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1); - OUT_RING (chan, stencil & 0xff); + BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1); + PUSH_DATA (push, stencil & 0xff); mode |= NVC0_3D_CLEAR_BUFFERS_S; } - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, mode); + BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, mode); for (i = 1; i < fb->nr_cbufs; i++) { - BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); - OUT_RING (chan, (i << 6) | 0x3c); + BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1); + PUSH_DATA (push, (i << 6) | 0x3c); } } @@ -709,42 +705,42 @@ nvc0_blit_set_src(struct nvc0_context *nvc0, static void nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit) { - struct nouveau_channel *chan = blit->screen->base.channel; + struct nouveau_pushbuf *push = blit->screen->base.pushbuf; /* TODO: maybe make this a MACRO (if we need more logic) ? */ /* blend state */ - BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1); - OUT_RING (chan, blit->color_mask); - BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1); - OUT_RING (chan, 0); - IMMED_RING(chan, RING_3D(LOGIC_OP_ENABLE), 0); + BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1); + PUSH_DATA (push, blit->color_mask); + BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1); + PUSH_DATA (push, 0); + IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0); /* rasterizer state */ - BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); - OUT_RING (chan, 0); - IMMED_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 0); - BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - OUT_RING (chan, 0xffff); - BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 1); - OUT_RING (chan, NVC0_3D_POLYGON_MODE_FRONT_FILL); - BEGIN_RING(chan, RING_3D(POLYGON_MODE_BACK), 1); - OUT_RING (chan, NVC0_3D_POLYGON_MODE_BACK_FILL); - IMMED_RING(chan, RING_3D(POLYGON_SMOOTH_ENABLE), 0); - IMMED_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 0); - IMMED_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 0); - IMMED_RING(chan, RING_3D(CULL_FACE_ENABLE), 0); + BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1); + PUSH_DATA (push, 0); + IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0); + BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + PUSH_DATA (push, 0xffff); + BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_FRONT), 1); + PUSH_DATA (push, NVC0_3D_POLYGON_MODE_FRONT_FILL); + BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_BACK), 1); + PUSH_DATA (push, NVC0_3D_POLYGON_MODE_BACK_FILL); + IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0); /* zsa state */ - IMMED_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 0); - IMMED_RING(chan, RING_3D(STENCIL_ENABLE), 0); - IMMED_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0); /* disable transform feedback */ - IMMED_RING(chan, RING_3D(TFB_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0); } static void @@ -835,7 +831,7 @@ nvc0_resource_resolve(struct pipe_context *pipe, struct nvc0_context *nvc0 = nvc0_context(pipe); struct nvc0_screen *screen = nvc0->screen; struct nvc0_blitctx *blit = screen->blitctx; - struct nouveau_channel *chan = screen->base.channel; + struct nouveau_pushbuf *push = screen->base.pushbuf; struct pipe_resource *src = info->src.res; struct pipe_resource *dst = info->dst.res; float x0, x1, y0, y1; @@ -878,11 +874,11 @@ nvc0_resource_resolve(struct pipe_context *pipe, y0 *= (float)(1 << nv50_miptree(src)->ms_y); y1 *= (float)(1 << nv50_miptree(src)->ms_y); - BEGIN_RING(chan, RING_3D(SP_START_ID(5)), 1); - OUT_RING (chan, + BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1); + PUSH_DATA (push, blit->fp.code_base + blit->fp_offset); - IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 0); + IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0); /* Draw a large triangle in screen coordinates covering the whole * render target, with scissors defining the destination region. @@ -890,43 +886,43 @@ nvc0_resource_resolve(struct pipe_context *pipe, * arranged in a way to yield the desired offset and scale. */ - BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2); - OUT_RING (chan, (info->dst.x1 << 16) | info->dst.x0); - OUT_RING (chan, (info->dst.y1 << 16) | info->dst.y0); + BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2); + PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0); + PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0); - IMMED_RING(chan, RING_3D(VERTEX_BEGIN_GL), + IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74201); - OUT_RINGf (chan, x0); - OUT_RINGf (chan, y0); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74200); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 0.0f); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74201); - OUT_RINGf (chan, x1); - OUT_RINGf (chan, y0); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74200); - OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x); - OUT_RINGf (chan, 0.0f); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74201); - OUT_RINGf (chan, x0); - OUT_RINGf (chan, y1); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3); - OUT_RING (chan, 0x74200); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y); - - IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74201); + PUSH_DATAf(push, x0); + PUSH_DATAf(push, y0); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74200); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 0.0f); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74201); + PUSH_DATAf(push, x1); + PUSH_DATAf(push, y0); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74200); + PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x); + PUSH_DATAf(push, 0.0f); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74201); + PUSH_DATAf(push, x0); + PUSH_DATAf(push, y1); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3); + PUSH_DATA (push, 0x74200); + PUSH_DATAf(push, 0.0f); + PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y); + + IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); /* re-enable normally constant state */ - IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); + IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); nvc0_blitctx_post_blit(nvc0, blit); } diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index 0a1bc379868..fd58f80ab97 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -56,6 +56,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe, const struct pipe_sampler_view *templ) { const struct util_format_description *desc; + uint64_t address; uint32_t *tic; uint32_t swz[4]; uint32_t depth; @@ -66,6 +67,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe, view = MALLOC_STRUCT(nv50_tic_entry); if (!view) return NULL; + mt = nv50_miptree(texture); view->pipe = *templ; view->pipe.reference.count = 1; @@ -80,8 +82,6 @@ nvc0_create_sampler_view(struct pipe_context *pipe, desc = util_format_description(view->pipe.format); - /* TIC[0] */ - tic[0] = nvc0_format_table[view->pipe.format].tic; tex_int = util_format_is_pure_integer(view->pipe.format); @@ -96,26 +96,24 @@ nvc0_create_sampler_view(struct pipe_context *pipe, (swz[2] << NV50_TIC_0_MAPB__SHIFT) | (swz[3] << NV50_TIC_0_MAPA__SHIFT); - tic[1] = /* mt->base.bo->offset; */ 0; - tic[2] = /* mt->base.bo->offset >> 32 */ 0; + address = mt->base.address; - tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER; + tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; /* check for linear storage type */ - if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) { + if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (texture->target == PIPE_BUFFER) { - tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER; - tic[1] = /* address offset */ + address += view->pipe.u.buf.first_element * desc->block.bits / 8; + tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER; tic[3] = 0; tic[4] = /* width */ view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1; - tic[5] = 0; + tic[5] = 0; } else { - mt = nv50_miptree(texture); /* must be 2D texture without mip maps */ tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT; if (texture->target != PIPE_TEXTURE_RECT) @@ -126,24 +124,27 @@ nvc0_create_sampler_view(struct pipe_context *pipe, } tic[6] = tic[7] = 0; + tic[1] = address; + tic[2] |= address >> 32; return &view->pipe; } - mt = nv50_miptree(texture); if (mt->base.base.target != PIPE_TEXTURE_RECT) tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; tic[2] |= - ((mt->base.bo->tile_mode & 0x0f0) << (22 - 4)) | - ((mt->base.bo->tile_mode & 0xf00) << (25 - 8)); + ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) | + ((mt->level[0].tile_mode & 0xf00) << (25 - 8)); depth = MAX2(mt->base.base.array_size, mt->base.base.depth0); if (mt->base.base.array_size > 1) { /* there doesn't seem to be a base layer field in TIC */ - tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride; + address += view->pipe.u.tex.first_layer * mt->layer_stride; depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1; } + tic[1] = address; + tic[2] |= address >> 32; switch (mt->base.base.target) { case PIPE_TEXTURE_1D: @@ -205,7 +206,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe, static boolean nvc0_validate_tic(struct nvc0_context *nvc0, int s) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nouveau_bo *txc = nvc0->screen->txc; unsigned i; boolean need_flush = FALSE; @@ -215,53 +216,46 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) struct nv04_resource *res; if (!tic) { - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (i << 1) | 0); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (i << 1) | 0); continue; } res = nv04_resource(tic->pipe.texture); if (tic->id < 0) { - uint32_t offset = res->offset + tic->tic[1]; - tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); - MARK_RING (chan, 9 + 8, 4); - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, 32); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, 0x100111); - BEGIN_RING_NI(chan, RING_MF(DATA), 8); - OUT_RING (chan, tic->tic[0]); - OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RD); - OUT_RELOC (chan, res->bo, offset, res->domain | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]); - OUT_RINGp (chan, &tic->tic[3], 5); + PUSH_SPACE(push, 17); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATAh(push, txc->offset + (tic->id * 32)); + PUSH_DATA (push, txc->offset + (tic->id * 32)); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, 32); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); + BEGIN_NIC0(push, NVC0_M2MF(DATA), 8); + PUSH_DATAp(push, &tic->tic[0], 8); need_flush = TRUE; } else if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { - BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, (tic->id << 4) | 1); + BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1); + PUSH_DATA (push, (tic->id << 4) | 1); } nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res, - res->domain | NOUVEAU_BO_RD); + BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD); - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (tic->id << 9) | (i << 1) | 1); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1); } for (; i < nvc0->state.num_textures[s]; ++i) { - BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); - OUT_RING (chan, (i << 1) | 0); + BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); + PUSH_DATA (push, (i << 1) | 0); } nvc0->state.num_textures[s] = nvc0->num_textures[s]; @@ -277,15 +271,15 @@ void nvc0_validate_textures(struct nvc0_context *nvc0) need_flush |= nvc0_validate_tic(nvc0, 4); if (need_flush) { - BEGIN_RING(nvc0->screen->base.channel, RING_3D(TIC_FLUSH), 1); - OUT_RING (nvc0->screen->base.channel, 0); + BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1); + PUSH_DATA (nvc0->base.pushbuf, 0); } } static boolean nvc0_validate_tsc(struct nvc0_context *nvc0, int s) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; unsigned i; boolean need_flush = FALSE; @@ -293,8 +287,8 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]); if (!tsc) { - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (i << 4) | 0); + BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (i << 4) | 0); continue; } if (tsc->id < 0) { @@ -307,12 +301,12 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) } nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1); + BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1); } for (; i < nvc0->state.num_samplers[s]; ++i) { - BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1); - OUT_RING (chan, (i << 4) | 0); + BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); + PUSH_DATA (push, (i << 4) | 0); } nvc0->state.num_samplers[s] = nvc0->num_samplers[s]; @@ -328,7 +322,7 @@ void nvc0_validate_samplers(struct nvc0_context *nvc0) need_flush |= nvc0_validate_tsc(nvc0, 4); if (need_flush) { - BEGIN_RING(nvc0->screen->base.channel, RING_3D(TSC_FLUSH), 1); - OUT_RING (nvc0->screen->base.channel, 0); + BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1); + PUSH_DATA (nvc0->base.pushbuf, 0); } } diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index f16863733b7..774793d8d02 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -14,12 +14,13 @@ struct nvc0_transfer { }; void -nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, +nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0, const struct nv50_m2mf_rect *dst, const struct nv50_m2mf_rect *src, uint32_t nblocksx, uint32_t nblocksy) { - struct nouveau_channel *chan = nouveau_screen(pscreen)->channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; + struct nouveau_bufctx *bctx = nvc0->bufctx; const int cpp = dst->cpp; uint32_t src_ofst = src->base; uint32_t dst_ofst = dst->base; @@ -30,34 +31,39 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, assert(dst->cpp == src->cpp); - if (nouveau_bo_tile_layout(src->bo)) { - BEGIN_RING(chan, RING_MF(TILING_MODE_IN), 5); - OUT_RING (chan, src->tile_mode); - OUT_RING (chan, src->width * cpp); - OUT_RING (chan, src->height); - OUT_RING (chan, src->depth); - OUT_RING (chan, src->z); + nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD); + nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); + + if (nouveau_bo_memtype(src->bo)) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5); + PUSH_DATA (push, src->tile_mode); + PUSH_DATA (push, src->width * cpp); + PUSH_DATA (push, src->height); + PUSH_DATA (push, src->depth); + PUSH_DATA (push, src->z); } else { src_ofst += src->y * src->pitch + src->x * cpp; - BEGIN_RING(chan, RING_MF(PITCH_IN), 1); - OUT_RING (chan, src->width * cpp); + BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1); + PUSH_DATA (push, src->width * cpp); exec |= NVC0_M2MF_EXEC_LINEAR_IN; } - if (nouveau_bo_tile_layout(dst->bo)) { - BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5); - OUT_RING (chan, dst->tile_mode); - OUT_RING (chan, dst->width * cpp); - OUT_RING (chan, dst->height); - OUT_RING (chan, dst->depth); - OUT_RING (chan, dst->z); + if (nouveau_bo_memtype(dst->bo)) { + BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5); + PUSH_DATA (push, dst->tile_mode); + PUSH_DATA (push, dst->width * cpp); + PUSH_DATA (push, dst->height); + PUSH_DATA (push, dst->depth); + PUSH_DATA (push, dst->z); } else { dst_ofst += dst->y * dst->pitch + dst->x * cpp; - BEGIN_RING(chan, RING_MF(PITCH_OUT), 1); - OUT_RING (chan, dst->width * cpp); + BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1); + PUSH_DATA (push, dst->width * cpp); exec |= NVC0_M2MF_EXEC_LINEAR_OUT; } @@ -65,41 +71,41 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, while (height) { int line_count = height > 2047 ? 2047 : height; - MARK_RING (chan, 17, 4); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATAh(push, src->bo->offset + src_ofst); + PUSH_DATA (push, src->bo->offset + src_ofst); - BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); - OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); - OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD); - - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATAh(push, dst->bo->offset + dst_ofst); + PUSH_DATA (push, dst->bo->offset + dst_ofst); if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) { - BEGIN_RING(chan, RING_MF(TILING_POSITION_IN_X), 2); - OUT_RING (chan, src->x * cpp); - OUT_RING (chan, sy); + BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2); + PUSH_DATA (push, src->x * cpp); + PUSH_DATA (push, sy); } else { src_ofst += line_count * src->pitch; } if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) { - BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2); - OUT_RING (chan, dst->x * cpp); - OUT_RING (chan, dy); + BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2); + PUSH_DATA (push, dst->x * cpp); + PUSH_DATA (push, dy); } else { dst_ofst += line_count * dst->pitch; } - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, nblocksx * cpp); - OUT_RING (chan, line_count); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, exec); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, nblocksx * cpp); + PUSH_DATA (push, line_count); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, exec); height -= line_count; sy += line_count; dy += line_count; } + + nouveau_bufctx_reset(bctx, 0); } void @@ -107,36 +113,44 @@ nvc0_m2mf_push_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, const void *data) { - struct nouveau_channel *chan = nv->screen->channel; + struct nvc0_context *nvc0 = nvc0_context(&nv->pipe); + struct nouveau_pushbuf *push = nv->pushbuf; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; + nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, nvc0->bufctx); + nouveau_pushbuf_validate(push); + while (count) { unsigned nr; - MARK_RING (chan, 16, 2); - - nr = AVAIL_RING(chan) - 9; - nr = MIN2(count, nr); + if (!PUSH_SPACE(push, 16)) + break; + nr = PUSH_AVAIL(push); + assert(nr >= 16); + nr = MIN2(count, nr - 9); nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, nr * 4); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, 0x100111); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATAh(push, dst->offset + offset); + PUSH_DATA (push, dst->offset + offset); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, nr * 4); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, 0x100111); /* must not be interrupted (trap on QUERY fence, 0x50 works however) */ - BEGIN_RING_NI(chan, RING_MF(DATA), nr); - OUT_RINGp (chan, src, nr); + BEGIN_NIC0(push, NVC0_M2MF(DATA), nr); + PUSH_DATAp(push, src, nr); count -= nr; src += nr; offset += nr * 4; } + + nouveau_bufctx_reset(nvc0->bufctx, 0); } void @@ -145,88 +159,37 @@ nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nouveau_channel *chan = nv->screen->channel; + struct nouveau_pushbuf *push = nv->pushbuf; + struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx; + + nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD); + nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); while (size) { unsigned bytes = MIN2(size, 1 << 17); - MARK_RING (chan, 11, 4); - - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2); - OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); - OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, bytes); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) | + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2); + PUSH_DATAh(push, dst->offset + dstoff); + PUSH_DATA (push, dst->offset + dstoff); + BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2); + PUSH_DATAh(push, src->offset + srcoff); + PUSH_DATA (push, src->offset + srcoff); + BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2); + PUSH_DATA (push, bytes); + PUSH_DATA (push, 1); + BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1); + PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) | NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT); srcoff += bytes; dstoff += bytes; size -= bytes; } -} - -#if 0 -static void -nvc0_m2mf_push_rect(struct pipe_screen *pscreen, - const struct nv50_m2mf_rect *dst, - const void *data, - unsigned nblocksx, unsigned nblocksy) -{ - struct nouveau_channel *chan; - const uint8_t *src = (const uint8_t *)data; - const int cpp = dst->cpp; - const int line_len = nblocksx * cpp; - int dy = dst->y; - - assert(nouveau_bo_tile_layout(dst->bo)); - - BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5); - OUT_RING (chan, dst->tile_mode); - OUT_RING (chan, dst->width * cpp); - OUT_RING (chan, dst->height); - OUT_RING (chan, dst->depth); - OUT_RING (chan, dst->z); - - while (nblocksy) { - int line_count, words; - int size = MIN2(AVAIL_RING(chan), NV04_PFIFO_MAX_PACKET_LEN); - if (size < (12 + words)) { - FIRE_RING(chan); - continue; - } - line_count = (size * 4) / line_len; - words = (line_count * line_len + 3) / 4; - - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR); - - BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2); - OUT_RING (chan, dst->x * cpp); - OUT_RING (chan, dy); - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, line_len); - OUT_RING (chan, line_count); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) | - NVC0_M2MF_EXEC_PUSH | NVC0_M2MF_EXEC_LINEAR_IN); - - BEGIN_RING_NI(chan, RING_MF(DATA), words); - OUT_RINGp (chan, src, words); - - dy += line_count; - src += line_len * line_count; - nblocksy -= line_count; - } + nouveau_bufctx_reset(bctx, 0); } -#endif struct pipe_transfer * nvc0_miptree_transfer_new(struct pipe_context *pctx, @@ -236,7 +199,6 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, const struct pipe_box *box) { struct nvc0_context *nvc0 = nvc0_context(pctx); - struct pipe_screen *pscreen = pctx->screen; struct nouveau_device *dev = nvc0->screen->base.device; struct nv50_miptree *mt = nv50_miptree(res); struct nvc0_transfer *tx; @@ -273,7 +235,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, size = tx->base.layer_stride; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, - size * tx->nlayers, &tx->rect[1].bo); + size * tx->nlayers, NULL, &tx->rect[1].bo); if (ret) { FREE(tx); return NULL; @@ -291,7 +253,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, unsigned z = tx->rect[0].z; unsigned i; for (i = 0; i < tx->nlayers; ++i) { - nvc0_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0], + nvc0_m2mf_transfer_rect(nvc0, &tx->rect[1], &tx->rect[0], tx->nblocksx, tx->nblocksy); if (mt->layout_3d) tx->rect[0].z++; @@ -311,14 +273,14 @@ void nvc0_miptree_transfer_del(struct pipe_context *pctx, struct pipe_transfer *transfer) { - struct pipe_screen *pscreen = pctx->screen; + struct nvc0_context *nvc0 = nvc0_context(pctx); struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer; struct nv50_miptree *mt = nv50_miptree(tx->base.resource); unsigned i; if (tx->base.usage & PIPE_TRANSFER_WRITE) { for (i = 0; i < tx->nlayers; ++i) { - nvc0_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1], + nvc0_m2mf_transfer_rect(nvc0, &tx->rect[0], &tx->rect[1], tx->nblocksx, tx->nblocksy); if (mt->layout_3d) tx->rect[0].z++; @@ -338,6 +300,7 @@ void * nvc0_miptree_transfer_map(struct pipe_context *pctx, struct pipe_transfer *transfer) { + struct nvc0_context *nvc0 = nvc0_context(pctx); struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer; int ret; unsigned flags = 0; @@ -350,7 +313,7 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx, if (transfer->usage & PIPE_TRANSFER_WRITE) flags |= NOUVEAU_BO_WR; - ret = nouveau_bo_map(tx->rect[1].bo, flags); + ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->screen->base.client); if (ret) return NULL; return tx->rect[1].bo->map; @@ -360,9 +323,6 @@ void nvc0_miptree_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer) { - struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer; - - nouveau_bo_unmap(tx->rect[1].bo); } void @@ -371,33 +331,34 @@ nvc0_cb_push(struct nouveau_context *nv, unsigned base, unsigned size, unsigned offset, unsigned words, const uint32_t *data) { - struct nouveau_channel *chan = nv->screen->channel; + struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx; + struct nouveau_pushbuf *push = nv->pushbuf; assert(!(offset & 3)); size = align(size, 0x100); - MARK_RING (chan, 16, 2); - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, size); - OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR); + nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain); + nouveau_pushbuf_bufctx(push, bctx); + nouveau_pushbuf_validate(push); + + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, size); + PUSH_DATAh(push, bo->offset + base); + PUSH_DATA (push, bo->offset + base); while (words) { - unsigned nr = AVAIL_RING(chan); + unsigned nr = PUSH_AVAIL(push); nr = MIN2(nr, words); nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1); - BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1); - OUT_RING (chan, offset); - OUT_RINGp (chan, data, nr); + BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1); + PUSH_DATA (push, offset); + PUSH_DATAp(push, data, nr); words -= nr; data += nr; offset += nr * 4; - - if (words) { - MARK_RING(chan, 6, 1); - nouveau_bo_validate(chan, bo, domain | NOUVEAU_BO_WR); - } } + + nouveau_bufctx_reset(bctx, 0); } diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index de456b91945..fbdc5d25d58 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -20,6 +20,8 @@ * SOFTWARE. */ +#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING + #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" @@ -128,7 +130,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, struct pipe_vertex_element *ve, unsigned attr) { const void *data; - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nv04_resource *res = nv04_resource(vb->buffer); float v[4]; int i; @@ -139,10 +141,11 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); - BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), nc + 1); - OUT_RING (chan, VTX_ATTR(attr, nc, FLOAT, 32)); + PUSH_SPACE(push, 6); + BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), nc + 1); + PUSH_DATA (push, VTX_ATTR(attr, nc, FLOAT, 32)); for (i = 0; i < nc; ++i) - OUT_RINGf(chan, v[i]); + PUSH_DATAf(push, v[i]); } static INLINE void @@ -171,7 +174,7 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) nvc0->vbo_fifo = nvc0->vbo_user = 0; - nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX); + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX); for (i = 0; i < nvc0->num_vtxbufs; ++i) { vb = &nvc0->vtxbuf[i]; @@ -189,33 +192,41 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) nvc0->vbo_user |= 1 << i; assert(vb->stride > vb->buffer_offset); nvc0_vbuf_range(nvc0, i, &base, &size); - nouveau_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(&nvc0->base, buf, base, size); } else { nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART); } nvc0->base.vbo_dirty = TRUE; } } - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); + BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD); } } static void nvc0_update_user_vbufs(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; uint32_t base, offset, size; int i; uint32_t written = 0; + /* TODO: use separate bufctx bin for user buffers + */ + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX); + + PUSH_SPACE(push, nvc0->vertex->num_elements * 8); + for (i = 0; i < nvc0->vertex->num_elements; ++i) { struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; const int b = ve->vertex_buffer_index; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b]; struct nv04_resource *buf = nv04_resource(vb->buffer); - if (!(nvc0->vbo_user & (1 << b))) + if (!(nvc0->vbo_user & (1 << b))) { + BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD); continue; + } if (!vb->stride) { nvc0_emit_vtxattr(nvc0, vb, ve, i); @@ -225,17 +236,18 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) if (!(written & (1 << b))) { written |= 1 << b; - nouveau_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(&nvc0->base, buf, base, size); } offset = vb->buffer_offset + ve->src_offset; - MARK_RING (chan, 6, 4); - BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5); - OUT_RING (chan, i); - OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD); - OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD); - OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); - OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); + BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5); + PUSH_DATA (push, i); + PUSH_DATAh(push, buf->address + base + size - 1); + PUSH_DATA (push, buf->address + base + size - 1); + PUSH_DATAh(push, buf->address + offset); + PUSH_DATA (push, buf->address + offset); + + BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD); } nvc0->base.vbo_dirty = TRUE; } @@ -256,7 +268,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0) void nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_vertex_stateobj *vertex = nvc0->vertex; struct pipe_vertex_buffer *vb; struct nvc0_vertex_element *ve; @@ -270,19 +282,21 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) nvc0_prevalidate_vbufs(nvc0); } - BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements); + PUSH_SPACE(push, vertex->num_elements + 1); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements); for (i = 0; i < vertex->num_elements; ++i) { ve = &vertex->element[i]; vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index]; if (likely(vb->stride) || nvc0->vbo_fifo) { - OUT_RING(chan, ve->state); + PUSH_DATA(push, ve->state); } else { - OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST); + PUSH_DATA(push, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST); nvc0->vbo_fifo &= ~(1 << i); } } + PUSH_SPACE(push, vertex->num_elements * 16); for (i = 0; i < vertex->num_elements; ++i) { struct nv04_resource *res; unsigned size, offset; @@ -292,13 +306,13 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) if (unlikely(ve->pipe.instance_divisor)) { if (!(nvc0->state.instance_elts & (1 << i))) { - IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); } - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1); - OUT_RING (chan, ve->pipe.instance_divisor); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_DIVISOR(i)), 1); + PUSH_DATA (push, ve->pipe.instance_divisor); } else if (unlikely(nvc0->state.instance_elts & (1 << i))) { - IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); + IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); } res = nv04_resource(vb->buffer); @@ -306,37 +320,58 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) { if (!nvc0->vbo_fifo) nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, 0); continue; } size = vb->buffer->width0; offset = ve->pipe.src_offset + vb->buffer_offset; - MARK_RING (chan, 8, 4); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, (1 << 12) | vb->stride); - BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5); - OUT_RING (chan, i); - OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD); - OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, (1 << 12) | vb->stride); + BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5); + PUSH_DATA (push, i); + PUSH_DATAh(push, res->address + size - 1); + PUSH_DATA (push, res->address + size - 1); + PUSH_DATAh(push, res->address + offset); + PUSH_DATA (push, res->address + offset); } for (; i < nvc0->state.num_vtxelts; ++i) { - BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(i)), 1); - OUT_RING (chan, NVC0_3D_VERTEX_ATTRIB_INACTIVE); + PUSH_SPACE(push, 5); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(i)), 1); + PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_INACTIVE); if (unlikely(nvc0->state.instance_elts & (1 << i))) - IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); - OUT_RING (chan, 0); + IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1); + PUSH_DATA (push, 0); } nvc0->state.num_vtxelts = vertex->num_elements; nvc0->state.instance_elts = vertex->instance_elts; } +void +nvc0_idxbuf_validate(struct nvc0_context *nvc0) +{ + struct nouveau_pushbuf *push = nvc0->base.pushbuf; + struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer); + + assert(buf); + if (!nouveau_resource_mapped_by_gpu(&buf->base)) + return; + + PUSH_SPACE(push, 6); + BEGIN_NVC0(push, NVC0_3D(INDEX_ARRAY_START_HIGH), 5); + PUSH_DATAh(push, buf->address + nvc0->idxbuf.offset); + PUSH_DATA (push, buf->address + nvc0->idxbuf.offset); + PUSH_DATAh(push, buf->address + buf->base.width0 - 1); + PUSH_DATA (push, buf->address + buf->base.width0 - 1); + PUSH_DATA (push, nvc0->idxbuf.index_size >> 1); + + BCTX_REFN(nvc0->bufctx_3d, IDX, buf, RD); +} + #define NVC0_PRIM_GL_CASE(n) \ case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n @@ -367,13 +402,11 @@ nvc0_prim_gl(unsigned prim) } static void -nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan) +nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push) { - struct nvc0_screen *screen = chan->user_private; + struct nvc0_screen *screen = push->user_priv; nouveau_fence_update(&screen->base, TRUE); - - nvc0_bufctx_emit_relocs(screen->cur_ctx); } static void @@ -381,47 +414,51 @@ nvc0_draw_arrays(struct nvc0_context *nvc0, unsigned mode, unsigned start, unsigned count, unsigned instance_count) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; unsigned prim; if (nvc0->state.index_bias) { - IMMED_RING(chan, RING_3D(VB_ELEMENT_BASE), 0); + PUSH_SPACE(push, 1); + IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0); nvc0->state.index_bias = 0; } prim = nvc0_prim_gl(mode); while (instance_count--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, prim); - BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2); - OUT_RING (chan, start); - OUT_RING (chan, count); - IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); + PUSH_SPACE(push, 6); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, prim); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2); + PUSH_DATA (push, start); + PUSH_DATA (push, count); + IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } static void -nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, +nvc0_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map, unsigned start, unsigned count) { map += start; if (count & 3) { unsigned i; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3); + PUSH_SPACE(push, 4); + BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), count & 3); for (i = 0; i < (count & 3); ++i) - OUT_RING(chan, *map++); + PUSH_DATA(push, *map++); count &= ~3; } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr); + PUSH_SPACE(push, nr + 1); + BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U8), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, + PUSH_DATA(push, (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]); map += 4; } @@ -430,22 +467,24 @@ nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, } static void -nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, +nvc0_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map, unsigned start, unsigned count) { map += start; if (count & 1) { count &= ~1; - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (chan, *map++); + PUSH_SPACE(push, 2); + BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (push, *map++); } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + PUSH_SPACE(push, nr + 1); + BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, (map[1] << 16) | map[0]); + PUSH_DATA(push, (map[1] << 16) | map[0]); map += 2; } count -= nr * 2; @@ -453,7 +492,7 @@ nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, } static void -nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, +nvc0_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map, unsigned start, unsigned count) { map += start; @@ -461,8 +500,9 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, while (count) { const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN); - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr); - OUT_RINGp (chan, map, nr); + PUSH_SPACE(push, nr + 1); + BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), nr); + PUSH_DATAp(push, map, nr); map += nr; count -= nr; @@ -470,22 +510,24 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, } static void -nvc0_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map, +nvc0_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map, unsigned start, unsigned count) { map += start; if (count & 1) { count--; - BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1); - OUT_RING (chan, *map++); + PUSH_SPACE(push, 1); + BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1); + PUSH_DATA (push, *map++); } while (count) { unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2; - BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr); + PUSH_SPACE(push, nr + 1); + BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr); for (i = 0; i < nr; ++i) { - OUT_RING(chan, (map[1] << 16) | map[0]); + PUSH_DATA(push, (map[1] << 16) | map[0]); map += 2; } count -= nr * 2; @@ -497,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, unsigned mode, unsigned start, unsigned count, unsigned instance_count, int32_t index_bias) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; void *data; unsigned prim; const unsigned index_size = nvc0->idxbuf.index_size; @@ -505,34 +547,27 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, prim = nvc0_prim_gl(mode); if (index_bias != nvc0->state.index_bias) { - BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1); - OUT_RING (chan, index_bias); + PUSH_SPACE(push, 2); + BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 1); + PUSH_DATA (push, index_bias); nvc0->state.index_bias = index_bias; } if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) { - struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer); - unsigned offset = nvc0->idxbuf.offset; - unsigned limit = nvc0->idxbuf.buffer->width0 - 1; - - while (instance_count--) { - MARK_RING (chan, 11, 4); - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, mode); - BEGIN_RING(chan, RING_3D(INDEX_ARRAY_START_HIGH), 7); - OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD); - OUT_RESRCh(chan, res, limit, NOUVEAU_BO_RD); - OUT_RESRCl(chan, res, limit, NOUVEAU_BO_RD); - OUT_RING (chan, index_size >> 1); - OUT_RING (chan, start); - OUT_RING (chan, count); - IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); - - nvc0_resource_fence(res, NOUVEAU_BO_RD); - - mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; - } + PUSH_SPACE(push, 1); + IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), prim); + do { + PUSH_SPACE(push, 7); + BEGIN_NVC0(push, NVC0_3D(INDEX_BATCH_FIRST), 2); + PUSH_DATA (push, start); + PUSH_DATA (push, count); + if (--instance_count) { + BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, prim | NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT); + } + } while (instance_count); + IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); } else { data = nouveau_resource_map_offset(&nvc0->base, nv04_resource(nvc0->idxbuf.buffer), @@ -541,26 +576,28 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, return; while (instance_count--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, prim); + PUSH_SPACE(push, 2); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, prim); switch (index_size) { case 1: - nvc0_draw_elements_inline_u08(chan, data, start, count); + nvc0_draw_elements_inline_u08(push, data, start, count); break; case 2: - nvc0_draw_elements_inline_u16(chan, data, start, count); + nvc0_draw_elements_inline_u16(push, data, start, count); break; case 4: if (shorten) - nvc0_draw_elements_inline_u32_short(chan, data, start, count); + nvc0_draw_elements_inline_u32_short(push, data, start, count); else - nvc0_draw_elements_inline_u32(chan, data, start, count); + nvc0_draw_elements_inline_u32(push, data, start, count); break; default: assert(0); return; } - IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); + PUSH_SPACE(push, 1); + IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } @@ -571,7 +608,7 @@ static void nvc0_draw_stream_output(struct nvc0_context *nvc0, const struct pipe_draw_info *info) { - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_so_target *so = nvc0_so_target(info->count_from_stream_output); struct nv04_resource *res = nv04_resource(so->pipe.buffer); unsigned mode = nvc0_prim_gl(info->mode); @@ -579,21 +616,23 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0, if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; - IMMED_RING(chan, RING_3D(SERIALIZE), 0); - nvc0_query_fifo_wait(chan, so->pq); - IMMED_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 0); + PUSH_SPACE(push, 2); + IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0); + nvc0_query_fifo_wait(push, so->pq); + IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0); } while (num_instances--) { - BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); - OUT_RING (chan, mode); - BEGIN_RING(chan, RING_3D(DRAW_TFB_BASE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(DRAW_TFB_STRIDE), 1); - OUT_RING (chan, so->stride); - BEGIN_RING(chan, RING_3D(DRAW_TFB_BYTES), 1); - nvc0_query_pushbuf_submit(chan, so->pq, 0x4); - IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); + PUSH_SPACE(push, 8); + BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1); + PUSH_DATA (push, mode); + BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BASE), 1); + PUSH_DATA (push, 0); + BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_STRIDE), 1); + PUSH_DATA (push, so->stride); + BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BYTES), 1); + nvc0_query_pushbuf_submit(push, so->pq, 0x4); + IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0); mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } @@ -603,7 +642,7 @@ void nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; /* For picking only a few vertices from a large user buffer, push is better, * if index count is larger and we expect repeated vertices, suggest upload. @@ -624,24 +663,27 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* 8 as minimum to avoid immediate double validation of new buffers */ nvc0_state_validate(nvc0, ~0, 8); - chan->flush_notify = nvc0_draw_vbo_flush_notify; + push->kick_notify = nvc0_draw_vbo_kick_notify; if (nvc0->vbo_fifo) { nvc0_push_vbo(nvc0, info); - chan->flush_notify = nvc0_default_flush_notify; + push->kick_notify = nvc0_default_kick_notify; return; } + /* space for base instance, flush, and prim restart */ + PUSH_SPACE(push, 8); + if (nvc0->state.instance_base != info->start_instance) { nvc0->state.instance_base = info->start_instance; /* NOTE: this does not affect the shader input, should it ? */ - BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1); - OUT_RING (chan, info->start_instance); + BEGIN_NVC0(push, NVC0_3D(VB_INSTANCE_BASE), 1); + PUSH_DATA (push, info->start_instance); } if (nvc0->base.vbo_dirty) { - BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); - OUT_RING (chan, 0); + BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 1); + PUSH_DATA (push, 0); nvc0->base.vbo_dirty = FALSE; } @@ -659,20 +701,20 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (info->primitive_restart != nvc0->state.prim_restart) { if (info->primitive_restart) { - BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2); - OUT_RING (chan, 1); - OUT_RING (chan, info->restart_index); + BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2); + PUSH_DATA (push, 1); + PUSH_DATA (push, info->restart_index); if (info->restart_index > 65535) shorten = FALSE; } else { - IMMED_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0); + IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0); } nvc0->state.prim_restart = info->primitive_restart; } else if (info->primitive_restart) { - BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1); - OUT_RING (chan, info->restart_index); + BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1); + PUSH_DATA (push, info->restart_index); if (info->restart_index > 65535) shorten = FALSE; @@ -682,7 +724,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, info->instance_count, info->index_bias); } - chan->flush_notify = nvc0_default_flush_notify; + push->kick_notify = nvc0_default_kick_notify; nvc0_release_user_vbufs(nvc0); } diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h index 0fcf9944c14..c3ab1c93644 100644 --- a/src/gallium/drivers/nvc0/nvc0_winsys.h +++ b/src/gallium/drivers/nvc0/nvc0_winsys.h @@ -4,117 +4,132 @@ #include #include -#include "pipe/p_defines.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" -#include "nouveau/nouveau_reloc.h" +#include "pipe/p_defines.h" -#include "nvc0_resource.h" /* OUT_RESRC */ +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_buffer.h" #ifndef NV04_PFIFO_MAX_PACKET_LEN #define NV04_PFIFO_MAX_PACKET_LEN 2047 #endif -#define NVC0_SUBCH_3D 1 -#define NVC0_SUBCH_2D 2 -#define NVC0_SUBCH_MF 3 -#define NVC0_MF_(n) NVC0_M2MF_##n +static INLINE void +nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin, + unsigned flags, struct nouveau_bo *bo) +{ + nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL; +} + +static INLINE void +nvc0_add_resident(struct nouveau_bufctx *bufctx, int bin, + struct nv04_resource *res, unsigned flags) +{ + struct nouveau_bufref *ref = + nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain); + ref->priv = res; + ref->priv_data = flags; +} + +#define BCTX_REFN_bo(ctx, bin, fl, bo) \ + nv50_add_bufctx_resident_bo(ctx, NVC0_BIND_##bin, fl, bo); + +#define BCTX_REFN(bctx, bin, res, acc) \ + nvc0_add_resident(bctx, NVC0_BIND_##bin, res, NOUVEAU_BO_##acc) + +static INLINE void +PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_pushbuf_refn ref = { bo, flags }; + nouveau_pushbuf_refn(push, &ref, 1); +} + -#define RING_3D(n) ((NVC0_SUBCH_3D << 13) | (NVC0_3D_##n >> 2)) -#define RING_2D(n) ((NVC0_SUBCH_2D << 13) | (NVC0_2D_##n >> 2)) -#define RING_MF(n) ((NVC0_SUBCH_MF << 13) | (NVC0_MF_(n) >> 2)) +#define SUBC_3D(m) 1, (m) +#define NVC0_3D(n) SUBC_3D(NVC0_3D_##n) -#define RING_3D_(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2)) -#define RING_2D_(m) ((NVC0_SUBCH_2D << 13) | ((m) >> 2)) -#define RING_MF_(m) ((NVC0_SUBCH_MF << 13) | ((m) >> 2)) +#define SUBC_2D(m) 2, (m) +#define NVC0_2D(n) SUBC_2D(NVC0_2D_##n) -#define RING_GR(gr, m) (((gr)->subc << 13) | ((m) >> 2)) +#define SUBC_M2MF(m) 3, (m) +#define NVC0_M2MF(n) SUBC_M2MF(NVC0_M2MF_##n) -int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); +#define SUBC_COMPUTE(m) 4, (m) +#define NVC0_COMPUTE(n) SUBC_COMPUTE(NVC0_COMPUTE_##n) -static inline uint32_t -nouveau_bo_tile_layout(const struct nouveau_bo *bo) +static INLINE uint32_t +NVC0_FIFO_PKHDR_SQ(int subc, int mthd, unsigned size) { - return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK; + return 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2); } -static INLINE void -nouveau_bo_validate(struct nouveau_channel *chan, - struct nouveau_bo *bo, unsigned flags) +static INLINE uint32_t +NVC0_FIFO_PKHDR_NI(int subc, int mthd, unsigned size) { - nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0); + return 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2); } -/* incremental methods */ -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size) +static INLINE uint32_t +NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint8_t data) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, (0x2 << 28) | (size << 16) | mthd); + return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2); } -/* non-incremental */ -static INLINE void -BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size) +static INLINE uint32_t +NVC0_FIFO_PKHDR_1I(int subc, int mthd, unsigned size) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, (0x6 << 28) | (size << 16) | mthd); + return 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2); } -/* increment-once */ -static INLINE void -BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size) + +static INLINE uint8_t +nouveau_bo_memtype(const struct nouveau_bo *bo) { - WAIT_RING(chan, size + 1); - OUT_RING (chan, (0xa << 28) | (size << 16) | mthd); + return bo->config.nvc0.memtype; } -/* inline-data */ + static INLINE void -IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data) +PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data) { - WAIT_RING(chan, 1); - OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd); + *push->cur++ = (uint32_t)(data >> 32); } -static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res, - unsigned delta, unsigned flags) +static INLINE void +BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) { - return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags); +#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, size + 1); +#endif + PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(subc, mthd, size)); } -static INLINE int -OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, - unsigned delta, unsigned flags) +static INLINE void +BEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) { - if (flags & NOUVEAU_BO_WR) - res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; - return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); +#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, size + 1); +#endif + PUSH_DATA (push, NVC0_FIFO_PKHDR_NI(subc, mthd, size)); } static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s) +BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size) { - struct nouveau_subchannel *subc = &gr->channel->subc[s]; - - assert(s < 8); - if (subc->gr) { - assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT); - subc->gr->bound = NOUVEAU_GROBJ_UNBOUND; - } - subc->gr = gr; - subc->gr->subc = s; - subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; - - BEGIN_RING(chan, RING_GR(gr, 0x0000), 1); - OUT_RING (chan, gr->grclass); +#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, size + 1); +#endif + PUSH_DATA (push, NVC0_FIFO_PKHDR_1I(subc, mthd, size)); } +static INLINE void +IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint8_t data) +{ +#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING + PUSH_SPACE(push, 1); #endif + PUSH_DATA (push, NVC0_FIFO_PKHDR_IL(subc, mthd, data)); +} + +#endif /* __NVC0_WINSYS_H__ */ diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c index 0cbcc4b2a93..017e92ece9c 100644 --- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c +++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c @@ -6,10 +6,6 @@ #include "nouveau_drm_public.h" -#include "nouveau_drmif.h" -#include "nouveau_channel.h" -#include "nouveau_bo.h" - #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_screen.h" @@ -20,7 +16,7 @@ nouveau_drm_screen_create(int fd) struct pipe_screen *(*init)(struct nouveau_device *); int ret; - ret = nouveau_device_open_existing(&dev, 0, fd, 0); + ret = nouveau_device_wrap(fd, 0, &dev); if (ret) return NULL;