diff options
Diffstat (limited to 'src/gallium/winsys')
22 files changed, 33 insertions, 2478 deletions
diff --git a/src/gallium/winsys/drm/nouveau/common/Makefile b/src/gallium/winsys/drm/nouveau/common/Makefile index 06f558959d..9bc5c42585 100644 --- a/src/gallium/winsys/drm/nouveau/common/Makefile +++ b/src/gallium/winsys/drm/nouveau/common/Makefile @@ -4,17 +4,8 @@ include $(TOP)/configs/current LIBNAME = nouveaudrm C_SOURCES = \ - nouveau_bo.c \ - nouveau_channel.c \ - nouveau_context.c \ - nouveau_device.c \ - nouveau_dma.c \ - nouveau_fence.c \ - nouveau_grobj.c \ + nouveau_context.c \ nouveau_lock.c \ - nouveau_notifier.c \ - nouveau_pushbuf.c \ - nouveau_resource.c \ nouveau_screen.c \ nouveau_winsys.c \ nouveau_winsys_pipe.c \ @@ -27,6 +18,8 @@ include ./Makefile.template DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ && pkg-config libdrm --atleast-version=2.3.1 \ + && pkg-config libdrm_nouveau --exact-version=0.5 \ + && pkg-config libdrm_nouveau --cflags \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") symlinks: diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c deleted file mode 100644 index 76b98bed67..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_bo.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * 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 <stdint.h> -#include <stdlib.h> -#include <errno.h> -#include <assert.h> - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, - void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_mem_free mf; - - if (map && *map) { - drmUnmap(*map, ma->size); - *map = NULL; - } - - if (ma->size) { - mf.offset = ma->offset; - mf.flags = ma->flags; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, - &mf, sizeof(mf)); - ma->size = 0; - } -} - -static int -nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, - uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ma->alignment = align; - ma->size = size; - ma->flags = flags; - if (map) - ma->flags |= NOUVEAU_MEM_MAPPED; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, - sizeof(struct drm_nouveau_mem_alloc)); - if (ret) - return ret; - - if (map) { - ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); - if (ret) { - *map = NULL; - nouveau_mem_free(dev, ma, map); - return ret; - } - } - - return 0; -} - -static void -nouveau_bo_tmp_del(void *priv) -{ - struct nouveau_resource *r = priv; - - nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); - nouveau_resource_free(&r); -} - -static unsigned -nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) -{ - struct nouveau_resource *r = nvdev->sa_heap; - unsigned max = 0; - - while (r) { - if (r->in_use && !nouveau_fence(r->priv)->emitted) { - r = r->next; - continue; - } - - if (max < r->size) - max = r->size; - r = r->next; - } - - return max; -} - -static struct nouveau_resource * -nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, - struct nouveau_fence *fence) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_resource *r = NULL; - struct nouveau_fence *ref = NULL; - - if (fence) - nouveau_fence_ref(fence, &ref); - else - nouveau_fence_new(chan, &ref); - assert(ref); - - while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { - if (nouveau_bo_tmp_max(nvdev) < size) { - nouveau_fence_ref(NULL, &ref); - return NULL; - } - - nouveau_fence_flush(chan); - } - nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); - - return r; -} - -int -nouveau_bo_init(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - int ret; - - ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | - NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); - if (ret) - return ret; - - ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); - if (ret) { - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); - return ret; - } - - return 0; -} - -void -nouveau_bo_takedown(struct nouveau_device *dev) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); -} - -int -nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, - int size, struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - int ret; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - nvbo->base.size = size; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->drm.alignment = align; - nvbo->refcount = 1; - - if (flags & NOUVEAU_BO_TILED) { - nvbo->tiled = 1; - if (flags & NOUVEAU_BO_ZTILE) - nvbo->tiled |= 2; - flags &= ~NOUVEAU_BO_TILED; - } - - ret = nouveau_bo_set_status(&nvbo->base, flags); - if (ret) { - free(nvbo); - return ret; - } - - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo = calloc(1, sizeof(*nvbo)); - if (!nvbo) - return -ENOMEM; - nvbo->base.device = dev; - - nvbo->sysmem = ptr; - nvbo->user = 1; - - nvbo->base.size = size; - nvbo->base.offset = nvbo->drm.offset; - nvbo->base.handle = bo_to_ptr(nvbo); - nvbo->refcount = 1; - *bo = &nvbo->base; - return 0; -} - -int -nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, - struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); - - if (!dev || !bo || *bo) - return -EINVAL; - - nvbo->refcount++; - *bo = &nvbo->base; - return 0; -} - -static void -nouveau_bo_del_cb(void *priv) -{ - struct nouveau_bo_priv *nvbo = priv; - - nouveau_fence_ref(NULL, &nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); -} - -void -nouveau_bo_del(struct nouveau_bo **bo) -{ - struct nouveau_bo_priv *nvbo; - - if (!bo || !*bo) - return; - nvbo = nouveau_bo(*bo); - *bo = NULL; - - if (--nvbo->refcount) - return; - - if (nvbo->pending) - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - - if (nvbo->fence) - nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); - else - nouveau_bo_del_cb(nvbo); -} - -int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence; - - if (!nvbo) - return -EINVAL; - - /* If the buffer is pending it must be busy, unless - * both are RD, in which case we can allow access */ - if (nvbo->pending) { - if ((nvbo->pending->flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD && - (flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_RD) - return 0; - else - return 1; - } - - if (flags & NOUVEAU_BO_WR) - fence = nvbo->fence; - else - fence = nvbo->wr_fence; - - /* If the buffer is not pending and doesn't have a fence - * that conflicts with our flags then it can't be busy - */ - if (!fence) - return 0; - else - /* If the fence is signalled the buffer is not busy, else is busy */ - return !nouveau_fence(fence)->signalled; -} - -int -nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - - if (!nvbo) - return -EINVAL; - - if (nvbo->pending && - (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { - nouveau_pushbuf_flush(nvbo->pending->channel, 0); - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_wait(&nvbo->fence); - else - nouveau_fence_wait(&nvbo->wr_fence); - - if (nvbo->sysmem) - bo->map = nvbo->sysmem; - else - bo->map = nvbo->map; - return 0; -} - -void -nouveau_bo_unmap(struct nouveau_bo *bo) -{ - bo->map = NULL; -} - -static int -nouveau_bo_upload(struct nouveau_bo_priv *nvbo) -{ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); - return 0; -} - -int -nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct drm_nouveau_mem_alloc new; - void *new_map = NULL, *new_sysmem = NULL; - unsigned new_flags = 0, ret; - - assert(!bo->map); - - /* Check current memtype vs requested, if they match do nothing */ - if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) - return 0; - if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && - (flags & NOUVEAU_BO_GART)) - return 0; - if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) - return 0; - - memset(&new, 0x00, sizeof(new)); - - /* Allocate new memory */ - if (flags & NOUVEAU_BO_VRAM) - new_flags |= NOUVEAU_MEM_FB; - else - if (flags & NOUVEAU_BO_GART) - new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); - - if (nvbo->tiled && flags) { - new_flags |= NOUVEAU_MEM_TILE; - if (nvbo->tiled & 2) - new_flags |= NOUVEAU_MEM_TILE_ZETA; - } - - if (new_flags) { - ret = nouveau_mem_alloc(bo->device, bo->size, - nvbo->drm.alignment, new_flags, - &new, &new_map); - if (ret) - return ret; - } else - if (!nvbo->user) { - new_sysmem = malloc(bo->size); - } - - /* Copy old -> new */ - /*XXX: use M2MF */ - if (nvbo->sysmem || nvbo->map) { - struct nouveau_pushbuf_bo *pbo = nvbo->pending; - nvbo->pending = NULL; - nouveau_bo_map(bo, NOUVEAU_BO_RD); - memcpy(new_map, bo->map, bo->size); - nouveau_bo_unmap(bo); - nvbo->pending = pbo; - } - - /* Free old memory */ - if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - - nvbo->drm = new; - nvbo->map = new_map; - if (!nvbo->user) - nvbo->sysmem = new_sysmem; - bo->flags = flags; - bo->offset = nvbo->drm.offset; - return 0; -} - -static int -nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_resource *r; - - if (nvchan->user_charge + bo->size > nvdev->sa.size) - return 1; - - if (!(flags & NOUVEAU_BO_GART)) - return 1; - - r = nouveau_bo_tmp(chan, bo->size, fence); - if (!r) - return 1; - nvchan->user_charge += bo->size; - - memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); - - nvbo->offset = nvdev->sa.offset + r->start; - nvbo->flags = NOUVEAU_BO_GART; - return 0; -} - -static int -nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - int ret; - - ret = nouveau_bo_set_status(bo, flags); - if (ret) { - nouveau_fence_flush(chan); - - ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; - } - - if (nvbo->user) - nouveau_bo_upload(nvbo); - - nvbo->offset = nvbo->drm.offset; - if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) - nvbo->flags = NOUVEAU_BO_GART; - else - nvbo->flags = NOUVEAU_BO_VRAM; - - return 0; -} - -int -nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - uint32_t flags) -{ - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; - int ret; - - assert(bo->map == NULL); - - if (nvbo->user) { - ret = nouveau_bo_validate_user(chan, bo, fence, flags); - if (ret) { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - } else { - ret = nouveau_bo_validate_bo(chan, bo, fence, flags); - if (ret) - return ret; - } - - if (flags & NOUVEAU_BO_WR) - nouveau_fence_ref(fence, &nvbo->wr_fence); - nouveau_fence_ref(fence, &nvbo->fence); - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c deleted file mode 100644 index b7298131c1..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_channel.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 <stdlib.h> -#include <string.h> -#include <errno.h> -#include <util/u_memory.h> -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -int -nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, - uint32_t tt_ctxdma, struct nouveau_channel **chan) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct nouveau_channel_priv *nvchan; - int ret; - - if (!nvdev || !chan || *chan) - return -EINVAL; - - nvchan = CALLOC_STRUCT(nouveau_channel_priv); - if (!nvchan) - return -ENOMEM; - nvchan->base.device = dev; - - nvchan->drm.fb_ctxdma_handle = fb_ctxdma; - nvchan->drm.tt_ctxdma_handle = tt_ctxdma; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, - &nvchan->drm, sizeof(nvchan->drm)); - if (ret) { - FREE(nvchan); - return ret; - } - - nvchan->base.id = nvchan->drm.channel; - if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, - &nvchan->base.vram) || - nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, - &nvchan->base.gart)) { - nouveau_channel_free((void *)&nvchan); - return -EINVAL; - } - - ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, - (void*)&nvchan->user); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - nvchan->put = &nvchan->user[0x40/4]; - nvchan->get = &nvchan->user[0x44/4]; - nvchan->ref_cnt = &nvchan->user[0x48/4]; - - ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, - (drmAddressPtr)&nvchan->notifier_block); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, - (void*)&nvchan->pushbuf); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, - &nvchan->base.nullobj); - if (ret) { - nouveau_channel_free((void *)&nvchan); - return ret; - } - - nouveau_dma_channel_init(&nvchan->base); - nouveau_pushbuf_init(&nvchan->base); - - *chan = &nvchan->base; - return 0; -} - -void -nouveau_channel_free(struct nouveau_channel **chan) -{ - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_channel_free cf; - - if (!chan || !*chan) - return; - nvchan = nouveau_channel(*chan); - *chan = NULL; - nvdev = nouveau_device(nvchan->base.device); - - FIRE_RING_CH(&nvchan->base); - - nouveau_grobj_free(&nvchan->base.vram); - nouveau_grobj_free(&nvchan->base.gart); - nouveau_grobj_free(&nvchan->base.nullobj); - - FREE(nvchan->pb.buffers); - FREE(nvchan->pb.relocs); - cf.channel = nvchan->drm.channel; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); - FREE(nvchan); -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c index e093877381..de4a90e25f 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.c @@ -43,7 +43,7 @@ nouveau_channel_context_create(struct nouveau_device *dev) return NULL; } - nvc->next_handle = 0x80000000; + nvc->next_handle = 0x88000000; if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, &nvc->sync_notifier))) { @@ -120,22 +120,12 @@ nouveau_context_init(struct nouveau_screen *nv_screen, { struct pipe_surface *fb_surf; struct nouveau_pipe_buffer *fb_buf; - struct nouveau_bo_priv *fb_bo; - - fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); - fb_bo->drm.offset = nv_screen->front_offset; - fb_bo->drm.flags = NOUVEAU_MEM_FB; - fb_bo->drm.size = nv_screen->front_pitch * - nv_screen->front_height; - fb_bo->refcount = 1; - fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; - fb_bo->base.offset = fb_bo->drm.offset; - fb_bo->base.handle = (unsigned long)fb_bo; - fb_bo->base.size = fb_bo->drm.size; - fb_bo->base.device = nv_screen->device; fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); - fb_buf->bo = &fb_bo->base; + + nouveau_bo_fake(dev, nv_screen->front_offset, NOUVEAU_BO_VRAM, + nv_screen->front_pitch*nv_screen->front_height, + NULL, &fb_buf->bo); fb_surf = calloc(1, sizeof(struct pipe_surface)); if (nv_screen->front_cpp == 2) diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h index b1bdb01bdf..d7199db3de 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_context.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_context.h @@ -3,7 +3,14 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau_drmif.h" -#include "nouveau_dma.h" +#include "nouveau_device.h" +#include "nouveau_channel.h" +#include "nouveau_pushbuf.h" +#include "nouveau_bo.h" +#include "nouveau_grobj.h" +#include "nouveau_notifier.h" +#include "nouveau_class.h" +#include "nouveau_local.h" struct nouveau_channel_context { struct pipe_screen *pscreen; @@ -29,7 +36,6 @@ struct nouveau_channel_context { struct nouveau_grobj *Nv2D; uint32_t next_handle; - uint32_t next_subchannel; uint32_t next_sequence; }; diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_device.c b/src/gallium/winsys/drm/nouveau/common/nouveau_device.c deleted file mode 100644 index 92b57b834b..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_device.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <util/u_memory.h> -#include "nouveau_drmif.h" - -int -nouveau_device_open_existing(struct nouveau_device **dev, int close, - int fd, drm_context_t ctx) -{ - struct nouveau_device_priv *nvdev; - int ret; - - if (!dev || *dev) - return -EINVAL; - - nvdev = CALLOC_STRUCT(nouveau_device_priv); - if (!nvdev) - return -ENOMEM; - nvdev->fd = fd; - nvdev->ctx = ctx; - nvdev->needs_close = close; - - drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); - - if ((ret = nouveau_bo_init(&nvdev->base))) { - nouveau_device_close((void *)&nvdev); - return ret; - } - - { - uint64_t value; - - ret = nouveau_device_get_param(&nvdev->base, - NOUVEAU_GETPARAM_CHIPSET_ID, - &value); - if (ret) { - nouveau_device_close((void *)&nvdev); - return ret; - } - nvdev->base.chipset = value; - } - - *dev = &nvdev->base; - return 0; -} - -int -nouveau_device_open(struct nouveau_device **dev, const char *busid) -{ - drm_context_t ctx; - int fd, ret; - - if (!dev || *dev) - return -EINVAL; - - fd = drmOpen("nouveau", busid); - if (fd < 0) - return -EINVAL; - - ret = drmCreateContext(fd, &ctx); - if (ret) { - drmClose(fd); - return ret; - } - - ret = nouveau_device_open_existing(dev, 1, fd, ctx); - if (ret) { - drmDestroyContext(fd, ctx); - drmClose(fd); - return ret; - } - - return 0; -} - -void -nouveau_device_close(struct nouveau_device **dev) -{ - struct nouveau_device_priv *nvdev; - - if (dev || !*dev) - return; - nvdev = nouveau_device(*dev); - *dev = NULL; - - nouveau_bo_takedown(&nvdev->base); - - if (nvdev->needs_close) { - drmDestroyContext(nvdev->fd, nvdev->ctx); - drmClose(nvdev->fd); - } - FREE(nvdev); -} - -int -nouveau_device_get_param(struct nouveau_device *dev, - uint64_t param, uint64_t *value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_getparam g; - int ret; - - if (!nvdev || !value) - return -EINVAL; - - g.param = param; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, - &g, sizeof(g)); - if (ret) - return ret; - - *value = g.value; - return 0; -} - -int -nouveau_device_set_param(struct nouveau_device *dev, - uint64_t param, uint64_t value) -{ - struct nouveau_device_priv *nvdev = nouveau_device(dev); - struct drm_nouveau_setparam s; - int ret; - - if (!nvdev) - return -EINVAL; - - s.param = param; - s.value = value; - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, - &s, sizeof(s)); - if (ret) - return ret; - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c deleted file mode 100644 index f8a8ba04f6..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 <stdint.h> -#include <assert.h> -#include <errno.h> - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static inline uint32_t -READ_GET(struct nouveau_channel_priv *nvchan) -{ - return *nvchan->get; -} - -static inline void -WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) -{ - uint32_t put = ((val << 2) + nvchan->dma->base); - volatile int dum; - - NOUVEAU_DMA_BARRIER; - dum = READ_GET(nvchan); - - *nvchan->put = put; - nvchan->dma->put = val; -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); -#endif - - NOUVEAU_DMA_BARRIER; -} - -static inline int -LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) -{ - uint32_t get = *val; - - if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { - *val = (get - dma->base) >> 2; - return 1; - } - - return 0; -} - -void -nouveau_dma_channel_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - int i; - - nvchan->dma = &nvchan->dma_master; - nvchan->dma->base = nvchan->drm.put_base; - nvchan->dma->cur = nvchan->dma->put = 0; - nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; - nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; - - RING_SPACE_CH(chan, RING_SKIPS); - for (i = 0; i < RING_SKIPS; i++) - OUT_RING_CH(chan, 0); -} - -#define CHECK_TIMEOUT() do { \ - if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ - return - EBUSY; \ -} while(0) - -int -nouveau_dma_wait(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - uint32_t get, t_start; - - FIRE_RING_CH(chan); - - t_start = NOUVEAU_TIME_MSEC(); - while (dma->free < size) { - CHECK_TIMEOUT(); - - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - continue; - - if (dma->put >= get) { - dma->free = dma->max - dma->cur; - - if (dma->free < size) { -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = 1; -#endif - OUT_RING_CH(chan, 0x20000000 | dma->base); - if (get <= RING_SKIPS) { - /*corner case - will be idle*/ - if (dma->put <= RING_SKIPS) - WRITE_PUT(nvchan, - RING_SKIPS + 1); - - do { - CHECK_TIMEOUT(); - get = READ_GET(nvchan); - if (!LOCAL_GET(dma, &get)) - get = 0; - } while (get <= RING_SKIPS); - } - - WRITE_PUT(nvchan, RING_SKIPS); - dma->cur = dma->put = RING_SKIPS; - dma->free = get - (RING_SKIPS + 1); - } - } else { - dma->free = get - dma->cur - 1; - } - } - - return 0; -} - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -static void -nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - unsigned mthd_count = 0; - - while (get != put) { - uint32_t gpuget = (get << 2) + nvchan->drm.put_base; - uint32_t data; - - if (get < 0 || get >= nvchan->drm.cmdbuf_size) { - NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); - assert(0); - } - data = nvchan->pushbuf[get++]; - - if (mthd_count) { - NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); - mthd_count--; - continue; - } - - switch (data & 0x60000000) { - case 0x00000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x MTHD " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x20000000: - get = (data & 0x1ffffffc) >> 2; - NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", - gpuget, data, data & 0x1ffffffc); - continue; - case 0x40000000: - mthd_count = (data >> 18) & 0x7ff; - NOUVEAU_MSG("0x%08x 0x%08x NINC " - "Sc %d Mthd 0x%04x Size %d\n", - gpuget, data, (data>>13) & 7, data & 0x1ffc, - mthd_count); - break; - case 0x60000000: - /* DMA_OPCODE_CALL apparently, doesn't seem to work on - * my NV40 at least.. - */ - /* fall-through */ - default: - NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", - gpuget, data); - assert(0); - } - } -} -#endif - -void -nouveau_dma_kickoff(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->cur == dma->put) - return; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); - return; - } -#endif - -#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF - nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); -#endif - - WRITE_PUT(nvchan, dma->cur); -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h deleted file mode 100644 index cfa6d26e82..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_dma.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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_DMA_H__ -#define __NOUVEAU_DMA_H__ - -#include <string.h> -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define RING_SKIPS 8 - -extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); -extern void nouveau_dma_subc_bind(struct nouveau_grobj *); -extern void nouveau_dma_channel_init(struct nouveau_channel *); -extern void nouveau_dma_kickoff(struct nouveau_channel *); - -#ifdef NOUVEAU_DMA_DEBUG -static char faulty[1024]; -#endif - -static inline void -nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free == 0) { - NOUVEAU_ERR("No space left in packet at %s\n", faulty); - return; - } - dma->push_free--; -#endif -#ifdef NOUVEAU_DMA_TRACE - { - uint32_t offset = (dma->cur << 2) + dma->base; - NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", - nvchan->drm.channel, offset, data); - } -#endif - nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; - dma->cur++; -} - -static inline void -nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free < size) { - NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", - dma->push_free, size); - return; - } -#endif -#ifdef NOUVEAU_DMA_TRACE - while (size--) { - nouveau_dma_out(chan, *ptr); - ptr++; - } -#else - memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free -= size; -#endif - dma->cur += size; -#endif -} - -static inline void -nouveau_dma_space(struct nouveau_channel *chan, int size) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - - if (dma->free < size) { - if (nouveau_dma_wait(chan, size) && chan->hang_notify) - chan->hang_notify(chan); - } - dma->free -= size; -#ifdef NOUVEAU_DMA_DEBUG - dma->push_free = size; -#endif -} - -static inline void -nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, - int method, int size, const char* file, int line) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *dma = nvchan->dma; - (void)dma; - -#ifdef NOUVEAU_DMA_TRACE - NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, - grobj->handle, grobj->subc, method, size); -#endif - -#ifdef NOUVEAU_DMA_DEBUG - if (dma->push_free) { - NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", - dma->push_free, faulty); - return; - } - sprintf(faulty,"%s:%d",file,line); -#endif - - nouveau_dma_space(chan, (size + 1)); - nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); -} - -#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) -#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) -#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) -#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ - (dwords)) -#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) -#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) - -#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h deleted file mode 100644 index 5f72800676..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_drmif.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * 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_DRMIF_H__ -#define __NOUVEAU_DRMIF_H__ - -#include <stdint.h> -#include <xf86drm.h> -#include <nouveau_drm.h> - -#include "nouveau/nouveau_device.h" -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_grobj.h" -#include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_bo.h" -#include "nouveau/nouveau_resource.h" -#include "nouveau/nouveau_pushbuf.h" - -struct nouveau_device_priv { - struct nouveau_device base; - - int fd; - drm_context_t ctx; - drmLock *lock; - int needs_close; - - struct drm_nouveau_mem_alloc sa; - void *sa_map; - struct nouveau_resource *sa_heap; -}; -#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) - -extern int -nouveau_device_open_existing(struct nouveau_device **, int close, - int fd, drm_context_t ctx); - -extern int -nouveau_device_open(struct nouveau_device **, const char *busid); - -extern void -nouveau_device_close(struct nouveau_device **); - -extern int -nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); - -extern int -nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); - -struct nouveau_fence { - struct nouveau_channel *channel; -}; - -struct nouveau_fence_cb { - struct nouveau_fence_cb *next; - void (*func)(void *); - void *priv; -}; - -struct nouveau_fence_priv { - struct nouveau_fence base; - int refcount; - - struct nouveau_fence *next; - struct nouveau_fence_cb *signal_cb; - - uint32_t sequence; - int emitted; - int signalled; -}; -#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) - -extern int -nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); - -extern int -nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); - -extern int -nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); - -extern void -nouveau_fence_emit(struct nouveau_fence *); - -extern int -nouveau_fence_wait(struct nouveau_fence **); - -extern void -nouveau_fence_flush(struct nouveau_channel *); - -struct nouveau_pushbuf_reloc { - struct nouveau_pushbuf_bo *pbbo; - uint32_t *ptr; - uint32_t flags; - uint32_t data; - uint32_t vor; - uint32_t tor; -}; - -struct nouveau_pushbuf_bo { - struct nouveau_channel *channel; - struct nouveau_bo *bo; - unsigned flags; - unsigned handled; -}; - -#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 -#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 -struct nouveau_pushbuf_priv { - struct nouveau_pushbuf base; - - struct nouveau_fence *fence; - - unsigned nop_jump; - unsigned start; - unsigned size; - - struct nouveau_pushbuf_bo *buffers; - unsigned nr_buffers; - struct nouveau_pushbuf_reloc *relocs; - unsigned nr_relocs; -}; -#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) - -#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) -#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) -#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) -#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) - -extern int -nouveau_pushbuf_init(struct nouveau_channel *); - -extern int -nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); - -extern int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, - struct nouveau_bo *, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor); - -struct nouveau_dma_priv { - uint32_t base; - uint32_t max; - uint32_t cur; - uint32_t put; - uint32_t free; - - int push_free; -} dma; - -struct nouveau_channel_priv { - struct nouveau_channel base; - - struct drm_nouveau_channel_alloc drm; - - uint32_t *pushbuf; - void *notifier_block; - - volatile uint32_t *user; - volatile uint32_t *put; - volatile uint32_t *get; - volatile uint32_t *ref_cnt; - - struct nouveau_dma_priv dma_master; - struct nouveau_dma_priv dma_bufmgr; - struct nouveau_dma_priv *dma; - - struct nouveau_fence *fence_head; - struct nouveau_fence *fence_tail; - uint32_t fence_sequence; - - struct nouveau_pushbuf_priv pb; - - unsigned user_charge; -}; -#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) - -extern int -nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, - struct nouveau_channel **); - -extern void -nouveau_channel_free(struct nouveau_channel **); - -struct nouveau_grobj_priv { - struct nouveau_grobj base; -}; -#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) - -extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, - int class, struct nouveau_grobj **); -extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, - struct nouveau_grobj **); -extern void nouveau_grobj_free(struct nouveau_grobj **); - - -struct nouveau_notifier_priv { - struct nouveau_notifier base; - - struct drm_nouveau_notifierobj_alloc drm; - volatile void *map; -}; -#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) - -extern int -nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, - struct nouveau_notifier **); - -extern void -nouveau_notifier_free(struct nouveau_notifier **); - -extern void -nouveau_notifier_reset(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_status(struct nouveau_notifier *, int id); - -extern uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *, int id); - -extern int -nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, - int timeout); - -struct nouveau_bo_priv { - struct nouveau_bo base; - - struct nouveau_pushbuf_bo *pending; - struct nouveau_fence *fence; - struct nouveau_fence *wr_fence; - - struct drm_nouveau_mem_alloc drm; - void *map; - - void *sysmem; - int user; - - int refcount; - - uint64_t offset; - uint64_t flags; - int tiled; -}; -#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) - -extern int -nouveau_bo_init(struct nouveau_device *); - -extern void -nouveau_bo_takedown(struct nouveau_device *); - -extern int -nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_user(struct nouveau_device *, void *ptr, int size, - struct nouveau_bo **); - -extern int -nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); - -extern int -nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_del(struct nouveau_bo **); - -extern int -nouveau_bo_busy(struct nouveau_bo *bo, uint32_t flags); - -extern int -nouveau_bo_map(struct nouveau_bo *, uint32_t flags); - -extern void -nouveau_bo_unmap(struct nouveau_bo *); - -extern int -nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - uint32_t flags); - -extern int -nouveau_resource_init(struct nouveau_resource **heap, unsigned start, - unsigned size); - -extern int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **); - -extern void -nouveau_resource_free(struct nouveau_resource **); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c deleted file mode 100644 index 451011e112..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_fence.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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 <stdlib.h> -#include <errno.h> -#include <assert.h> - -#include "nouveau_drmif.h" -#include "nouveau_dma.h" -#include "nouveau_local.h" - -static void -nouveau_fence_del_unsignalled(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence *le; - - if (nvchan->fence_head == fence) { - nvchan->fence_head = nouveau_fence(fence)->next; - if (nvchan->fence_head == NULL) - nvchan->fence_tail = NULL; - return; - } - - le = nvchan->fence_head; - while (le && nouveau_fence(le)->next != fence) - le = nouveau_fence(le)->next; - assert(le && nouveau_fence(le)->next == fence); - nouveau_fence(le)->next = nouveau_fence(fence)->next; - if (nvchan->fence_tail == fence) - nvchan->fence_tail = le; -} - -static void -nouveau_fence_del(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return; - nvfence = nouveau_fence(*fence); - *fence = NULL; - - if (--nvfence->refcount) - return; - - if (nvfence->emitted && !nvfence->signalled) { - if (nvfence->signal_cb) { - nvfence->refcount++; - nouveau_fence_wait((void *)&nvfence); - return; - } - - nouveau_fence_del_unsignalled(&nvfence->base); - } - free(nvfence); -} - -int -nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!chan || !fence || *fence) - return -EINVAL; - - nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); - if (!nvfence) - return -ENOMEM; - nvfence->base.channel = chan; - nvfence->refcount = 1; - - *fence = &nvfence->base; - return 0; -} - -int -nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence) - return -EINVAL; - - if (*fence) { - nouveau_fence_del(fence); - *fence = NULL; - } - - if (ref) { - nvfence = nouveau_fence(ref); - nvfence->refcount++; - *fence = &nvfence->base; - } - - return 0; -} - -int -nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), - void *priv) -{ - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - struct nouveau_fence_cb *cb; - - if (!nvfence || !func) - return -EINVAL; - - cb = malloc(sizeof(struct nouveau_fence_cb)); - if (!cb) - return -ENOMEM; - - cb->func = func; - cb->priv = priv; - cb->next = nvfence->signal_cb; - nvfence->signal_cb = cb; - return 0; -} - -void -nouveau_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); - struct nouveau_fence_priv *nvfence = nouveau_fence(fence); - - nvfence->emitted = 1; - nvfence->sequence = ++nvchan->fence_sequence; - if (nvfence->sequence == 0xffffffff) - NOUVEAU_ERR("AII wrap unhandled\n"); - - /*XXX: assumes subc 0 is populated */ - /* Not the way to fence on nv4 */ - if (nvchan->base.device->chipset >= 0x10) { - RING_SPACE_CH(fence->channel, 2); - OUT_RING_CH (fence->channel, 0x00040050); - OUT_RING_CH (fence->channel, nvfence->sequence); - } - - if (nvchan->fence_tail) { - nouveau_fence(nvchan->fence_tail)->next = fence; - } else { - nvchan->fence_head = fence; - } - nvchan->fence_tail = fence; -} - -void -nouveau_fence_flush(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - uint32_t sequence = *nvchan->ref_cnt; - - while (nvchan->fence_head) { - struct nouveau_fence_priv *nvfence; - - nvfence = nouveau_fence(nvchan->fence_head); - if (nvfence->sequence > sequence) - break; - nouveau_fence_del_unsignalled(&nvfence->base); - nvfence->signalled = 1; - - if (nvfence->signal_cb) { - struct nouveau_fence *fence = NULL; - - nouveau_fence_ref(&nvfence->base, &fence); - - while (nvfence->signal_cb) { - struct nouveau_fence_cb *cb; - - cb = nvfence->signal_cb; - nvfence->signal_cb = cb->next; - cb->func(cb->priv); - free(cb); - } - - nouveau_fence_ref(NULL, &fence); - } - } -} - -int -nouveau_fence_wait(struct nouveau_fence **fence) -{ - struct nouveau_fence_priv *nvfence; - - if (!fence || !*fence) - return -EINVAL; - nvfence = nouveau_fence(*fence); - - if (nvfence->emitted) { - while (!nvfence->signalled) - nouveau_fence_flush(nvfence->base.channel); - } - nouveau_fence_ref(NULL, fence); - - return 0; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c deleted file mode 100644 index fb430a25b8..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_grobj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 <stdlib.h> -#include <errno.h> -#include <util/u_memory.h> -#include "nouveau_drmif.h" - -int -nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, - int class, struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev = nouveau_device(chan->device); - struct nouveau_grobj_priv *nvgrobj; - struct drm_nouveau_grobj_alloc g; - int ret; - - if (!nvdev || !grobj || *grobj) - return -EINVAL; - - nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = class; - - g.channel = chan->id; - g.handle = handle; - g.class = class; - ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, - &g, sizeof(g)); - if (ret) { - nouveau_grobj_free((void *)&nvgrobj); - return ret; - } - - *grobj = &nvgrobj->base; - return 0; -} - -int -nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, - struct nouveau_grobj **grobj) -{ - struct nouveau_grobj_priv *nvgrobj; - - if (!chan || !grobj || *grobj) - return -EINVAL; - - nvgrobj = CALLOC_STRUCT(nouveau_grobj_priv); - if (!nvgrobj) - return -ENOMEM; - nvgrobj->base.channel = chan; - nvgrobj->base.handle = handle; - nvgrobj->base.grclass = 0; - - *grobj = &nvgrobj->base; - return 0; -} - -void -nouveau_grobj_free(struct nouveau_grobj **grobj) -{ - struct nouveau_device_priv *nvdev; - struct nouveau_channel_priv *chan; - struct nouveau_grobj_priv *nvgrobj; - - if (!grobj || !*grobj) - return; - nvgrobj = nouveau_grobj(*grobj); - *grobj = NULL; - - - chan = nouveau_channel(nvgrobj->base.channel); - nvdev = nouveau_device(chan->base.device); - - if (nvgrobj->base.grclass) { - struct drm_nouveau_gpuobj_free f; - - f.channel = chan->drm.channel; - f.handle = nvgrobj->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, - &f, sizeof(f)); - } - FREE(nvgrobj); -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h index 877c7a8c47..11175bce7a 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_local.h +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_local.h @@ -16,100 +16,4 @@ fflush(stderr); \ } while(0) -#define NOUVEAU_TIME_MSEC() 0 - -/* User FIFO control */ -//#define NOUVEAU_DMA_TRACE -//#define NOUVEAU_DMA_DEBUG -//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF -#define NOUVEAU_DMA_BARRIER -#define NOUVEAU_DMA_TIMEOUT 2000 - -/* Push buffer access macros */ -static INLINE void -OUT_RING(struct nouveau_channel *chan, unsigned data) -{ - *(chan->pushbuf->cur++) = (data); -} - -static INLINE void -OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) -{ - memcpy(chan->pushbuf->cur, data, size * 4); - chan->pushbuf->cur += size; -} - -static INLINE void -OUT_RINGf(struct nouveau_channel *chan, float f) -{ - union { uint32_t i; float f; } c; - c.f = f; - OUT_RING(chan, c.i); -} - -static INLINE void -BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - if (chan->pushbuf->remaining < (size + 1)) - nouveau_pushbuf_flush(chan, (size + 1)); - OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); - chan->pushbuf->remaining -= (size + 1); -} - -static INLINE void -FIRE_RING(struct nouveau_channel *chan) -{ - nouveau_pushbuf_flush(chan, 0); -} - -static INLINE void -BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) -{ - gr->subc = subc; - BEGIN_RING(chan, gr, 0x0000, 1); - OUT_RING (chan, gr->handle); -} - -static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, - data, flags, vor, tor); -} - -/* Raw data + flags depending on FB/TT buffer */ -static INLINE void -OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); -} - -/* FB/TT object handle */ -static INLINE void -OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned flags) -{ - OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, - chan->vram->handle, chan->gart->handle); -} - -/* Low 32-bits of offset */ -static INLINE void -OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); -} - -/* High 32-bits of offset */ -static INLINE void -OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, - unsigned delta, unsigned flags) -{ - OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); -} - #endif diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c deleted file mode 100644 index 01e8f38440..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_notifier.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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 <stdlib.h> -#include <errno.h> - -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -#define NOTIFIER(__v) \ - struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ - volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) - -int -nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int count, struct nouveau_notifier **notifier) -{ - struct nouveau_notifier_priv *nvnotify; - int ret; - - if (!chan || !notifier || *notifier) - return -EINVAL; - - nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); - if (!nvnotify) - return -ENOMEM; - nvnotify->base.channel = chan; - nvnotify->base.handle = handle; - - nvnotify->drm.channel = chan->id; - nvnotify->drm.handle = handle; - nvnotify->drm.count = count; - if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, - DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, - &nvnotify->drm, - sizeof(nvnotify->drm)))) { - nouveau_notifier_free((void *)&nvnotify); - return ret; - } - - nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + - nvnotify->drm.offset; - *notifier = &nvnotify->base; - return 0; -} - -void -nouveau_notifier_free(struct nouveau_notifier **notifier) -{ - - struct nouveau_notifier_priv *nvnotify; - struct nouveau_channel_priv *nvchan; - struct nouveau_device_priv *nvdev; - struct drm_nouveau_gpuobj_free f; - - if (!notifier || !*notifier) - return; - nvnotify = nouveau_notifier(*notifier); - *notifier = NULL; - - nvchan = nouveau_channel(nvnotify->base.channel); - nvdev = nouveau_device(nvchan->base.device); - - f.channel = nvchan->drm.channel; - f.handle = nvnotify->base.handle; - drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); - free(nvnotify); -} - -void -nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - n[NV_NOTIFY_TIME_0 /4] = 0x00000000; - n[NV_NOTIFY_TIME_1 /4] = 0x00000000; - n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; - n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << - NV_NOTIFY_STATE_STATUS_SHIFT); -} - -uint32_t -nouveau_notifier_status(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; -} - -uint32_t -nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) -{ - NOTIFIER(n); - - return n[NV_NOTIFY_RETURN_VALUE/4]; -} - -int -nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, - int status, int timeout) -{ - NOTIFIER(n); - uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); - - while (time <= timeout) { - uint32_t v; - - v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; - if (v == status) - return 0; - - if (timeout) - time = NOUVEAU_TIME_MSEC() - t_start; - } - - return -EBUSY; -} - diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c deleted file mode 100644 index 7c094eb795..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_pushbuf.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * 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 <stdlib.h> -#include <errno.h> -#include <assert.h> -#include <util/u_memory.h> -#include "nouveau_drmif.h" -#include "nouveau_dma.h" - -#define PB_BUFMGR_DWORDS (4096 / 2) -#define PB_MIN_USER_DWORDS 2048 - -static int -nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - - assert((min + 1) <= nvchan->dma->max); - - /* Wait for enough space in push buffer */ - min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; - min += 1; /* a bit extra for the NOP */ - if (nvchan->dma->free < min) - WAIT_RING_CH(chan, min); - - /* Insert NOP, may turn into a jump later */ - RING_SPACE_CH(chan, 1); - nvpb->nop_jump = nvchan->dma->cur; - OUT_RING_CH(chan, 0); - - /* Any remaining space is available to the user */ - nvpb->start = nvchan->dma->cur; - nvpb->size = nvchan->dma->free; - nvpb->base.channel = chan; - nvpb->base.remaining = nvpb->size; - nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; - - /* Create a new fence object for this "frame" */ - nouveau_fence_ref(NULL, &nvpb->fence); - nouveau_fence_new(chan, &nvpb->fence); - - return 0; -} - -int -nouveau_pushbuf_init(struct nouveau_channel *chan) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_dma_priv *m = &nvchan->dma_master; - struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; - int i; - - if (!nvchan) - return -EINVAL; - - /* Reassign last bit of push buffer for a "separate" bufmgr - * ring buffer - */ - m->max -= PB_BUFMGR_DWORDS; - m->free -= PB_BUFMGR_DWORDS; - - b->base = m->base + ((m->max + 2) << 2); - b->max = PB_BUFMGR_DWORDS - 2; - b->cur = b->put = 0; - b->free = b->max - b->cur; - - /* Some NOPs just to be safe - *XXX: RING_SKIPS - */ - nvchan->dma = b; - RING_SPACE_CH(chan, 8); - for (i = 0; i < 8; i++) - OUT_RING_CH(chan, 0); - nvchan->dma = m; - - nouveau_pushbuf_space(chan, 0); - chan->pushbuf = &nvchan->pb.base; - - nvchan->pb.buffers = CALLOC(NOUVEAU_PUSHBUF_MAX_BUFFERS, - sizeof(struct nouveau_pushbuf_bo)); - nvchan->pb.relocs = CALLOC(NOUVEAU_PUSHBUF_MAX_RELOCS, - sizeof(struct nouveau_pushbuf_reloc)); - return 0; -} - -static uint32_t -nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, - struct nouveau_pushbuf_reloc *r) -{ - uint32_t push; - - if (r->flags & NOUVEAU_BO_LOW) { - push = bo->offset + r->data; - } else - if (r->flags & NOUVEAU_BO_HIGH) { - push = (bo->offset + r->data) >> 32; - } else { - push = r->data; - } - - if (r->flags & NOUVEAU_BO_OR) { - if (bo->flags & NOUVEAU_BO_VRAM) - push |= r->vor; - else - push |= r->tor; - } - - return push; -} - -/* This would be our TTM "superioctl" */ -int -nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) -{ - struct nouveau_channel_priv *nvchan = nouveau_channel(chan); - struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - int ret, i; - - if (nvpb->base.remaining == nvpb->size) - return 0; - - nouveau_fence_flush(chan); - - nvpb->size -= nvpb->base.remaining; - nvchan->dma->cur += nvpb->size; - nvchan->dma->free -= nvpb->size; - assert(nvchan->dma->cur <= nvchan->dma->max); - - nvchan->dma = &nvchan->dma_bufmgr; - nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | - (nvchan->dma->base + (nvchan->dma->cur << 2)); - - /* Validate buffers + apply relocations */ - nvchan->user_charge = 0; - for (i = 0; i < nvpb->nr_relocs; i++) { - struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; - struct nouveau_pushbuf_bo *pbbo = r->pbbo; - struct nouveau_bo *bo = pbbo->bo; - - /* Validated, mem matches presumed, no relocation necessary */ - if (pbbo->handled & 2) { - if (!(pbbo->handled & 1)) - assert(0); - continue; - } - - /* Not yet validated, do it now */ - if (!(pbbo->handled & 1)) { - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - if (ret) { - assert(0); - return ret; - } - pbbo->handled |= 1; - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { - pbbo->handled |= 2; - continue; - } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - } - - /* Apply the relocation */ - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - } - nvpb->nr_relocs = 0; - - /* Dereference all buffers on validate list */ - for (i = 0; i < nvpb->nr_buffers; i++) { - struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; - - nouveau_bo(pbbo->bo)->pending = NULL; - nouveau_bo_del(&pbbo->bo); - } - nvpb->nr_buffers = 0; - - /* Switch back to user's ring */ - RING_SPACE_CH(chan, 1); - OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + - nvchan->dma_master.base)); - nvchan->dma = &nvchan->dma_master; - - /* Fence + kickoff */ - nouveau_fence_emit(nvpb->fence); - FIRE_RING_CH(chan); - - /* Allocate space for next push buffer */ - ret = nouveau_pushbuf_space(chan, min); - assert(!ret); - - return 0; -} - -static struct nouveau_pushbuf_bo * -nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - struct nouveau_pushbuf_bo *pbbo; - - if (nvbo->pending) - return nvbo->pending; - - if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) - return NULL; - pbbo = nvpb->buffers + nvpb->nr_buffers++; - nvbo->pending = pbbo; - - nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); - pbbo->channel = chan; - pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->handled = 0; - return pbbo; -} - -int -nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, - struct nouveau_bo *bo, uint32_t data, uint32_t flags, - uint32_t vor, uint32_t tor) -{ - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); - struct nouveau_pushbuf_bo *pbbo; - struct nouveau_pushbuf_reloc *r; - - if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) - return -ENOMEM; - - pbbo = nouveau_pushbuf_emit_buffer(chan, bo); - if (!pbbo) - return -ENOMEM; - pbbo->flags |= (flags & NOUVEAU_BO_RDWR); - pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - - r = nvpb->relocs + nvpb->nr_relocs++; - r->pbbo = pbbo; - r->ptr = ptr; - r->flags = flags; - r->data = data; - r->vor = vor; - r->tor = tor; - - if (flags & NOUVEAU_BO_DUMMY) - *(uint32_t *)ptr = 0; - else - *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); - return 0; -} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c deleted file mode 100644 index 766fd279fe..0000000000 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_resource.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 <stdlib.h> -#include <errno.h> -#include <util/u_memory.h> -#include "nouveau_drmif.h" -#include "nouveau_local.h" - -int -nouveau_resource_init(struct nouveau_resource **heap, - unsigned start, unsigned size) -{ - struct nouveau_resource *r; - - r = CALLOC_STRUCT(nouveau_resource); - if (!r) - return 1; - - r->start = start; - r->size = size; - *heap = r; - return 0; -} - -int -nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, - struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!heap || !size || !res || *res) - return 1; - - while (heap) { - if (!heap->in_use && heap->size >= size) { - r = CALLOC_STRUCT(nouveau_resource); - 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_resource_free(struct nouveau_resource **res) -{ - struct nouveau_resource *r; - - if (!res || !*res) - return; - r = *res; - *res = NULL; - - r->in_use = 0; - - if (r->next && !r->next->in_use) { - struct nouveau_resource *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/winsys/drm/nouveau/common/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c index 722694e4a4..3b2b86cd40 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys.c @@ -29,8 +29,9 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, if (ret) return ret; - assert(nv->nvc->next_subchannel < 7); - BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); + BEGIN_RING(chan, *grobj, 0x0000, 1); + OUT_RING (chan, (*grobj)->handle); + (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; return 0; } @@ -73,14 +74,8 @@ static int nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, struct pipe_fence_handle **fence) { - if (fence) { - struct nouveau_pushbuf *pb = nvws->channel->pushbuf; - struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(nvpb->fence, &ref); - *fence = (struct pipe_fence_handle *)ref; - } + if (fence) + *fence = NULL; return nouveau_pushbuf_flush(nvws->channel, size); } diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index 8e889b9f36..6f79e0800a 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -105,7 +105,7 @@ nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) { struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); - nouveau_bo_del(&nvbuf->bo); + nouveau_bo_ref(NULL, &nvbuf->bo); FREE(nvbuf); } @@ -121,6 +121,7 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) map_flags |= NOUVEAU_BO_WR; +#if 0 if (flags & PIPE_BUFFER_USAGE_DISCARD && !(flags & PIPE_BUFFER_USAGE_CPU_READ) && nouveau_bo_busy(nvbuf->bo, map_flags)) { @@ -131,10 +132,11 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, uint32_t flags = nouveau_flags_from_usage(nv, buf->usage); if (!nouveau_bo_new(dev, flags, buf->alignment, buf->size, &rename)) { - nouveau_bo_del(&nvbuf->bo); + nouveau_bo_ref(NULL, &nvbuf->bo); nvbuf->bo = rename; } } +#endif if (nouveau_bo_map(nvbuf->bo, map_flags)) return NULL; @@ -149,42 +151,26 @@ nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) nouveau_bo_unmap(nvbuf->bo); } -static INLINE struct nouveau_fence * -nouveau_pipe_fence(struct pipe_fence_handle *pfence) -{ - return (struct nouveau_fence *)pfence; -} - static void nouveau_pipe_fence_reference(struct pipe_winsys *ws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence) { - nouveau_fence_ref((void *)pfence, (void *)ptr); + *ptr = pfence; } static int nouveau_pipe_fence_signalled(struct pipe_winsys *ws, struct pipe_fence_handle *pfence, unsigned flag) { - struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - - if (nouveau_fence(fence)->signalled == 0) - nouveau_fence_flush(nvpws->nv->nvc->channel); - - return !nouveau_fence(fence)->signalled; + return 0; } static int nouveau_pipe_fence_finish(struct pipe_winsys *ws, struct pipe_fence_handle *pfence, unsigned flag) { - struct nouveau_fence *fence = nouveau_pipe_fence(pfence); - struct nouveau_fence *ref = NULL; - - nouveau_fence_ref(fence, &ref); - return nouveau_fence_wait(&ref); + return 0; } static void diff --git a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c index e9a8a2ac1c..b83f3475df 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv04_surface.c @@ -354,7 +354,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); @@ -366,7 +365,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); OUT_RING (chan, nvc->channel->vram->handle); @@ -378,7 +376,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating blit object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); @@ -392,7 +389,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NOUVEAU_ERR("Error creating rect object: %d\n", ret); return 1; } - BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); @@ -431,8 +427,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) return 1; } - BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; } else @@ -449,8 +443,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) return 1; } - BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - return 0; } diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c index c8ab7f690f..d16f3a97d5 100644 --- a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c +++ b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c @@ -34,7 +34,7 @@ nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) if (surf_format < 0) return 1; - if (!nouveau_bo(bo)->tiled) { + if (!bo->tiled) { BEGIN_RING(chan, eng2d, mthd, 2); OUT_RING (chan, surf_format); OUT_RING (chan, 1); @@ -166,7 +166,6 @@ nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) return ret; nvc->Nv2D = eng2d; - BIND_RING (chan, eng2d, nvc->next_subchannel++); BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); OUT_RING (chan, nvc->sync_notifier->handle); OUT_RING (chan, chan->vram->handle); diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index e129e42e97..3f3553b61d 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -26,6 +26,9 @@ C_SOURCES = \ ASM_SOURCES = +DRIVER_DEFINES = $(shell pkg-config libdrm_nouveau --cflags) +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + include ../../Makefile.template symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h index 8257790d47..64cf326411 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.h @@ -5,8 +5,6 @@ #include <xmlconfig.h> #include <nouveau/nouveau_winsys.h> #include "../common/nouveau_context.h" -#include "../common/nouveau_drmif.h" -#include "../common/nouveau_dma.h" struct nouveau_framebuffer { struct st_framebuffer *stfb; diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c index 1d7c92376f..964a9028aa 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c +++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen_dri.c @@ -12,7 +12,7 @@ #include "nouveau_screen_dri.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 #error nouveau_drm.h version does not match expected version #endif |