From 7b971a50088caeeb2d66d99dbf6bef580a01c5d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 16 May 2007 15:14:20 -0700 Subject: WIP: Replace TTM buffer pool manager with a simplified interface. The interface is not solid yet (some simplification to do still, and adjustment for 0-copy), and the drivers are not converted. However, the new interface allows using the same calls to support either a TTM or a classic static allocation backend, with the static backend allowing a more limited feature set. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 506 ++------------- src/mesa/drivers/dri/common/dri_bufmgr.h | 203 ++++-- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 871 ++++++++++++++++++++++++++ src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 356 +++++++++++ src/mesa/drivers/dri/common/dri_bufpool.h | 86 --- src/mesa/drivers/dri/common/dri_drmpool.c | 227 ------- 6 files changed, 1453 insertions(+), 796 deletions(-) create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr_fake.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr_ttm.c delete mode 100644 src/mesa/drivers/dri/common/dri_bufpool.h delete mode 100644 src/mesa/drivers/dri/common/dri_drmpool.c (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 65d6545965..fc2d4a0665 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -1,493 +1,123 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * +/* + * Copyright © 2007 Intel Corporation + * * 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, sub license, 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: - * + * 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 (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Eric Anholt * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell */ -#include -#include -#include "glthread.h" -#include "errno.h" +#include "mtypes.h" #include "dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "dri_bufpool.h" -_glthread_DECLARE_STATIC_MUTEX(bmMutex); - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. +/** @file dri_bufmgr.c + * + * Convenience functions for buffer management methods. */ - - -typedef struct _DriFenceObject -{ - int fd; - _glthread_Mutex mutex; - int refCount; - const char *name; - drmFence fence; -} DriFenceObject; - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - unsigned flags; - unsigned hint; - unsigned alignment; - void *private; -} DriBufferObject; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -DriFenceObject * -driFenceBuffers(int fd, char *name, unsigned flags) -{ - DriFenceObject *fence = (DriFenceObject *) malloc(sizeof(*fence)); - int ret; - - if (!fence) - BM_CKFATAL(-EINVAL); - - _glthread_LOCK_MUTEX(bmMutex); - fence->refCount = 1; - fence->name = name; - fence->fd = fd; - _glthread_INIT_MUTEX(fence->mutex); - ret = drmFenceBuffers(fd, flags, &fence->fence); - _glthread_UNLOCK_MUTEX(bmMutex); - if (ret) { - free(fence); - BM_CKFATAL(ret); - } - return fence; -} - - -unsigned -driFenceType(DriFenceObject * fence) +dri_bo * +dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, unsigned int flags, unsigned int hint) { - unsigned ret; - - _glthread_LOCK_MUTEX(bmMutex); - ret = fence->fence.flags; - _glthread_UNLOCK_MUTEX(bmMutex); - - return ret; + return bufmgr->bo_alloc(bufmgr, name, size, alignment, flags, hint); } - -DriFenceObject * -driFenceReference(DriFenceObject * fence) +dri_bo * +dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, + unsigned long size, void *virtual, unsigned int flags, + unsigned int hint) { - _glthread_LOCK_MUTEX(bmMutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(bmMutex); - return fence; + return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, + flags, hint); } void -driFenceUnReference(DriFenceObject * fence) +dri_bo_reference(dri_bo *bo) { - if (!fence) - return; - - _glthread_LOCK_MUTEX(bmMutex); - if (--fence->refCount == 0) { - drmFenceDestroy(fence->fd, &fence->fence); - free(fence); - } - _glthread_UNLOCK_MUTEX(bmMutex); + bo->bufmgr->bo_reference(bo); } void -driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) +dri_bo_unreference(dri_bo *bo) { - int ret; - unsigned flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = drmFenceWait(fence->fd, flags, &fence->fence, type); - _glthread_UNLOCK_MUTEX(fence->mutex); - BM_CKFATAL(ret); + bo->bufmgr->bo_unreference(bo); } int -driFenceSignaled(DriFenceObject * fence, unsigned type) +dri_bo_map(dri_bo *buf, GLboolean write_enable) { - int signaled; - int ret; - - if (fence == NULL) - return GL_TRUE; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = drmFenceSignaled(fence->fd, &fence->fence, type, &signaled); - _glthread_UNLOCK_MUTEX(fence->mutex); - BM_CKFATAL(ret); - return signaled; -} - - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); + return buf->bufmgr->bo_map(buf, write_enable); } -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual)); - _glthread_UNLOCK_MUTEX(buf->mutex); - return virtual; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - assert(buf->private != NULL); - - buf->pool->unmap(buf->pool, buf->private); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned -driBOFlags(struct _DriBufferObject *buf) -{ - unsigned ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (++buf->refCount == 1) { - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(bmMutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(bmMutex); - tmp = --buf->refCount; - _glthread_UNLOCK_MUTEX(bmMutex); - if (!tmp) { - buf->pool->destroy(buf->pool, buf->private); - free(buf); - } -} - -void -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, unsigned flags) -{ - void *virtual; - int newBuffer; - struct _DriBufferPool *pool; - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - newBuffer = !buf->private || (pool->size(pool, buf->private) < size) || - pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual); - - if (newBuffer) { - if (buf->private) - pool->destroy(pool, buf->private); - if (!flags) - flags = buf->flags; - buf->private = pool->create(pool, size, flags, 0, buf->alignment); - if (!buf->private) - BM_CKFATAL(-ENOMEM); - BM_CKFATAL(pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual)); - } - - if (data != NULL) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetStatic(struct _DriBufferObject *buf, - unsigned long offset, - unsigned long size, void *virtual, unsigned flags) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setStatic\n"); - BM_CKFATAL(-EINVAL); - } - if (buf->pool->setstatic == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-EINVAL); - } - - if (!flags) - flags = buf->flags; - - buf->private = buf->pool->setstatic(buf->pool, offset, size, - virtual, flags); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - - - -void -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, unsigned flags, unsigned hint) +int +dri_bo_unmap(dri_bo *buf) { - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - BM_CKFATAL(-ENOMEM); - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(bmMutex); - buf->refCount = 1; - _glthread_UNLOCK_MUTEX(bmMutex); - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } + return buf->bufmgr->bo_unmap(buf); } -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) +int +dri_bo_validate(dri_bo *buf, unsigned int flags) { - ; + return buf->bufmgr->bo_validate(buf, flags); } - -void -driBOCreateList(int target, drmBOList * list) +dri_fence * +dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed) { - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOCreateList(target, list)); - _glthread_UNLOCK_MUTEX(bmMutex); + return bufmgr->fence_validated(bufmgr, name, flushed); } void -driBOResetList(drmBOList * list) +dri_fence_reference(dri_fence *fence) { - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOResetList(list)); - _glthread_UNLOCK_MUTEX(bmMutex); + fence->bufmgr->fence_reference(fence); } void -driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, - unsigned flags, unsigned mask) +dri_fence_unreference(dri_fence *fence) { - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmAddValidateItem(list, driBOKernel(buf), - flags, mask, &newItem)); - _glthread_UNLOCK_MUTEX(bmMutex); - - /* - * Tell userspace pools to validate the buffer. This should be a - * noop if the pool is already validated. - * FIXME: We should have a list for this as well. - */ - - if (buf->pool->validate) { - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private)); - } - - _glthread_UNLOCK_MUTEX(buf->mutex); + fence->bufmgr->fence_unreference(fence); } void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data) { - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); + if (size == 0 || data == NULL) + return; + dri_bo_map(bo, GL_TRUE); + memcpy((unsigned char *)bo->virtual + offset, data, size); + dri_bo_unmap(bo); } -void -driBOValidateList(int fd, drmBOList * list) -{ - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOValidateList(fd, list)); - _glthread_UNLOCK_MUTEX(bmMutex); -} void -driPoolTakeDown(struct _DriBufferPool *pool) +dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data) { - pool->takeDown(pool); + if (size == 0 || data == NULL) + return; + dri_bo_map(bo, GL_FALSE); + memcpy(data, (unsigned char *)bo->virtual + offset, size); + dri_bo_unmap(bo); } diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 01f149ae4e..eafee88b88 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -1,5 +1,6 @@ /************************************************************************** * + * Copyright © 2007 Intel Corporation * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA * All Rights Reserved. * @@ -28,43 +29,142 @@ /* * Authors: Thomas Hellström * Keith Whitwell + * Eric Anholt */ #ifndef _DRI_BUFMGR_H_ #define _DRI_BUFMGR_H_ #include +typedef struct _dri_bufmgr dri_bufmgr; +typedef struct _dri_bo dri_bo; +typedef struct _dri_fence dri_fence; -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; +struct _dri_bo { + /** Size in bytes of the buffer object. */ + unsigned long size; + /** + * Card virtual address (offset from the beginning of the aperture) for the + * object. Only valid while validated. + */ + unsigned long offset; + /** + * Virtual address for accessing the buffer data. Only valid while mapped. + */ + void *virtual; + /** Buffer manager context associated with this buffer object */ + dri_bufmgr *bufmgr; +}; -extern struct _DriFenceObject *driFenceBuffers(int fd, char *name, - unsigned flags); +struct _dri_fence { + /** + * This is an ORed mask of DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE, and + * DRM_FLAG_EXE indicating the operations associated with this fence. + * + * It is constant for the life of the fence object. + */ + unsigned int type; + /** Buffer manager context associated with this fence */ + dri_bufmgr *bufmgr; +}; -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); +/** + * Context for a buffer manager instance. + * + * Contains public methods followed by private storage for the buffer manager. + */ +struct _dri_bufmgr { + /** + * Allocate a buffer object. + * + * Buffer objects are not necessarily initially mapped into CPU virtual + * address space or graphics device aperture. They must be mapped using + * bo_map() to be used by the CPU, and validated for use using bo_validate() + * to be used from the graphics device. + * + * XXX: flags/hint reason to live? + */ + dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long size, unsigned int alignment, + unsigned int flags, unsigned int hint); -extern void driFenceUnReference(struct _DriFenceObject *fence); + /** + * Allocates a buffer object for a static allocation. + * + * Static allocations are ones such as the front buffer that are offered by + * the X Server, which are never evicted and never moved. + * + * XXX: flags/hint reason to live? + */ + dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int flags, + unsigned int hint); -extern void -driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); + /** Takes a reference on a buffer object */ + void (*bo_reference)(dri_bo *bo); -extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); -extern unsigned driFenceType(struct _DriFenceObject *fence); + /** + * Releases a reference on a buffer object, freeing the data if + * rerefences remain. + */ + void (*bo_unreference)(dri_bo *bo); -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ + /** + * Maps the buffer into userspace. + * + * This function will block waiting for any existing fence on the buffer to + * clear, first. The resulting mapping is available at buf->virtual. +\ */ + int (*bo_map)(dri_bo *buf, GLboolean write_enable); + + /** Reduces the refcount on the userspace mapping of the buffer object. */ + int (*bo_unmap)(dri_bo *buf); + + /** + * Makes the buffer accessible to the graphics chip. + * + * The resulting offset of the buffer within the graphics aperture is then + * available at buf->offset until the buffer is fenced. + * + * Flags should consist of the memory types that the buffer may be validated + * into and the read/write/exe flags appropriate to the use of the buffer. + */ + int (*bo_validate)(dri_bo *buf, unsigned int flags); + + /** + * Associates the current set of validated buffers with a fence. + * + * Once fenced, the buffer manager will allow the validated buffers to be + * evicted when the graphics device's execution has passed the fence + * command. + * + * The fence object will have flags for the sum of the read/write/exe flags + * of the validated buffers associated with it. + */ + dri_fence * (*fence_validated)(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed); + + /** Takes a reference on a fence object */ + void (*fence_reference)(dri_fence *fence); -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); + /** + * Releases a reference on a fence object, freeing the data if + * rerefences remain. + */ + void (*fence_unreference)(dri_fence *fence); + + /** + * Blocks until the given fence is signaled. + */ + void (*fence_wait)(dri_fence *fence); + + /** + * Checks and returns whether the given fence is signaled. + */ +}; + +/* extern void driBOData(struct _DriBufferObject *r_buf, unsigned size, const void *data, unsigned flags); extern void driBOSubData(struct _DriBufferObject *buf, @@ -73,27 +173,40 @@ extern void driBOSubData(struct _DriBufferObject *buf, extern void driBOGetSubData(struct _DriBufferObject *buf, unsigned long offset, unsigned long size, void *data); -extern void driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, unsigned flags, unsigned hint); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern void driBOCreateList(int target, drmBOList * list); -extern void driBOResetList(drmBOList * list); -extern void driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, - unsigned flags, unsigned mask); -extern void driBOValidateList(int fd, drmBOList * list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetStatic(struct _DriBufferObject *buf, - unsigned long offset, - unsigned long size, void *virtual, unsigned flags); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); +*/ + +dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, unsigned int flags, + unsigned int hint); +dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int flags, + unsigned int hint); +void dri_bo_reference(dri_bo *bo); +void dri_bo_unreference(dri_bo *bo); +int dri_bo_map(dri_bo *buf, GLboolean write_enable); +int dri_bo_unmap(dri_bo *buf); +int dri_bo_validate(dri_bo *buf, unsigned int flags); +dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed); +void dri_fence_reference(dri_fence *fence); +void dri_fence_unreference(dri_fence *fence); + +void dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data); +void dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data); + +dri_bufmgr *dri_bufmgr_ttm_init(int fd, unsigned int fence_type, + unsigned int fence_type_flush); + +void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, + unsigned long size, + unsigned int (*fence_emit)(void *private), + int (*fence_wait)(void *private, + unsigned int cookie), + void *driver_priv); +void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c new file mode 100644 index 0000000000..2519808851 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -0,0 +1,871 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 (including the + * next paragraph) 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +/* Originally a fake version of the buffer manager so that we can + * prototype the changes in a driver fairly quickly, has been fleshed + * out to a fully functional interim solution. + * + * Basically wraps the old style memory management in the new + * programming interface, but is more expressive and avoids many of + * the bugs in the old texture manager. + */ +#include "mtypes.h" +#include "dri_bufmgr.h" +#include "drm.h" + +#include "simple_list.h" +#include "mm.h" +#include "imports.h" + +#define DBG(...) + +/* Internal flags: + */ +#define BM_NO_BACKING_STORE DRM_BO_FLAG_MEM_PRIV0 +#define BM_NO_FENCE_SUBDATA DRM_BO_FLAG_MEM_PRIV1 + +/* Wrapper around mm.c's mem_block, which understands that you must + * wait for fences to expire before memory can be freed. This is + * specific to our use of memcpy for uploads - an upload that was + * processed through the command queue wouldn't need to care about + * fences. + */ +struct block { + struct block *next, *prev; + struct mem_block *mem; /* BM_MEM_AGP */ + + unsigned referenced:1; + unsigned on_hardware:1; + unsigned fenced:1; + + unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ + + dri_bo *bo; + void *virtual; +}; + +typedef struct _bufmgr_fake { + dri_bufmgr bufmgr; + + _glthread_Mutex mutex; /**< for thread safety */ + + unsigned long low_offset; + unsigned long size; + void *virtual; + + struct mem_block *heap; + struct block lru; /* only allocated, non-fence-pending blocks here */ + + unsigned buf_nr; /* for generating ids */ + + struct block referenced; /* after bmBufferOffset */ + struct block on_hardware; /* after bmValidateBuffers */ + struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ + /* then to bufmgr->lru or free() */ + + unsigned int last_fence; + + unsigned fail:1; + unsigned need_fence:1; + GLboolean thrashing; + + /** + * Driver callback to emit a fence, returning the cookie. + * + * Currently, this also requires that a write flush be emitted before + * emitting the fence, but this should change. + */ + unsigned int (*fence_emit)(void *private); + /** Driver callback to wait for a fence cookie to have passed. */ + int (*fence_wait)(void *private, unsigned int fence_cookie); + /** Driver-supplied argument to driver callbacks */ + void *driver_priv; +} dri_bufmgr_fake; + +typedef struct _dri_bo_fake { + dri_bo bo; + + unsigned id; /* debug only */ + const char *name; + + unsigned dirty:1; + unsigned int refcount; + /* Flags may consist of any of the DRM_BO flags, plus + * DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two + * driver private flags. + */ + unsigned int flags; + unsigned int alignment; + GLboolean is_static; + + struct block *block; + void *backing_store; + void (*invalidate_cb)(dri_bufmgr *bufmgr, void * ); + void *invalidate_ptr; +} dri_bo_fake; + +typedef struct _dri_fence_fake { + dri_fence fence; + + const char *name; + unsigned int refcount; + unsigned int fence_cookie; + GLboolean flushed; +} dri_fence_fake; + +static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, + unsigned int fence_cookie); + +#define MAXFENCE 0x7fffffff + +static GLboolean FENCE_LTE( unsigned a, unsigned b ) +{ + if (a == b) + return GL_TRUE; + + if (a < b && b - a < (1<<24)) + return GL_TRUE; + + if (a > b && MAXFENCE - a + b < (1<<24)) + return GL_TRUE; + + return GL_FALSE; +} + +static unsigned int +_fence_emit_internal(dri_bufmgr_fake *bufmgr_fake) +{ + bufmgr_fake->last_fence = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); + return bufmgr_fake->last_fence; +} + +static void +_fence_wait_internal(dri_bufmgr_fake *bufmgr_fake, unsigned int cookie) +{ + int ret; + + ret = bufmgr_fake->fence_wait(bufmgr_fake->driver_priv, cookie); + if (ret != 0) { + _mesa_printf("%s:%d: Error %d waiting for fence.\n", + __FILE__, __LINE__); + abort(); + } + clear_fenced(bufmgr_fake, cookie); +} + +static GLboolean +_fence_test(dri_bufmgr_fake *bufmgr_fake, unsigned fence) +{ + /* Slight problem with wrap-around: + */ + return fence == 0 || FENCE_LTE(fence, bufmgr_fake->last_fence); +} + +/** + * Allocate a memory manager block for the buffer. + */ +static GLboolean +alloc_block(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + dri_bufmgr_fake *bufmgr_fake= (dri_bufmgr_fake *)bo->bufmgr; + struct block *block = (struct block *)calloc(sizeof *block, 1); + unsigned int align_log2 = ffs(bo_fake->alignment); + GLuint sz; + + if (!block) + return GL_FALSE; + + sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1); + + block->mem = mmAllocMem(bufmgr_fake->heap, sz, align_log2, 0); + if (!block->mem) { + free(block); + return GL_FALSE; + } + + make_empty_list(block); + + /* Insert at head or at tail??? + */ + insert_at_tail(&bufmgr_fake->lru, block); + + block->virtual = bufmgr_fake->virtual + block->mem->ofs; + block->bo = bo; + + bo_fake->block = block; + + return GL_TRUE; +} + +/* Release the card storage associated with buf: + */ +static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block) +{ + DBG("free block %p\n", block); + + if (!block) + return; + + if (block->referenced) { + _mesa_printf("tried to free block on referenced list\n"); + assert(0); + } + else if (block->on_hardware) { + block->bo = NULL; + } + else if (block->fenced) { + block->bo = NULL; + } + else { + DBG(" - free immediately\n"); + remove_from_list(block); + + mmFreeMem(block->mem); + free(block); + } +} + +static void +alloc_backing_store(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + assert(!bo_fake->backing_store); + assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + + bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64); +} + +static void +free_backing_store(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + + if (bo_fake->backing_store) { + ALIGN_FREE(bo_fake->backing_store); + bo_fake->backing_store = NULL; + } +} + +static void +set_dirty(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + if (bo_fake->flags & BM_NO_BACKING_STORE) + bo_fake->invalidate_cb(&bufmgr_fake->bufmgr, bo_fake->invalidate_ptr); + + assert(!(bo_fake->flags & DRM_BO_FLAG_NO_EVICT)); + + DBG("set_dirty - buf %d\n", bo_fake->id); + bo_fake->dirty = 1; +} + +static GLboolean +evict_lru(dri_bufmgr_fake *bufmgr_fake, GLuint max_fence) +{ + struct block *block, *tmp; + + DBG("%s\n", __FUNCTION__); + + foreach_s(block, tmp, &bufmgr_fake->lru) { + dri_bo_fake *bo_fake = (dri_bo_fake *)block->bo; + + if (bo_fake != NULL && (bo_fake->flags & BM_NO_FENCE_SUBDATA)) + continue; + + if (block->fence && max_fence && !FENCE_LTE(block->fence, max_fence)) + return 0; + + set_dirty(&bo_fake->bo); + bo_fake->block = NULL; + + free_block(bufmgr_fake, block); + return GL_TRUE; + } + + return GL_FALSE; +} + +#define foreach_s_rev(ptr, t, list) \ + for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) + +static GLboolean +evict_mru(dri_bufmgr_fake *bufmgr_fake) +{ + struct block *block, *tmp; + + DBG("%s\n", __FUNCTION__); + + foreach_s_rev(block, tmp, &bufmgr_fake->lru) { + dri_bo_fake *bo_fake = (dri_bo_fake *)block->bo; + + if (bo_fake && (bo_fake->flags & BM_NO_FENCE_SUBDATA)) + continue; + + set_dirty(&bo_fake->bo); + bo_fake->block = NULL; + + free_block(bufmgr_fake, block); + return GL_TRUE; + } + + return GL_FALSE; +} + +/** + * Removes all objects from the fenced list older than the given fence. + */ +static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, + unsigned int fence_cookie) +{ + struct block *block, *tmp; + int ret = 0; + + foreach_s(block, tmp, &bufmgr_fake->fenced) { + assert(block->fenced); + + if (_fence_test(bufmgr_fake, block->fence)) { + + block->fenced = 0; + + if (!block->bo) { + DBG("delayed free: offset %x sz %x\n", + block->mem->ofs, block->mem->size); + remove_from_list(block); + mmFreeMem(block->mem); + free(block); + } + else { + DBG("return to lru: offset %x sz %x\n", + block->mem->ofs, block->mem->size); + move_to_tail(&bufmgr_fake->lru, block); + } + + ret = 1; + } + else { + /* Blocks are ordered by fence, so if one fails, all from + * here will fail also: + */ + break; + } + } + + /* Also check the referenced list: + */ + foreach_s(block, tmp, &bufmgr_fake->referenced ) { + if (block->fenced && _fence_test(bufmgr_fake, block->fence)) { + block->fenced = 0; + } + } + + DBG("%s: %d\n", __FUNCTION__, ret); + return ret; +} + +static void fence_blocks(dri_bufmgr_fake *bufmgr_fake, unsigned fence) +{ + struct block *block, *tmp; + + foreach_s (block, tmp, &bufmgr_fake->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->bo, fence); + block->fence = fence; + + block->on_hardware = 0; + block->fenced = 1; + + /* Move to tail of pending list here + */ + move_to_tail(&bufmgr_fake->fenced, block); + } + + /* Also check the referenced list: + */ + foreach_s (block, tmp, &bufmgr_fake->referenced) { + if (block->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->bo, fence); + + block->fence = fence; + block->on_hardware = 0; + block->fenced = 1; + } + } + + assert(is_empty_list(&bufmgr_fake->on_hardware)); +} + +static GLboolean evict_and_alloc_block(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + assert(bo_fake->block == NULL); + + /* Search for already free memory: + */ + if (alloc_block(bo)) + return GL_TRUE; + + /* If we're not thrashing, allow lru eviction to dig deeper into + * recently used textures. We'll probably be thrashing soon: + */ + if (!bufmgr_fake->thrashing) { + while (evict_lru(bufmgr_fake, 0)) + if (alloc_block(bo)) + return GL_TRUE; + } + + /* Keep thrashing counter alive? + */ + if (bufmgr_fake->thrashing) + bufmgr_fake->thrashing = 20; + + /* Wait on any already pending fences - here we are waiting for any + * freed memory that has been submitted to hardware and fenced to + * become available: + */ + while (!is_empty_list(&bufmgr_fake->fenced)) { + GLuint fence = bufmgr_fake->fenced.next->fence; + _fence_wait_internal(bufmgr_fake, fence); + + if (alloc_block(bo)) + return GL_TRUE; + } + + if (!is_empty_list(&bufmgr_fake->on_hardware)) { + while (!is_empty_list(&bufmgr_fake->fenced)) { + GLuint fence = bufmgr_fake->fenced.next->fence; + _fence_wait_internal(bufmgr_fake, fence); + } + + if (!bufmgr_fake->thrashing) { + DBG("thrashing\n"); + } + bufmgr_fake->thrashing = 20; + + if (alloc_block(bo)) + return GL_TRUE; + } + + while (evict_mru(bufmgr_fake)) + if (alloc_block(bo)) + return GL_TRUE; + + DBG("%s 0x%x bytes failed\n", __FUNCTION__, bo->size); + + assert(is_empty_list(&bufmgr_fake->on_hardware)); + assert(is_empty_list(&bufmgr_fake->fenced)); + + return GL_FALSE; +} + +/*********************************************************************** + * Public functions + */ + +/** + * Wait for hardware idle by emitting a fence and waiting for it. + */ +static void +dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake) +{ + unsigned int cookie; + + cookie = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); + _fence_wait_internal(bufmgr_fake->driver_priv, cookie); +} + +/* Specifically ignore texture memory sharing. + * -- just evict everything + * -- and wait for idle + */ +void +dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + struct block *block, *tmp; + + assert(is_empty_list(&bufmgr_fake->referenced)); + + bufmgr_fake->need_fence = 1; + bufmgr_fake->fail = 0; + + /* Wait for hardware idle. We don't know where acceleration has been + * happening, so we'll need to wait anyway before letting anything get + * put on the card again. + */ + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + assert(is_empty_list(&bufmgr_fake->fenced)); + assert(is_empty_list(&bufmgr_fake->on_hardware)); + + foreach_s(block, tmp, &bufmgr_fake->lru) { + assert(_fence_test(bufmgr_fake, block->fence)); + set_dirty(block->bo); + } + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static dri_bo * +dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, unsigned int flags, + unsigned int hint) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake; + + bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + bo_fake = calloc(1, sizeof(*bo_fake)); + if (!bo_fake) + return NULL; + + bo_fake->bo.size = size; + bo_fake->bo.offset = -1; + bo_fake->bo.virtual = NULL; + bo_fake->bo.bufmgr = bufmgr; + bo_fake->refcount = 1; + + /* Alignment must be a power of two */ + assert((alignment & (alignment - 1)) == 0); + if (alignment == 0) + alignment = 1; + bo_fake->alignment = alignment; + bo_fake->id = ++bufmgr_fake->buf_nr; + bo_fake->name = name; + bo_fake->flags = flags; + bo_fake->is_static = GL_FALSE; + + return &bo_fake->bo; +} + +static dri_bo * +dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, void *virtual, + unsigned int flags, unsigned int hint) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake; + + bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + bo_fake = calloc(1, sizeof(*bo_fake)); + if (!bo_fake) + return NULL; + + bo_fake->bo.size = size; + bo_fake->bo.offset = offset; + bo_fake->bo.virtual = virtual; + bo_fake->bo.bufmgr = bufmgr; + bo_fake->refcount = 1; + bo_fake->name = name; + bo_fake->flags = flags; + bo_fake->is_static = GL_TRUE; + + return &bo_fake->bo; +} + +static void +dri_fake_bo_reference(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + bo_fake->refcount++; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_bo_unreference(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + if (!bo) + return; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + if (--bo_fake->refcount == 0) { + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + /* No remaining references, so free it */ + if (bo_fake->block) + free_block(bufmgr_fake, bo_fake->block); + free_backing_store(bo); + free(bo); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +/** + * Map a buffer into bo->virtual, allocating either card memory space (If + * BM_NO_BACKING_STORE or DRM_BO_FLAG_NO_EVICT) or backing store, as necessary. + */ +static int +dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* Static buffers are always mapped. */ + if (bo_fake->is_static) + return 0; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + DBG("bmMapBuffer %d\n", bo_fake->id); + + if (bo->virtual != NULL) { + _mesa_printf("%s: already mapped\n", __FUNCTION__); + abort(); + } + else if (bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT)) { + + if (!bo_fake->block && !evict_and_alloc_block(bo)) { + DBG("%s: alloc failed\n", __FUNCTION__); + bufmgr_fake->fail = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 1; + } + else { + assert(bo_fake->block); + bo_fake->dirty = 0; + + if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA)) + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + bo->virtual = bo_fake->block->virtual; + } + } + else { + if (write_enable) + set_dirty(bo); + + if (bo_fake->backing_store == 0) + alloc_backing_store(bo); + + bo->virtual = bo_fake->backing_store; + } + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 0; +} + +static int +dri_fake_bo_unmap(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* Static buffers are always mapped. */ + if (bo_fake->is_static) + return 0; + + if (bo == NULL) + return 0; + + bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + + bo->virtual = NULL; + + return 0; +} + +static int +dri_fake_bo_validate(dri_bo *bo, unsigned int flags) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* XXX: Sanity-check whether we've already validated this one under + * different flags. See drmAddValidateItem(). + */ + + bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + /* Allocate the card memory */ + if (!bo_fake->block && !evict_and_alloc_block(bo)) { + bufmgr_fake->fail = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return -1; + } + + assert(bo_fake->block); + assert(bo_fake->block->bo == &bo_fake->bo); + + DBG("Add buf %d (block %p, dirty %d) to referenced list\n", + bo_fake->id, bo_fake->block, bo_fake->dirty); + + move_to_tail(&bufmgr_fake->referenced, bo_fake->block); + bo_fake->block->referenced = 1; + + bo->offset = bo_fake->block->mem->ofs; + + /* Upload the buffer contents if necessary */ + if (bo_fake->dirty) { + DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", bo_fake->id, + bo_fake->name, bo->size, block->mem->ofs); + + assert(!(bo_fake->flags & + (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); + + /* Actually, should be able to just wait for a fence on the memory, + * which we would be tracking when we free it. Waiting for idle is + * a sufficiently large hammer for now. + */ + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size); + + bo_fake->block->referenced = 0; + bo_fake->block->on_hardware = 1; + move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + } + + bufmgr_fake->need_fence = 1; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + + return 0; +} + +static dri_fence * +dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed) +{ + dri_fence_fake *fence_fake; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + unsigned int cookie; + + fence_fake = malloc(sizeof(*fence_fake)); + if (!fence_fake) + return NULL; + + fence_fake->refcount = 1; + fence_fake->name = name; + fence_fake->flushed = flushed; + fence_fake->fence.bufmgr = bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + cookie = _fence_emit_internal(bufmgr_fake); + fence_fake->fence_cookie = cookie; + fence_blocks(bufmgr_fake, cookie); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + + return &fence_fake->fence; +} + +static void +dri_fake_fence_reference(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + ++fence_fake->refcount; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_fence_unreference(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + if (!fence) + return; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + if (--fence_fake->refcount == 0) { + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + free(fence); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_fence_wait(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + _fence_wait_internal(bufmgr_fake->driver_priv, fence_fake->fence_cookie); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +dri_bufmgr * +dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, + unsigned long size, + unsigned int (*fence_emit)(void *private), + int (*fence_wait)(void *private, unsigned int cookie), + void *driver_priv) +{ + dri_bufmgr_fake *bufmgr_fake; + + bufmgr_fake = malloc(sizeof(*bufmgr_fake)); + + /* Initialize allocator */ + make_empty_list(&bufmgr_fake->referenced); + make_empty_list(&bufmgr_fake->fenced); + make_empty_list(&bufmgr_fake->on_hardware); + + bufmgr_fake->low_offset = low_offset; + bufmgr_fake->virtual = low_virtual; + bufmgr_fake->size = size; + bufmgr_fake->heap = mmInit(low_offset, size); + + _glthread_INIT_MUTEX(bufmgr_fake->mutex); + + /* Hook in methods */ + bufmgr_fake->bufmgr.bo_alloc = dri_fake_alloc; + bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_alloc_static; + bufmgr_fake->bufmgr.bo_reference = dri_fake_bo_reference; + bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference; + bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map; + bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap; + bufmgr_fake->bufmgr.bo_validate = dri_fake_bo_validate; + bufmgr_fake->bufmgr.fence_validated = dri_fake_fence_validated; + bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait; + bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; + bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + + return &bufmgr_fake->bufmgr; +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c new file mode 100644 index 0000000000..edf2a923ce --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -0,0 +1,356 @@ +/************************************************************************** + * + * Copyright © 2007 Intel Corporation + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + * Eric Anholt + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "mtypes.h" +#include "dri_bufmgr.h" +#include "string.h" +#include "imports.h" + +typedef struct _dri_bufmgr_ttm { + dri_bufmgr bufmgr; + + int fd; + _glthread_Mutex mutex; + unsigned int fence_type; + unsigned int fence_type_flush; +} dri_bufmgr_ttm; + +typedef struct _dri_bo_ttm { + dri_bo bo; + + int refcount; /* Protected by bufmgr->mutex */ + drmBO drm_bo; +} dri_bo_ttm; + +typedef struct _dri_fence_ttm +{ + dri_fence fence; + + int refcount; /* Protected by bufmgr->mutex */ + /** Fence type from when the fence was created, used for later waits */ + unsigned int type; + const char *name; + drmFence drm_fence; +} dri_fence_ttm; + +#if 0 +int +driFenceSignaled(DriFenceObject * fence, unsigned type) +{ + int signaled; + int ret; + + if (fence == NULL) + return GL_TRUE; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); + return signaled; +} +#endif + +static dri_bo * +dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, unsigned int flags, + unsigned int hint) +{ + dri_bufmgr_ttm *ttm_bufmgr; + dri_bo_ttm *ttm_buf; + unsigned int pageSize = getpagesize(); + int ret; + + ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; + + ttm_buf = malloc(sizeof(*ttm_buf)); + if (!ttm_buf) + return NULL; + + ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize, + NULL, drm_bo_type_dc, + flags, hint, &ttm_buf->drm_bo); + if (ret != 0) { + free(ttm_buf); + return NULL; + } + ttm_buf->bo.size = ttm_buf->drm_bo.size; + ttm_buf->bo.offset = ttm_buf->drm_bo.offset; + ttm_buf->bo.virtual = NULL; + ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->refcount = 1; + + return &ttm_buf->bo; +} + +static dri_bo * +dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, void *virtual, + unsigned int flags, unsigned int hint) +{ + dri_bufmgr_ttm *ttm_bufmgr; + dri_bo_ttm *ttm_buf; + int ret; + + ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; + + ttm_buf = malloc(sizeof(*ttm_buf)); + if (!ttm_buf) + return NULL; + + ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, + NULL, drm_bo_type_fake, + flags, 0, &ttm_buf->drm_bo); + if (ret != 0) { + free(ttm_buf); + return NULL; + } + ttm_buf->bo.size = ttm_buf->drm_bo.size; + ttm_buf->bo.offset = ttm_buf->drm_bo.offset; + ttm_buf->bo.virtual = virtual; + ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->refcount = 1; + + return &ttm_buf->bo; +} + +static void +dri_ttm_bo_reference(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ttm_buf->refcount++; + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_bo_unreference(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + if (--ttm_buf->refcount == 0) { + drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + free(buf); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static int +dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + unsigned int flags; + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + flags = DRM_BO_FLAG_READ; + if (write_enable) + flags |= DRM_BO_FLAG_WRITE; + + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); +} + +static int +dri_ttm_bo_unmap(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + if (buf == NULL) + return 0; + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + buf->virtual = NULL; + + return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); +} + +static int +dri_ttm_validate(dri_bo *buf, unsigned int flags) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + unsigned int mask; + int err; + + /* XXX: Sanity-check whether we've already validated this one under + * different flags. See drmAddValidateItem(). + */ + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + /* Calculate the appropriate mask to pass to the DRM. There appears to be + * be a direct relationship to flags, so it's unnecessary to have it passed + * in as an argument. + */ + mask = DRM_BO_MASK_MEM; + mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE); + + err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, mask, 0); + + if (err == 0) { + /* XXX: add to fence list for sanity checking */ + } + + return err; +} + +static dri_fence * +dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed) +{ + dri_fence_ttm *fence_ttm = malloc(sizeof(*fence_ttm)); + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + int ret; + unsigned int type; + + if (!fence_ttm) + return NULL; + + if (flushed) + type = bufmgr_ttm->fence_type_flush; + else + type = bufmgr_ttm->fence_type; + + fence_ttm->refcount = 1; + fence_ttm->name = name; + fence_ttm->type = type; + fence_ttm->fence.bufmgr = bufmgr; + ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); + if (ret) { + free(fence_ttm); + return NULL; + } + return &fence_ttm->fence; +} + +static void +dri_ttm_fence_reference(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ++fence_ttm->refcount; + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_fence_unreference(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + + if (!fence) + return; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + if (--fence_ttm->refcount == 0) { + drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + free(fence); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_fence_wait(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + int ret; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, + fence_ttm->type); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + if (ret != 0) { + _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", + __FILE__, __LINE__, fence_ttm->name); + abort(); + } +} + +/** + * Initializes the TTM buffer manager, which uses the kernel to allocate, map, + * and manage map buffer objections. + * + * \param fd File descriptor of the opened DRM device. + * \param fence_type Driver-specific fence type used for fences with no flush. + * \param fence_type_flush Driver-specific fence type used for fences with a + * flush. + */ +dri_bufmgr * +dri_bufmgr_ttm_init(int fd, unsigned int fence_type, + unsigned int fence_type_flush) +{ + dri_bufmgr_ttm *bufmgr_ttm; + + bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); + bufmgr_ttm->fd = fd; + bufmgr_ttm->fence_type = fence_type; + bufmgr_ttm->fence_type_flush = fence_type_flush; + _glthread_INIT_MUTEX(bufmgr_ttm->mutex); + + bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc; + bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static; + bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference; + bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference; + bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map; + bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap; + bufmgr_ttm->bufmgr.bo_validate = dri_ttm_validate; + bufmgr_ttm->bufmgr.fence_validated = dri_ttm_fence_validated; + bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference; + bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; + bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + + return &bufmgr_ttm->bufmgr; +} diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h deleted file mode 100644 index c6fb2c3ce0..0000000000 --- a/src/mesa/drivers/dri/common/dri_bufpool.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#ifndef _DRI_BUFPOOL_H_ -#define _DRI_BUFPOOL_H_ - -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - unsigned flags, unsigned hint, unsigned alignment); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private); - void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset, - unsigned long size, void *virtual, unsigned flags); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, - int lazy); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - - - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driDRMStaticPoolInit(int fd); - -#endif diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c deleted file mode 100644 index b5b324be50..0000000000 --- a/src/mesa/drivers/dri/common/dri_drmpool.c +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "dri_bufpool.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - return NULL; - } - - ret = drmBOCreate(pool->fd, 0, size, alignment / pageSize, - NULL, drm_bo_type_dc, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - ret = drmBODestroy(pool->fd, buf); - free(buf); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - drmBO *buf = (drmBO *) private; - - return drmBOMap(pool->fd, buf, flags, hint, virtual); -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return drmBOUnmap(pool->fd, buf); -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->offset; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - drmBO *buf = (drmBO *) private; - return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->setstatic = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->data = NULL; - return pool; -} - - -static void * -pool_setstatic(struct _DriBufferPool *pool, unsigned long offset, - unsigned long size, void *virtual, unsigned flags) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOCreate(pool->fd, offset, size, 0, NULL, drm_bo_type_fake, - flags, 0, buf); - - if (ret) { - free(buf); - return NULL; - } - - buf->virtual = virtual; - - return (void *) buf; -} - - -struct _DriBufferPool * -driDRMStaticPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = NULL; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->setstatic = &pool_setstatic; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->data = NULL; - return pool; -} -- cgit v1.2.3 From cfc21190af1038f204d38ab4764a9c731b0323a5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:28:01 -0700 Subject: Convert i915tex to the new interface and make it compile. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 + src/mesa/drivers/dri/common/dri_bufmgr.h | 12 +- src/mesa/drivers/dri/i915tex/Makefile | 3 +- src/mesa/drivers/dri/i915tex/i830_context.h | 6 +- src/mesa/drivers/dri/i915tex/i830_metaops.c | 2 +- src/mesa/drivers/dri/i915tex/i830_texstate.c | 7 +- src/mesa/drivers/dri/i915tex/i830_vtbl.c | 3 - src/mesa/drivers/dri/i915tex/i915_context.h | 6 +- src/mesa/drivers/dri/i915tex/i915_metaops.c | 2 +- src/mesa/drivers/dri/i915tex/i915_texstate.c | 8 +- src/mesa/drivers/dri/i915tex/i915_vtbl.c | 3 - src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 178 +++------ src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 21 +- src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 --------------------- src/mesa/drivers/dri/i915tex/intel_blit.c | 35 +- src/mesa/drivers/dri/i915tex/intel_blit.h | 6 +- .../drivers/dri/i915tex/intel_buffer_objects.c | 68 ++-- .../drivers/dri/i915tex/intel_buffer_objects.h | 8 +- src/mesa/drivers/dri/i915tex/intel_context.c | 18 +- src/mesa/drivers/dri/i915tex/intel_context.h | 18 +- src/mesa/drivers/dri/i915tex/intel_ioctl.c | 19 +- src/mesa/drivers/dri/i915tex/intel_ioctl.h | 4 +- src/mesa/drivers/dri/i915tex/intel_pixel_draw.c | 14 +- src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 18 +- src/mesa/drivers/dri/i915tex/intel_regions.c | 86 +++-- src/mesa/drivers/dri/i915tex/intel_regions.h | 8 +- src/mesa/drivers/dri/i915tex/intel_screen.c | 112 +++--- src/mesa/drivers/dri/i915tex/intel_screen.h | 19 +- src/mesa/drivers/dri/i915tex/intel_tex_image.c | 9 +- src/mesa/drivers/dri/i965/intel_context.c | 6 +- 30 files changed, 320 insertions(+), 803 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index fc2d4a0665..f60d3b0db6 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -85,6 +85,12 @@ dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed) return bufmgr->fence_validated(bufmgr, name, flushed); } +void +dri_fence_wait(dri_fence *fence) +{ + fence->bufmgr->fence_wait(fence); +} + void dri_fence_reference(dri_fence *fence) { diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index eafee88b88..62ed9d3821 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -164,17 +164,6 @@ struct _dri_bufmgr { */ }; -/* -extern void driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, unsigned flags); -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -*/ - dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, unsigned int alignment, unsigned int flags, unsigned int hint); @@ -189,6 +178,7 @@ int dri_bo_unmap(dri_bo *buf); int dri_bo_validate(dri_bo *buf, unsigned int flags); dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed); +void dri_fence_wait(dri_fence *fence); void dri_fence_reference(dri_fence *fence); void dri_fence_unreference(dri_fence *fence); diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index b218929dce..27fb29e9c2 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -50,8 +50,7 @@ DRIVER_SOURCES = \ intel_state.c \ intel_tris.c \ intel_fbo.c \ - intel_depthstencil.c \ - intel_batchpool.c + intel_depthstencil.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h index 3d754103c0..9397fa45b5 100644 --- a/src/mesa/drivers/dri/i915tex/i830_context.h +++ b/src/mesa/drivers/dri/i915tex/i830_context.h @@ -114,10 +114,10 @@ struct i830_hw_state struct intel_region *depth_region; /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Just use the buffer id. Will have to do - * this for draw and depth for FBO's... + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... */ - struct _DriBufferObject *tex_buffer[I830_TEX_UNITS]; + dri_bo *tex_buffer[I830_TEX_UNITS]; GLuint tex_offset[I830_TEX_UNITS]; GLuint emitted; /* I810_UPLOAD_* */ diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c index f76646d89d..13e4ab3aac 100644 --- a/src/mesa/drivers/dri/i915tex/i830_metaops.c +++ b/src/mesa/drivers/dri/i915tex/i830_metaops.c @@ -238,7 +238,7 @@ set_texture_blend_replace(struct intel_context *intel) */ static GLboolean set_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, + dri_bo *buffer, GLuint offset, GLuint pitch, GLuint height, GLenum format, GLenum type) { diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c index e3f34e3944..b25ec199f8 100644 --- a/src/mesa/drivers/dri/i915tex/i830_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c @@ -124,7 +124,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /*We need to refcount these. */ if (i830->state.tex_buffer[unit] != NULL) { - driBOUnReference(i830->state.tex_buffer[unit]); + dri_bo_unreference(i830->state.tex_buffer[unit]); i830->state.tex_buffer[unit] = NULL; } @@ -136,7 +136,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - i830->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + dri_bo_reference(intelObj->mt->region->buffer); + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, intelObj-> firstLevel); @@ -303,7 +304,7 @@ i830UpdateTextureState(struct intel_context *intel) I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); if (i830->state.tex_buffer[i] != NULL) { - driBOUnReference(i830->state.tex_buffer[i]); + dri_bo_unreference(i830->state.tex_buffer[i]); i830->state.tex_buffer[i] = NULL; } break; diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index dd0670dec3..441dc660ac 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -451,7 +451,6 @@ i830_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->draw_region->draw_offset); if (state->depth_region) { @@ -459,7 +458,6 @@ i830_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->depth_region->draw_offset); } @@ -487,7 +485,6 @@ i830_emit_state(struct intel_context *intel) if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, state->tex_offset[i] | TM0S0_USE_FENCE); } else { diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index d2713e88f9..7915385dca 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -219,10 +219,10 @@ struct i915_hw_state /* struct intel_region *tex_region[I915_TEX_UNITS]; */ /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Just use the buffer id. Will have to do - * this for draw and depth for FBO's... + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... */ - struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; + dri_bo *tex_buffer[I915_TEX_UNITS]; GLuint tex_offset[I915_TEX_UNITS]; diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c index 3ab62bc806..128f86e21b 100644 --- a/src/mesa/drivers/dri/i915tex/i915_metaops.c +++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c @@ -326,7 +326,7 @@ meta_texture_blend_replace(struct intel_context *intel) */ static GLboolean meta_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, + dri_bo *buffer, GLuint offset, GLuint pitch, GLuint height, GLenum format, GLenum type) { diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c index e0ecdfde24..31d18759ee 100644 --- a/src/mesa/drivers/dri/i915tex/i915_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c @@ -129,7 +129,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /*We need to refcount these. */ if (i915->state.tex_buffer[unit] != NULL) { - driBOUnReference(i915->state.tex_buffer[unit]); + dri_bo_unreference(i915->state.tex_buffer[unit]); i915->state.tex_buffer[unit] = NULL; } @@ -141,7 +141,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + dri_bo_reference(intelObj->mt->region->buffer); + i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, intelObj-> firstLevel); @@ -322,7 +324,7 @@ i915UpdateTextureState(struct intel_context *intel) I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); if (i915->state.tex_buffer[i] != NULL) { - driBOUnReference(i915->state.tex_buffer[i]); + dri_bo_unreference(i915->state.tex_buffer[i]); i915->state.tex_buffer[i] = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 52db9a95e6..50571b7e83 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -326,7 +326,6 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->draw_region->draw_offset); if (state->depth_region) { @@ -334,7 +333,6 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->depth_region->draw_offset); } @@ -378,7 +376,6 @@ i915_emit_state(struct intel_context *intel) if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, state->tex_offset[i]); } else { diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index c92b83bcb3..55e40d5d97 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -77,49 +77,6 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) fprintf(stderr, "END BATCH\n\n\n"); } -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - - int i; - - /* - * Get a new, free batchbuffer. - */ - - batch->size = batch->intel->intelScreen->maxBatchSize; - driBOData(batch->buffer, batch->size, NULL, 0); - - driBOResetList(&batch->list); - - /* - * Unreference buffers previously on the relocation list. - */ - - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOUnReference(r->buf); - } - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* - * We don't refcount the batchbuffer itself since we can't destroy it - * while it's on the list. - */ - - - driBOAddListItem(&batch->list, batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); - - - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->ptr = batch->map; -} - /*====================================================================== * Public functions */ @@ -129,12 +86,16 @@ intel_batchbuffer_alloc(struct intel_context *intel) struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); batch->intel = intel; + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_EXE, 0); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; - driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); batch->last_fence = NULL; - driBOCreateList(20, &batch->list); intel_batchbuffer_reset(batch); return batch; } @@ -143,17 +104,16 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch) { if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); - driFenceUnReference(batch->last_fence); + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); batch->last_fence = NULL; } if (batch->map) { - driBOUnmap(batch->buffer); + dri_bo_unmap(batch->buf); batch->map = NULL; } - driBOUnReference(batch->buffer); - batch->buffer = NULL; + dri_bo_unreference(batch->buf); + batch->buf = NULL; free(batch); } @@ -167,30 +127,35 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint *ptr; GLuint i; struct intel_context *intel = batch->intel; - unsigned fenceFlags; - struct _DriFenceObject *fo; - - driBOValidateList(batch->intel->driFd, &batch->list); - - /* Apply the relocations. This nasty map indicates to me that the - * whole task should be done internally by the memory manager, and - * that dma buffers probably need to be pinned within agp space. - */ - ptr = (GLuint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_ALLOW_UNFENCED_MAP); + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; for (i = 0; i < batch->nr_relocs; i++) { struct buffer_reloc *r = &batch->reloc[i]; - ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + dri_bo_validate(r->buf, r->validate_flags); + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); } if (INTEL_DEBUG & DEBUG_BATCH) intel_dump_batchbuffer(0, ptr, used); - driBOUnmap(batch->buffer); + dri_bo_unmap(batch->buf); batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; /* Throw away non-effective packets. Won't work once we have * hardware contexts which would preserve statechanges beyond a @@ -199,45 +164,32 @@ do_flush_locked(struct intel_batchbuffer *batch, if (!(intel->numClipRects == 0 && !ignore_cliprects)) { intel_batch_ioctl(batch->intel, - driBOOffset(batch->buffer), + batch->buf->offset, used, ignore_cliprects, allow_unlock); } - - /* - * Kernel fencing. The flags tells the kernel that we've - * programmed an MI_FLUSH. - */ - - fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; - fo = driFenceBuffers(batch->intel->driFd, - "Batch fence", fenceFlags); - - /* - * User space fencing. + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); - driBOFence(batch->buffer, fo); - - if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { - - /* - * Oops. We only validated a batch buffer. This means we - * didn't do any proper rendering. Discard this fence object. - */ - - driFenceUnReference(fo); - } else { - driFenceUnReference(batch->last_fence); + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); batch->last_fence = fo; - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOFence(r->buf, fo); - } + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); } if (intel->numClipRects == 0 && !ignore_cliprects) { if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ UNLOCK_HARDWARE(intel); sched_yield(); LOCK_HARDWARE(intel); @@ -247,7 +199,7 @@ do_flush_locked(struct intel_batchbuffer *batch, } -struct _DriFenceObject * +void intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; @@ -255,7 +207,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) GLboolean was_locked = intel->locked; if (used == 0) - return batch->last_fence; + return; /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. @@ -272,10 +224,6 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) used += 8; } - driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; - /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ @@ -291,16 +239,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* Reset the buffer: */ intel_batchbuffer_reset(batch); - return batch->last_fence; } void intel_batchbuffer_finish(struct intel_batchbuffer *batch) { - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceReference(fence); - driFenceFinish(fence, 3, GL_FALSE); - driFenceUnReference(fence); + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); } @@ -308,20 +254,18 @@ intel_batchbuffer_finish(struct intel_batchbuffer *batch) */ GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - GLuint flags, GLuint mask, GLuint delta) + dri_bo *buffer, + GLuint flags, GLuint delta) { - assert(batch->nr_relocs < MAX_RELOCS); + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOAddListItem(&batch->list, buffer, flags, mask); + assert(batch->nr_relocs <= MAX_RELOCS); - { - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOReference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - } + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; batch->ptr += 4; return GL_TRUE; diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index 59261f7274..302a605d3c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -16,9 +16,10 @@ struct intel_context; struct buffer_reloc { - struct _DriBufferObject *buf; + dri_bo *buf; GLuint offset; GLuint delta; /* not needed? */ + GLuint validate_flags; }; struct intel_batchbuffer @@ -26,8 +27,8 @@ struct intel_batchbuffer struct bufmgr *bm; struct intel_context *intel; - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; + dri_bo *buf; + dri_fence *last_fence; GLuint flags; drmBOList list; @@ -48,8 +49,7 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch); void intel_batchbuffer_finish(struct intel_batchbuffer *batch); -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); void intel_batchbuffer_reset(struct intel_batchbuffer *batch); @@ -65,9 +65,8 @@ void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, GLuint bytes); GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - GLuint flags, - GLuint mask, GLuint offset); + dri_bo *buffer, + GLuint flags, GLuint offset); /* Inline functions - might actually be better off with these * non-inlined. Certainly better off switching all command packets to @@ -113,9 +112,9 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ } while (0) #define ADVANCE_BATCH() do { } while(0) diff --git a/src/mesa/drivers/dri/i915tex/intel_batchpool.c b/src/mesa/drivers/dri/i915tex/intel_batchpool.c deleted file mode 100644 index 3c17c50204..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_batchpool.c +++ /dev/null @@ -1,418 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "dri_bufpool.h" -#include "dri_bufmgr.h" -#include "intel_screen.h" - -typedef struct -{ - drmMMListHead head; - struct _BPool *parent; - struct _DriFenceObject *fence; - unsigned long start; - int unfenced; - int mapped; -} BBuf; - -typedef struct _BPool -{ - _glthread_Mutex mutex; - unsigned long bufSize; - unsigned poolSize; - unsigned numFree; - unsigned numTot; - unsigned numDelayed; - unsigned checkDelayed; - drmMMListHead free; - drmMMListHead delayed; - drmMMListHead head; - drmBO kernelBO; - void *virtual; - BBuf *bufs; -} BPool; - - -static BPool * -createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, - unsigned checkDelayed) -{ - BPool *p = (BPool *) malloc(sizeof(*p)); - BBuf *buf; - int i; - - if (!p) - return NULL; - - p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); - if (!p->bufs) { - free(p); - return NULL; - } - - DRMINITLISTHEAD(&p->free); - DRMINITLISTHEAD(&p->head); - DRMINITLISTHEAD(&p->delayed); - - p->numTot = numBufs; - p->numFree = numBufs; - p->bufSize = bufSize; - p->numDelayed = 0; - p->checkDelayed = checkDelayed; - - _glthread_INIT_MUTEX(p->mutex); - - if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, - flags, 0, &p->kernelBO)) { - free(p->bufs); - free(p); - return NULL; - } - if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - &p->virtual)) { - drmBODestroy(fd, &p->kernelBO); - free(p->bufs); - free(p); - return NULL; - } - - /* - * We unmap the buffer so that we can validate it later. Note that this is - * just a synchronizing operation. The buffer will have a virtual mapping - * until it is destroyed. - */ - - drmBOUnmap(fd, &p->kernelBO); - - buf = p->bufs; - for (i = 0; i < numBufs; ++i) { - buf->parent = p; - buf->fence = NULL; - buf->start = i * bufSize; - buf->mapped = 0; - buf->unfenced = 0; - DRMLISTADDTAIL(&buf->head, &p->free); - buf++; - } - - return p; -} - - -static void -pool_checkFree(BPool * p, int wait) -{ - drmMMListHead *list, *prev; - BBuf *buf; - int signaled = 0; - int i; - - list = p->delayed.next; - - if (p->numDelayed > 3) { - for (i = 0; i < p->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &p->delayed; list = prev, prev = list->prev) { - - buf = DRMLISTENTRY(BBuf, list, head); - - if (!signaled) { - if (wait) { - driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); - signaled = 1; - } - else { - signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); - } - } - - if (!signaled) - break; - - driFenceUnReference(buf->fence); - buf->fence = NULL; - DRMLISTDEL(list); - p->numDelayed--; - DRMLISTADD(list, &p->free); - p->numFree++; - } -} - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - BPool *p = (BPool *) pool->data; - - drmMMListHead *item; - - if (alignment && (alignment != 4096)) - return NULL; - - _glthread_LOCK_MUTEX(p->mutex); - - if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); - - if (p->numFree == 0) { - fprintf(stderr, "Out of fixed size buffer objects\n"); - BM_CKFATAL(-ENOMEM); - } - - item = p->free.next; - - if (item == &p->free) { - fprintf(stderr, "Fixed size buffer pool corruption\n"); - } - - DRMLISTDEL(item); - --p->numFree; - - _glthread_UNLOCK_MUTEX(p->mutex); - return (void *) DRMLISTENTRY(BBuf, item, head); -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - if (buf->fence) { - DRMLISTADDTAIL(&buf->head, &p->delayed); - p->numDelayed++; - } - else { - buf->unfenced = 0; - DRMLISTADD(&buf->head, &p->free); - p->numFree++; - } - - if ((p->numDelayed % p->checkDelayed) == 0) - pool_checkFree(p, 0); - - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - /* - * Currently Mesa doesn't have any condition variables to resolve this - * cleanly in a multithreading environment. - * We bail out instead. - */ - - if (buf->mapped) { - fprintf(stderr, "Trying to map already mapped buffer object\n"); - BM_CKFATAL(-EINVAL); - } - -#if 0 - if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" - " 0x%08x %d\n", hint, flags, buf->start); - BM_CKFATAL(-EINVAL); - } - -#endif - - if (buf->fence) { - _glthread_UNLOCK_MUTEX(p->mutex); - return -EBUSY; - } - - buf->mapped = GL_TRUE; - *virtual = (unsigned char *) p->virtual + buf->start; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - BBuf *buf = (BBuf *) private; - driFenceFinish(buf->fence, 0, lazy); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - - buf->mapped = 0; - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return p->kernelBO.offset + buf->start; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->kernelBO.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->bufSize; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - if (buf->fence) { - driFenceUnReference(buf->fence); - } - buf->fence = fence; - buf->unfenced = 0; - driFenceReference(buf->fence); - _glthread_UNLOCK_MUTEX(p->mutex); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return &p->kernelBO; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - BPool *p = (BPool *) pool->data; - - /* - * Wait on outstanding fences. - */ - - _glthread_LOCK_MUTEX(p->mutex); - while ((p->numFree < p->numTot) && p->numDelayed) { - _glthread_UNLOCK_MUTEX(p->mutex); - sched_yield(); - pool_checkFree(p, GL_TRUE); - _glthread_LOCK_MUTEX(p->mutex); - } - - drmBODestroy(pool->fd, &p->kernelBO); - free(p->bufs); - _glthread_UNLOCK_MUTEX(p->mutex); - free(p); - free(pool); -} - - -struct _DriBufferPool * -driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, unsigned checkDelayed) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); - if (!pool->data) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = &pool_validate; - pool->waitIdle = &pool_waitIdle; - pool->setstatic = NULL; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index dbe4ba2ac5..ef596bdfc5 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -67,8 +67,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, intelScreen = intel->intelScreen; if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); intel->last_swap_fence = NULL; } intel->last_swap_fence = intel->first_swap_fence; @@ -140,19 +140,20 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, OUT_BATCH((pbox->y2 << 16) | pbox->x2); OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + 0); OUT_BATCH((pbox->y1 << 16) | pbox->x1); OUT_BATCH(BR13 & 0xffff); OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + 0); ADVANCE_BATCH(); } if (intel->first_swap_fence) - driFenceUnReference(intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(intel->first_swap_fence); + dri_fence_unreference(intel->first_swap_fence); + intel_batchbuffer_flush(intel->batch); + dri_fence_reference(intel->first_swap_fence); + intel->first_swap_fence = intel->batch->last_fence; } UNLOCK_HARDWARE(intel); @@ -165,7 +166,7 @@ void intelEmitFillBlit(struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) { @@ -199,8 +200,7 @@ intelEmitFillBlit(struct intel_context *intel, OUT_BATCH(BR13); OUT_BATCH((y << 16) | x); OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); OUT_BATCH(color); ADVANCE_BATCH(); } @@ -236,10 +236,10 @@ void intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct _DriBufferObject *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort src_x, GLshort src_y, GLshort dst_x, GLshort dst_y, @@ -297,12 +297,10 @@ intelEmitCopyBlit(struct intel_context *intel, OUT_BATCH(BR13); OUT_BATCH((dst_y << 16) | dst_x); OUT_BATCH((dst_y2 << 16) | dst_x2); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); OUT_BATCH((src_y << 16) | src_x); OUT_BATCH(((GLint) src_pitch & 0xffff)); - OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, src_offset); ADVANCE_BATCH(); } else { @@ -312,12 +310,10 @@ intelEmitCopyBlit(struct intel_context *intel, OUT_BATCH((0 << 16) | dst_x); OUT_BATCH((h << 16) | dst_x2); OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset + dst_y * dst_pitch); OUT_BATCH((0 << 16) | src_x); OUT_BATCH(((GLint) src_pitch & 0xffff)); OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset + src_y * src_pitch); ADVANCE_BATCH(); } @@ -420,7 +416,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) /* OK, clear this renderbuffer */ struct intel_region *irb_region = intel_get_rb_region(fb, buf); - struct _DriBufferObject *write_buffer = + dri_bo *write_buffer = intel_region_buffer(intel->intelScreen, irb_region, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); @@ -483,7 +479,6 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) OUT_BATCH((b.y1 << 16) | b.x1); OUT_BATCH((b.y2 << 16) | b.x2); OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, irb_region->draw_offset); OUT_BATCH(clearVal); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h index e7bc280f58..a66af86359 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.h +++ b/src/mesa/drivers/dri/i915tex/intel_blit.h @@ -40,10 +40,10 @@ extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); extern void intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct _DriBufferObject *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort srcx, GLshort srcy, GLshort dstx, GLshort dsty, @@ -53,7 +53,7 @@ extern void intelEmitCopyBlit(struct intel_context *intel, extern void intelEmitFillBlit(struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color); diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index ba3c7f0c1f..6d72ea3fa2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -35,6 +35,17 @@ #include "intel_regions.h" #include "dri_bufmgr.h" +/** Allocates a new dri_bo to store the data for the buffer object. */ +static void +intel_bufferobj_alloc_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", + intel_obj->Base.Size, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); +} + /** * There is some duplication between mesa's bufferobjects and our * bufmgr buffers. Both have an integer handle and a hashtable to @@ -44,21 +55,15 @@ static struct gl_buffer_object * intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) { - struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); _mesa_initialize_buffer_object(&obj->Base, name, target); - driGenBuffers(intel->intelScreen->regionPool, - "bufferobj", 1, &obj->buffer, 64, - DRM_BO_FLAG_MEM_LOCAL | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0); + obj->buffer = NULL; return &obj->Base; } - /* Break the COW tie to the region. The region gets to keep the data. */ void @@ -68,15 +73,9 @@ intel_bufferobj_release_region(struct intel_context *intel, assert(intel_obj->region->buffer == intel_obj->buffer); intel_obj->region->pbo = NULL; intel_obj->region = NULL; - driBOUnReference(intel_obj->buffer); - intel_obj->buffer = NULL; - /* This leads to a large number of buffer deletion/creation events. - * Currently the drm doesn't like that: - */ - driGenBuffers(intel->intelScreen->regionPool, - "buffer object", 1, &intel_obj->buffer, 64, 0, 0); - driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0); + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; } /* Break the COW tie to the region. Both the pbo and the region end @@ -107,7 +106,7 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) intel_bufferobj_release_region(intel, intel_obj); } else if (intel_obj->buffer) { - driDeleteBuffers(1, &intel_obj->buffer); + dri_bo_unreference(intel_obj->buffer); } _mesa_free(intel_obj); @@ -137,7 +136,15 @@ intel_bufferobj_data(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_release_region(intel, intel_obj); - driBOData(intel_obj->buffer, size, data, 0); + if (intel_obj->buffer != NULL && intel_obj->buffer->size != size) { + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } + + intel_bufferobj_alloc_buffer(intel, intel_obj); + + if (data != NULL) + dri_bo_subdata(intel_obj->buffer, 0, size, data); } @@ -162,7 +169,7 @@ intel_bufferobj_subdata(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - driBOSubData(intel_obj->buffer, offset, size, data); + dri_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -179,7 +186,7 @@ intel_bufferobj_get_subdata(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - driBOGetSubData(intel_obj->buffer, offset, size, data); + dri_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -202,8 +209,13 @@ intel_bufferobj_map(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - obj->Pointer = driBOMap(intel_obj->buffer, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + if (intel_obj->buffer == NULL) { + obj->Pointer = NULL; + return NULL; + } + + dri_bo_map(intel_obj->buffer, GL_TRUE); + obj->Pointer = intel_obj->buffer->virtual; return obj->Pointer; } @@ -218,21 +230,25 @@ intel_bufferobj_unmap(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - assert(obj->Pointer); - driBOUnmap(intel_obj->buffer); - obj->Pointer = NULL; + if (intel_obj->buffer != NULL) { + assert(obj->Pointer); + dri_bo_unmap(intel_obj->buffer); + obj->Pointer = NULL; + } return GL_TRUE; } -struct _DriBufferObject * +dri_bo * intel_bufferobj_buffer(struct intel_context *intel, struct intel_buffer_object *intel_obj, GLuint flag) { if (intel_obj->region) { if (flag == INTEL_WRITE_PART) intel_bufferobj_cow(intel, intel_obj); - else if (flag == INTEL_WRITE_FULL) + else if (flag == INTEL_WRITE_FULL) { intel_bufferobj_release_region(intel, intel_obj); + intel_bufferobj_alloc_buffer(intel, intel_obj); + } } return intel_obj->buffer; diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h index afe9b2f7cf..db579a8ae4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h @@ -41,7 +41,7 @@ struct gl_buffer_object; struct intel_buffer_object { struct gl_buffer_object Base; - struct _DriBufferObject *buffer; /* the low-level buffer manager's buffer handle */ + dri_bo *buffer; /* the low-level buffer manager's buffer handle */ struct intel_region *region; /* Is there a zero-copy texture associated with this (pixel) @@ -51,9 +51,9 @@ struct intel_buffer_object /* Get the bm buffer associated with a GL bufferobject: */ -struct _DriBufferObject *intel_bufferobj_buffer(struct intel_context *intel, - struct intel_buffer_object - *obj, GLuint flag); +dri_bo *intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object + *obj, GLuint flag); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 6a3456e154..7db672cce3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -303,9 +303,8 @@ intelFinish(GLcontext * ctx) struct intel_context *intel = intel_context(ctx); intelFlush(ctx); if (intel->batch->last_fence) { - driFenceFinish(intel->batch->last_fence, - 0, GL_FALSE); - driFenceUnReference(intel->batch->last_fence); + dri_fence_wait(intel->batch->last_fence); + dri_fence_unreference(intel->batch->last_fence); intel->batch->last_fence = NULL; } intelCheckFrontRotate(ctx); @@ -441,7 +440,6 @@ intelInitContext(struct intel_context *intel, intel->RenderIndex = ~0; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; intel->irqsEmitted = 0; intel->do_irqs = (intel->intelScreen->irq_active && @@ -514,13 +512,13 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel_batchbuffer_free(intel->batch); if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); intel->last_swap_fence = NULL; } if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->first_swap_fence); + dri_fence_wait(intel->first_swap_fence); + dri_fence_unreference(intel->first_swap_fence); intel->first_swap_fence = NULL; } @@ -664,14 +662,14 @@ intelContendedLock(struct intel_context *intel, GLuint flags) */ if (batchMap != NULL) { - driBOUnmap(intel->batch->buffer); + dri_bo_unmap(intel->batch->buf); intel->batch->map = NULL; } intel_batchbuffer_reset(intel->batch); if (batchMap == NULL) { - driBOUnmap(intel->batch->buffer); + dri_bo_unmap(intel->batch->buf); intel->batch->map = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 44c20af7f8..429f53cb51 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -50,7 +50,6 @@ struct intel_region; struct intel_context; -struct _DriBufferObject; typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, intelVertex *, intelVertex *); @@ -164,12 +163,12 @@ struct intel_context void (*meta_import_pixel_state) (struct intel_context * intel); - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - struct _DriBufferObject * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); + GLboolean(*meta_tex_rect_source) (struct intel_context * intel, + dri_bo * buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, GLenum type); void (*rotate_window) (struct intel_context * intel, __DRIdrawablePrivate * dPriv, GLuint srcBuf); @@ -181,8 +180,8 @@ struct intel_context GLuint Fallback; GLuint NewGLState; - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; + dri_fence *last_swap_fence; + dri_fence *first_swap_fence; struct intel_batchbuffer *batch; @@ -256,7 +255,6 @@ struct intel_context GLuint do_usleeps; int do_irqs; GLuint irqsEmitted; - drm_i915_irq_wait_t iw; drm_context_t hHWContext; drmLock *driHwLock; diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c index 3250c6b3a9..6e76737c78 100644 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c @@ -45,18 +45,15 @@ #define FILE_DEBUG_FLAG DEBUG_IOCTL int -intelEmitIrqLocked(struct intel_context *intel) +intelEmitIrqLocked(intelScreenPrivate *intelScreen) { drmI830IrqEmit ie; int ret, seq; - assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD | intel->hHWContext)); - ie.irq_seq = &seq; - ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, - &ie, sizeof(ie)); + ret = drmCommandWriteRead(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); if (ret) { fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); exit(1); @@ -68,18 +65,18 @@ intelEmitIrqLocked(struct intel_context *intel) } void -intelWaitIrq(struct intel_context *intel, int seq) +intelWaitIrq(intelScreenPrivate *intelScreen, int seq) { + drm_i915_irq_wait_t iw; int ret; DBG("%s %d\n", __FUNCTION__, seq); - intel->iw.irq_seq = seq; + iw.irq_seq = seq; do { - ret = - drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, - sizeof(intel->iw)); + ret = drmCommandWrite(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); } while (ret == -EAGAIN || ret == -EINTR); if (ret) { diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h b/src/mesa/drivers/dri/i915tex/intel_ioctl.h index e8d07de893..7a5b175ed1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.h @@ -30,8 +30,8 @@ #include "intel_context.h" -void intelWaitIrq(struct intel_context *intel, int seq); -int intelEmitIrqLocked(struct intel_context *intel); +void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); +int intelEmitIrqLocked(intelScreenPrivate *intelScreen); void intel_batch_ioctl(struct intel_context *intel, GLuint start_offset, diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c index 10a079896a..cbb583d3a2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -217,7 +217,7 @@ do_blit_drawpixels(GLcontext * ctx, struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); GLuint src_offset; GLuint rowLength; - struct _DriFenceObject *fence = NULL; + dri_fence *fence = NULL; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -298,8 +298,7 @@ do_blit_drawpixels(GLcontext * ctx, drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t rect; drm_clip_rect_t dest_rect; - struct _DriBufferObject *src_buffer = - intel_bufferobj_buffer(intel, src, INTEL_READ); + dri_bo *src_buffer = intel_bufferobj_buffer(intel, src, INTEL_READ); int i; dest_rect.x1 = dPriv->x + x; @@ -324,14 +323,15 @@ do_blit_drawpixels(GLcontext * ctx, ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY); } - fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(fence); + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); } UNLOCK_HARDWARE(intel); if (fence) { - driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); - driFenceUnReference(fence); + dri_fence_wait(fence); + dri_fence_unreference(fence); } if (INTEL_DEBUG & DEBUG_PIXEL) diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c index 24e49ae066..a22844926c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -173,7 +173,7 @@ do_blit_readpixels(GLcontext * ctx, struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; - struct _DriFenceObject *fence = NULL; + dri_fence *fence = NULL; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -241,9 +241,9 @@ do_blit_readpixels(GLcontext * ctx, GLboolean all = (width * height * src->cpp == dst->Base.Size && x == 0 && dst_offset == 0); - struct _DriBufferObject *dst_buffer = - intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); + dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; drm_clip_rect_t *box = dPriv->pClipRects; @@ -275,16 +275,16 @@ do_blit_readpixels(GLcontext * ctx, GL_COPY); } - fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(fence); + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); } UNLOCK_HARDWARE(intel); if (fence) { - driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(fence); + dri_fence_wait(fence); + dri_fence_unreference(fence); } if (INTEL_DEBUG & DEBUG_PIXEL) diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index a114bdf896..9c005c0e5d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -52,8 +52,17 @@ void intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) { DBG("%s\n", __FUNCTION__); - if (region && region->buffer) - driBOWaitIdle(region->buffer, GL_FALSE); + /* XXX: Using this function is likely bogus -- it ought to only have been + * used before a map, anyway, but leave this cheap implementation of it + * for now. + */ + if (region && region->buffer) { + /* Mapping it for read will ensure that any acceleration to the region + * would have landed already. + */ + dri_bo_map(region->buffer, GL_TRUE); + dri_bo_unmap(region->buffer); + } } /* XXX: Thread safety? @@ -66,8 +75,8 @@ intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) if (region->pbo) intel_region_cow(intelScreen, region); - region->map = driBOMap(region->buffer, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + dri_bo_map(region->buffer, GL_TRUE); + region->map = region->buffer->virtual; } return region->map; @@ -78,13 +87,11 @@ intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - driBOUnmap(region->buffer); + dri_bo_unmap(region->buffer); region->map = NULL; } } -#undef TEST_CACHED_TEXTURES - struct intel_region * intel_region_alloc(intelScreenPrivate *intelScreen, GLuint cpp, GLuint pitch, GLuint height) @@ -98,16 +105,8 @@ intel_region_alloc(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - driGenBuffers(intelScreen->regionPool, - "region", 1, ®ion->buffer, 64, -#ifdef TEST_CACHED_TEXTURES - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_BIND_CACHED | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, -#else - 0, -#endif - 0); - driBOData(region->buffer, pitch * cpp * height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + pitch * cpp * height, 64, 0, 0); return region; } @@ -138,7 +137,7 @@ intel_region_release(struct intel_region **region) if ((*region)->pbo) (*region)->pbo->region = NULL; (*region)->pbo = NULL; - driBOUnReference((*region)->buffer); + dri_bo_unreference((*region)->buffer); free(*region); } *region = NULL; @@ -160,16 +159,13 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - /* - * We use a "shared" buffer type to indicate buffers created and - * shared by others. - */ - - driGenBuffers(intelScreen->staticPool, "static region", 1, - ®ion->buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + /* XXX: questionable flags */ + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", + offset, pitch * cpp * height, virtual, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE, 0); return region; } @@ -195,13 +191,14 @@ intel_region_update_static(intelScreenPrivate *intelScreen, * shared by others. */ - driDeleteBuffers(1, ®ion->buffer); - driGenBuffers(intelScreen->staticPool, "static region", 1, - ®ion->buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); - + dri_bo_unreference(region->buffer); + /* XXX: questionable flags */ + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", + offset, pitch * cpp * height, virtual, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE, 0); } @@ -376,17 +373,19 @@ intel_region_attach_pbo(intelScreenPrivate *intelScreen, } if (region->buffer) { - driDeleteBuffers(1, ®ion->buffer); + dri_bo_unreference(region->buffer); region->buffer = NULL; } region->pbo = pbo; region->pbo->region = region; - region->buffer = driBOReference(pbo->buffer); + dri_bo_reference(pbo->buffer); + region->buffer = pbo->buffer; } -/* Break the COW tie to the pbo. The pbo gets to keep the data. +/* Break the COW tie to the pbo and allocate a new buffer. + * The pbo gets to keep the data. */ void intel_region_release_pbo(intelScreenPrivate *intelScreen, @@ -395,13 +394,12 @@ intel_region_release_pbo(intelScreenPrivate *intelScreen, assert(region->buffer == region->pbo->buffer); region->pbo->region = NULL; region->pbo = NULL; - driBOUnReference(region->buffer); + dri_bo_unreference(region->buffer); region->buffer = NULL; - driGenBuffers(intelScreen->regionPool, - "region", 1, ®ion->buffer, 64, 0, 0); - driBOData(region->buffer, - region->cpp * region->pitch * region->height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + region->pitch * region->cpp * region->height, + 64, 0, 0); } /* Break the COW tie to the pbo. Both the pbo and the region end up @@ -457,7 +455,7 @@ intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) } } -struct _DriBufferObject * +dri_bo * intel_region_buffer(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint flag) { diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h index d938c107a4..9623cf7bd5 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -44,7 +44,7 @@ struct intel_buffer_object; */ struct intel_region { - struct _DriBufferObject *buffer; /**< buffer manager's buffer ID */ + dri_bo *buffer; /**< buffer manager's buffer */ GLuint refcount; /**< Reference count for region */ GLuint cpp; /**< bytes per pixel */ GLuint pitch; /**< in pixels */ @@ -134,8 +134,8 @@ void intel_region_release_pbo(intelScreenPrivate *intelScreen, void intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region); -struct _DriBufferObject *intel_region_buffer(intelScreenPrivate *intelScreen, - struct intel_region *region, - GLuint flag); +dri_bo *intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint flag); #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 9034ee1b22..a1b8070f81 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -46,7 +46,7 @@ #include "intel_fbo.h" #include "i830_dri.h" -#include "dri_bufpool.h" +#include "dri_bufmgr.h" #include "intel_regions.h" #include "intel_batchbuffer.h" @@ -120,16 +120,22 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *) & intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; + if (0) + _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); + if (intelScreen->tex.size != 0) { + intelScreen->ttm = GL_FALSE; + + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *) & intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } else { + intelScreen->ttm = GL_TRUE; } -#endif + if (0) printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n", intelScreen->front.map, @@ -138,6 +144,32 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) return GL_TRUE; } +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} static struct intel_region * intel_recreate_static(intelScreenPrivate *intelScreen, @@ -393,7 +425,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) intelScreenPrivate *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; drmI830Sarea *sarea; - unsigned batchPoolSize = 1024*1024; PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> @@ -422,11 +453,11 @@ intelInitDriver(__DRIscreenPrivate * sPriv) sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); - intelScreen->maxBatchSize = BATCH_SZ; intelScreen->deviceID = gDRIPriv->deviceID; if (intelScreen->deviceID == PCI_CHIP_I865_G) intelScreen->maxBatchSize = 4096; - batchPoolSize /= intelScreen->maxBatchSize; + else + intelScreen->maxBatchSize = BATCH_SZ; intelScreen->mem = gDRIPriv->mem; intelScreen->cpp = gDRIPriv->cpp; @@ -452,24 +483,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - - /* - * FIXME: Remove this code and its references. - */ - - intelScreen->tex.offset = gDRIPriv->textureOffset; - intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; - intelScreen->tex.handle = gDRIPriv->textures; - intelScreen->tex.size = gDRIPriv->textureSize; - -#else - intelScreen->tex.offset = 0; - intelScreen->logTextureGranularity = 0; - intelScreen->tex.handle = 0; - intelScreen->tex.size = 0; -#endif - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; if (0) @@ -517,27 +530,18 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->regionPool = driDRMPoolInit(sPriv->fd); - - if (!intelScreen->regionPool) - return GL_FALSE; - - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - - if (!intelScreen->staticPool) - return GL_FALSE; - - intelScreen->texPool = intelScreen->regionPool; - - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - intelScreen->maxBatchSize, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; + if (intelScreen->ttm) { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + } else { + intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); } intel_recreate_static_regions(intelScreen); @@ -553,9 +557,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); - driPoolTakeDown(intelScreen->regionPool); - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); + /* XXX: bufmgr teardown */ FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index 05e2f1f2ea..168793d05a 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -33,7 +33,7 @@ #include "intel_rotate.h" #include "i830_common.h" #include "xmlconfig.h" -#include "dri_bufpool.h" +#include "dri_bufmgr.h" /* XXX: change name or eliminate to avoid conflict with "struct * intel_region"!!! @@ -90,11 +90,15 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; - struct _DriBufferPool *batchPool; - struct _DriBufferPool *texPool; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *staticPool; + + dri_bufmgr *bufmgr; unsigned int maxBatchSize; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; } intelScreenPrivate; @@ -121,11 +125,6 @@ extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); -extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, - unsigned checkDelayed); - extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); extern void diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c index 42679ef9db..f9c8bc5801 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -221,11 +221,10 @@ try_pbo_upload(struct intel_context *intel, intelFlush(&intel->ctx); LOCK_HARDWARE(intel); { - struct _DriBufferObject *src_buffer = - intel_bufferobj_buffer(intel, pbo, INTEL_READ); - struct _DriBufferObject *dst_buffer = - intel_region_buffer(intel->intelScreen, intelImage->mt->region, - INTEL_WRITE_FULL); + dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); + dri_bo *dst_buffer = intel_region_buffer(intel->intelScreen, + intelImage->mt->region, + INTEL_WRITE_FULL); intelEmitCopyBlit(intel, diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 10eb9a2e28..422eb96097 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -656,7 +656,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; if (intel->aub_wrap) { - bm_fake_NotifyContendedLockTake( intel ); + bm_fake_NotifyContendedLockTake( intel ); intel->vtbl.lost_hardware( intel ); intel->vtbl.aub_wrap(intel); intel->aub_wrap = 0; @@ -667,7 +667,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.lost_hardware( intel ); } - /* Make sure nothing has been emitted prior to getting the lock: + /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -700,8 +700,6 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.note_unlock( intel ); intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); _glthread_UNLOCK_MUTEX(lockMutex); } -- cgit v1.2.3 From bb1bb88bab809ce47fc5669ceb294b83ed164975 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 11:55:00 -0700 Subject: Fix some use-before-initialize in bufmgr_fake. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 2519808851..0ef3199d5f 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -846,6 +846,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, make_empty_list(&bufmgr_fake->referenced); make_empty_list(&bufmgr_fake->fenced); make_empty_list(&bufmgr_fake->on_hardware); + make_empty_list(&bufmgr_fake->lru); bufmgr_fake->low_offset = low_offset; bufmgr_fake->virtual = low_virtual; @@ -867,5 +868,9 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + bufmgr_fake->fence_emit = fence_emit; + bufmgr_fake->fence_wait = fence_wait; + bufmgr_fake->driver_priv = driver_priv; + return &bufmgr_fake->bufmgr; } -- cgit v1.2.3 From 71648a088ee7bfb1a535f32c8afdef4dc2d43e9e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:10:05 -0700 Subject: Dead code elimination and fix bufmgr_fake_wait_idle. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 0ef3199d5f..914410e4ba 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -501,7 +501,7 @@ dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake) unsigned int cookie; cookie = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); - _fence_wait_internal(bufmgr_fake->driver_priv, cookie); + _fence_wait_internal(bufmgr_fake, cookie); } /* Specifically ignore texture memory sharing. @@ -688,7 +688,6 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) static int dri_fake_bo_unmap(dri_bo *bo) { - dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake = (dri_bo_fake *)bo; /* Static buffers are always mapped. */ @@ -698,8 +697,6 @@ dri_fake_bo_unmap(dri_bo *bo) if (bo == NULL) return 0; - bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; - bo->virtual = NULL; return 0; -- cgit v1.2.3 From b0529dcc7bf6aa8330da19d98daa0abaa932cc97 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:39:00 -0700 Subject: Zero out bufmgr_fake on alloc. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 914410e4ba..191e16af61 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -837,7 +837,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, { dri_bufmgr_fake *bufmgr_fake; - bufmgr_fake = malloc(sizeof(*bufmgr_fake)); + bufmgr_fake = calloc(1, sizeof(*bufmgr_fake)); /* Initialize allocator */ make_empty_list(&bufmgr_fake->referenced); -- cgit v1.2.3 From 425d0c6305f7781788077452ae9e2de595b0961d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:57:34 -0700 Subject: Fix double-counting of low_offset in block->virtual. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 191e16af61..1820da5b44 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -214,7 +214,8 @@ alloc_block(dri_bo *bo) */ insert_at_tail(&bufmgr_fake->lru, block); - block->virtual = bufmgr_fake->virtual + block->mem->ofs; + block->virtual = bufmgr_fake->virtual + + block->mem->ofs - bufmgr_fake->low_offset; block->bo = bo; bo_fake->block = block; -- cgit v1.2.3 From 431baf221ea7858ecb5edb2a5a01b5f993147a4d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:59:39 -0700 Subject: Allow unreference with a NULL argument. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index f60d3b0db6..dd76e8ead6 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -58,6 +58,9 @@ dri_bo_reference(dri_bo *bo) void dri_bo_unreference(dri_bo *bo) { + if (bo == NULL) + return; + bo->bufmgr->bo_unreference(bo); } @@ -100,6 +103,9 @@ dri_fence_reference(dri_fence *fence) void dri_fence_unreference(dri_fence *fence) { + if (fence == NULL) + return; + fence->bufmgr->fence_unreference(fence); } -- cgit v1.2.3 From a926b7397bb19dea74995bcb02c0ee5438e4a63c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 13:47:21 -0700 Subject: Fix another mis-calling of _fence_wait_internal. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 1820da5b44..daa09cc5cd 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -825,7 +825,7 @@ dri_fake_fence_wait(dri_fence *fence) dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; _glthread_LOCK_MUTEX(bufmgr_fake->mutex); - _fence_wait_internal(bufmgr_fake->driver_priv, fence_fake->fence_cookie); + _fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); } -- cgit v1.2.3 From b9323aa2cb4563fba1b328dbc802d673449056ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 May 2007 16:55:06 -0700 Subject: Replace the flags/hint arguments to bo_alloc{,_static} with a location mask. Now, allocations only take locations, rather than a variety of unused flags. The only interesting flag before was the no_move/no_evict pair for scanout and similar buffers, which the DRI drivers don't use. That will be readded when we get to using this code for display buffer allocation, by adding a pin/unpin call (dynamic pinning/unpinning may be useful for VT switching and root window resizing). This commit changes one instance of DRM_BO_FLAG_MEM_LOCAL with DRM_BO_FLAG_MEM_TT, which appeared to have been unintentional. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 22 +++++++++++++---- src/mesa/drivers/dri/common/dri_bufmgr.h | 15 ++++-------- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 20 ++++++++-------- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 28 ++++++++++++++++++---- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 3 +-- .../drivers/dri/i915tex/intel_buffer_objects.c | 3 +-- src/mesa/drivers/dri/i915tex/intel_regions.c | 14 ++++------- 7 files changed, 61 insertions(+), 44 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 154e7841a0..840fc7601a 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -35,18 +35,30 @@ dri_bo * dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, - unsigned int alignment, unsigned int flags, unsigned int hint) + unsigned int alignment, unsigned int location_mask) { - return bufmgr->bo_alloc(bufmgr, name, size, alignment, flags, hint); + assert((location_mask & ~(DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_MEM_PRIV1 | DRM_BO_FLAG_MEM_PRIV2 | + DRM_BO_FLAG_MEM_PRIV3 | + DRM_BO_FLAG_MEM_PRIV4)) == 0); + + return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask); } dri_bo * dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, - unsigned long size, void *virtual, unsigned int flags, - unsigned int hint) + unsigned long size, void *virtual, + unsigned int location_mask) { + assert((location_mask & ~(DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_MEM_PRIV1 | DRM_BO_FLAG_MEM_PRIV2 | + DRM_BO_FLAG_MEM_PRIV3 | + DRM_BO_FLAG_MEM_PRIV4)) == 0); + return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, - flags, hint); + location_mask); } void diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 62ed9d3821..6aac54b7f4 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -81,25 +81,20 @@ struct _dri_bufmgr { * address space or graphics device aperture. They must be mapped using * bo_map() to be used by the CPU, and validated for use using bo_validate() * to be used from the graphics device. - * - * XXX: flags/hint reason to live? */ dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, unsigned long size, unsigned int alignment, - unsigned int flags, unsigned int hint); + unsigned int location_mask); /** * Allocates a buffer object for a static allocation. * * Static allocations are ones such as the front buffer that are offered by * the X Server, which are never evicted and never moved. - * - * XXX: flags/hint reason to live? */ dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, unsigned long offset, unsigned long size, - void *virtual, unsigned int flags, - unsigned int hint); + void *virtual, unsigned int location_mask); /** Takes a reference on a buffer object */ void (*bo_reference)(dri_bo *bo); @@ -165,12 +160,10 @@ struct _dri_bufmgr { }; dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, - unsigned int alignment, unsigned int flags, - unsigned int hint); + unsigned int alignment, unsigned int location_mask); dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, - void *virtual, unsigned int flags, - unsigned int hint); + void *virtual, unsigned int location_mask); void dri_bo_reference(dri_bo *bo); void dri_bo_unreference(dri_bo *bo); int dri_bo_map(dri_bo *buf, GLboolean write_enable); diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index daa09cc5cd..90a2ff85f9 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -541,9 +541,9 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) } static dri_bo * -dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, - unsigned long size, unsigned int alignment, unsigned int flags, - unsigned int hint) +dri_fake_bo_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, + unsigned int location_mask) { dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake; @@ -567,16 +567,16 @@ dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, bo_fake->alignment = alignment; bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; - bo_fake->flags = flags; + bo_fake->flags = 0; bo_fake->is_static = GL_FALSE; return &bo_fake->bo; } static dri_bo * -dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, - unsigned long offset, unsigned long size, void *virtual, - unsigned int flags, unsigned int hint) +dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int location_mask) { dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake; @@ -593,7 +593,7 @@ dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->bo.bufmgr = bufmgr; bo_fake->refcount = 1; bo_fake->name = name; - bo_fake->flags = flags; + bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; return &bo_fake->bo; @@ -854,8 +854,8 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, _glthread_INIT_MUTEX(bufmgr_fake->mutex); /* Hook in methods */ - bufmgr_fake->bufmgr.bo_alloc = dri_fake_alloc; - bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_alloc_static; + bufmgr_fake->bufmgr.bo_alloc = dri_fake_bo_alloc; + bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_bo_alloc_static; bufmgr_fake->bufmgr.bo_reference = dri_fake_bo_reference; bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference; bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map; diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index edf2a923ce..a721a7ce5c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -89,13 +89,14 @@ driFenceSignaled(DriFenceObject * fence, unsigned type) static dri_bo * dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, - unsigned long size, unsigned int alignment, unsigned int flags, - unsigned int hint) + unsigned long size, unsigned int alignment, + unsigned int location_mask) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; unsigned int pageSize = getpagesize(); int ret; + unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -103,6 +104,15 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; + /* The mask argument doesn't do anything for us that we want other than + * determine which pool (TTM or local) the buffer is allocated into, so just + * pass all of the allocation class flags. + */ + flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_EXE; + /* No hints we want to use. */ + hint = 0; + ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize, NULL, drm_bo_type_dc, flags, hint, &ttm_buf->drm_bo); @@ -122,11 +132,12 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, static dri_bo * dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, void *virtual, - unsigned int flags, unsigned int hint) + unsigned int location_mask) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; int ret; + unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -134,9 +145,18 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; + /* The mask argument doesn't do anything for us that we want other than + * determine which pool (TTM or local) the buffer is allocated into, so just + * pass all of the allocation class flags. + */ + flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + /* No hints we want to use. */ + hint = 0; + ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, NULL, drm_bo_type_fake, - flags, 0, &ttm_buf->drm_bo); + flags, hint, &ttm_buf->drm_bo); if (ret != 0) { free(ttm_buf); return NULL; diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 42ec0ae980..26eecb9440 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -102,8 +102,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_EXE, 0); + DRM_BO_FLAG_MEM_TT); dri_bo_map(batch->buf, GL_TRUE); batch->map = batch->buf->virtual; batch->size = intel->intelScreen->maxBatchSize; diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 6d72ea3fa2..1b95bfd47a 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -42,8 +42,7 @@ intel_bufferobj_alloc_buffer(struct intel_context *intel, { intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", intel_obj->Base.Size, 64, - DRM_BO_FLAG_MEM_LOCAL | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); } /** diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index 9c005c0e5d..e0574ac57b 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -106,7 +106,7 @@ intel_region_alloc(intelScreenPrivate *intelScreen, region->refcount = 1; region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - pitch * cpp * height, 64, 0, 0); + pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); return region; } @@ -162,10 +162,7 @@ intel_region_create_static(intelScreenPrivate *intelScreen, /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); return region; } @@ -195,10 +192,7 @@ intel_region_update_static(intelScreenPrivate *intelScreen, /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); } @@ -399,7 +393,7 @@ intel_region_release_pbo(intelScreenPrivate *intelScreen, region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", region->pitch * region->cpp * region->height, - 64, 0, 0); + 64, DRM_BO_FLAG_MEM_TT); } /* Break the COW tie to the pbo. Both the pbo and the region end up -- cgit v1.2.3 From 2ac17c68e2d64260168a54a275e839775828f534 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 31 May 2007 09:45:45 -0700 Subject: Add buffer manager destroy function. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 ++++++ src/mesa/drivers/dri/common/dri_bufmgr.h | 5 +++-- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 11 +++++++++++ src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 9 +++++++++ src/mesa/drivers/dri/i915tex/intel_screen.c | 2 +- 5 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 840fc7601a..407409bf06 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -144,3 +144,9 @@ dri_bo_get_subdata(dri_bo *bo, unsigned long offset, memcpy(data, (unsigned char *)bo->virtual + offset, size); dri_bo_unmap(bo); } + +void +dri_bufmgr_destroy(dri_bufmgr *bufmgr) +{ + bufmgr->destroy(bufmgr); +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 6aac54b7f4..0f8e27923b 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -155,8 +155,9 @@ struct _dri_bufmgr { void (*fence_wait)(dri_fence *fence); /** - * Checks and returns whether the given fence is signaled. + * Tears down the buffer manager instance. */ + void (*destroy)(dri_bufmgr *bufmgr); }; dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, @@ -190,6 +191,6 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, int (*fence_wait)(void *private, unsigned int cookie), void *driver_priv); -void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +void dri_bufmgr_destroy(dri_bufmgr *bufmgr); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 90a2ff85f9..c6202d969c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -829,6 +829,16 @@ dri_fake_fence_wait(dri_fence *fence) _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); } +static void +dri_fake_destroy(dri_bufmgr *bufmgr) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + _glthread_DESTROY_MUTEX(bufmgr_fake->mutex); + mmDestroy(bufmgr_fake->heap); + free(bufmgr); +} + dri_bufmgr * dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, unsigned long size, @@ -865,6 +875,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait; bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + bufmgr_fake->bufmgr.destroy = dri_fake_destroy; bufmgr_fake->fence_emit = fence_emit; bufmgr_fake->fence_wait = fence_wait; diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index a721a7ce5c..64248a1d87 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -339,6 +339,15 @@ dri_ttm_fence_wait(dri_fence *fence) } } +static void +dri_fake_destroy(dri_bufmgr *bufmgr) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + + _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); + free(bufmgr); +} + /** * Initializes the TTM buffer manager, which uses the kernel to allocate, map, * and manage map buffer objections. diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 4d61407909..e3a631b696 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -557,7 +557,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); - /* XXX: bufmgr teardown */ + dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } -- cgit v1.2.3 From 1ddbfd779b2e11131d3c86406497fe970d8f816b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Jun 2007 12:19:42 -0700 Subject: Test for TTM presence initially rather than test for lack of classic aperture. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 13 +++++++++++++ src/mesa/drivers/dri/i915tex/intel_screen.c | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index a721a7ce5c..508d4f5053 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -353,6 +353,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush) { dri_bufmgr_ttm *bufmgr_ttm; + dri_bo *test_alloc; bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); bufmgr_ttm->fd = fd; @@ -372,5 +373,17 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + /* Attempt an allocation to make sure that the DRM was actually set up for + * TTM. + */ + test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", + 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); + if (test_alloc == NULL) { + _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); + free(bufmgr_ttm); + return NULL; + } + dri_bo_unreference(test_alloc); + return &bufmgr_ttm->bufmgr; } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 4d61407909..1ae2819ae2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -123,8 +123,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) if (0) _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); if (intelScreen->tex.size != 0) { - intelScreen->ttm = GL_FALSE; - if (drmMap(sPriv->fd, intelScreen->tex.handle, intelScreen->tex.size, @@ -132,8 +130,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); return GL_FALSE; } - } else { - intelScreen->ttm = GL_TRUE; } if (0) @@ -530,12 +526,16 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - if (intelScreen->ttm) { - intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, - DRM_FENCE_TYPE_EXE, - DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW); - } else { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + if (intelScreen->bufmgr == NULL) { + if (intelScreen->tex.size == 0) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); + return GL_FALSE; + } intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, intelScreen->tex.map, intelScreen->tex.size, -- cgit v1.2.3 From bf0ae055de73e0cf66085e02ad4881bea497e4cb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Jun 2007 12:20:07 -0700 Subject: Fix TTM static allocation flags. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 508d4f5053..47ea42ad55 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -150,7 +150,7 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, * pass all of the allocation class flags. */ flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE; /* No hints we want to use. */ hint = 0; -- cgit v1.2.3 From f972f58d8003de9495af82e7927fb962f460b083 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 11:44:48 -0700 Subject: Improve fake bufmgr debugging, and don't try to migrate static buffers. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 39 +++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 90a2ff85f9..8bae4d8b34 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -41,7 +41,11 @@ #include "mm.h" #include "imports.h" +#if 0 +#define DBG(...) _mesa_printf(__VA_ARGS__) +#else #define DBG(...) +#endif /* Internal flags: */ @@ -570,6 +574,9 @@ dri_fake_bo_alloc(dri_bufmgr *bufmgr, const char *name, bo_fake->flags = 0; bo_fake->is_static = GL_FALSE; + DBG("drm_bo_alloc: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + return &bo_fake->bo; } @@ -592,10 +599,14 @@ dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->bo.virtual = virtual; bo_fake->bo.bufmgr = bufmgr; bo_fake->refcount = 1; + bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; + DBG("drm_bo_alloc_static: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + return &bo_fake->bo; } @@ -648,7 +659,8 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) _glthread_LOCK_MUTEX(bufmgr_fake->mutex); { - DBG("bmMapBuffer %d\n", bo_fake->id); + DBG("drm_bo_map: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); if (bo->virtual != NULL) { _mesa_printf("%s: already mapped\n", __FUNCTION__); @@ -698,6 +710,9 @@ dri_fake_bo_unmap(dri_bo *bo) if (bo == NULL) return 0; + DBG("drm_bo_unmap: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + bo->virtual = NULL; return 0; @@ -713,22 +728,32 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) * different flags. See drmAddValidateItem(). */ + DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; _glthread_LOCK_MUTEX(bufmgr_fake->mutex); { + if (bo_fake->is_static) { + /* Add it to the needs-fence list */ + bufmgr_fake->need_fence = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 0; + } + /* Allocate the card memory */ if (!bo_fake->block && !evict_and_alloc_block(bo)) { bufmgr_fake->fail = 1; _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + DBG("Failed to validate buf %d:%s\n", bo_fake->id, bo_fake->name); return -1; } assert(bo_fake->block); assert(bo_fake->block->bo == &bo_fake->bo); - DBG("Add buf %d (block %p, dirty %d) to referenced list\n", - bo_fake->id, bo_fake->block, bo_fake->dirty); + DBG("Add buf %d:%s (block %p, dirty %d) to referenced list\n", + bo_fake->id, bo_fake->name, bo_fake->block, bo_fake->dirty); move_to_tail(&bufmgr_fake->referenced, bo_fake->block); bo_fake->block->referenced = 1; @@ -737,8 +762,8 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) /* Upload the buffer contents if necessary */ if (bo_fake->dirty) { - DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", bo_fake->id, - bo_fake->name, bo->size, block->mem->ofs); + DBG("Upload dirty buf %d:%s, sz %d offset 0x%x\n", bo_fake->id, + bo_fake->name, bo->size, bo_fake->block->mem->ofs); assert(!(bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); @@ -786,6 +811,8 @@ dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_blocks(bufmgr_fake, cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + DBG("drm_fence_validated: 0x%08x cookie\n", fence_fake->fence_cookie); + return &fence_fake->fence; } @@ -824,6 +851,8 @@ dri_fake_fence_wait(dri_fence *fence) dri_fence_fake *fence_fake = (dri_fence_fake *)fence; dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + DBG("drm_fence_wait: 0x%08x cookie\n", fence_fake->fence_cookie); + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); _fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); -- cgit v1.2.3 From f7643b96e9e526a7610dec51650546e4b916ccd2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jul 2007 15:45:49 -0700 Subject: bufmgr_fake: Keep the bufmgr lock held while freeing a block. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index e08b5b3c7f..003ac49f3b 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -632,11 +632,11 @@ dri_fake_bo_unreference(dri_bo *bo) _glthread_LOCK_MUTEX(bufmgr_fake->mutex); if (--bo_fake->refcount == 0) { - _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); /* No remaining references, so free it */ if (bo_fake->block) free_block(bufmgr_fake, bo_fake->block); free_backing_store(bo); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); free(bo); return; } -- cgit v1.2.3 From d086f7ab2e38fc2b5398aed6823453ae53e5dcb8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 6 Jul 2007 12:01:33 -0700 Subject: bufmgr_ttm: hook up destroy function, track buffer names. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index fd432ba3f7..4c3624382c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -56,6 +56,7 @@ typedef struct _dri_bo_ttm { int refcount; /* Protected by bufmgr->mutex */ drmBO drm_bo; + const char *name; } dri_bo_ttm; typedef struct _dri_fence_ttm @@ -124,6 +125,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.offset = ttm_buf->drm_bo.offset; ttm_buf->bo.virtual = NULL; ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->name = name; ttm_buf->refcount = 1; return &ttm_buf->bo; @@ -165,6 +167,7 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.offset = ttm_buf->drm_bo.offset; ttm_buf->bo.virtual = virtual; ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->name = name; ttm_buf->refcount = 1; return &ttm_buf->bo; @@ -340,7 +343,7 @@ dri_ttm_fence_wait(dri_fence *fence) } static void -dri_fake_destroy(dri_bufmgr *bufmgr) +dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr) { dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; @@ -381,6 +384,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference; bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy; /* Attempt an allocation to make sure that the DRM was actually set up for * TTM. -- cgit v1.2.3 From 9a4cc2e90595a41d3d3cb6a752e4b5a089a213d2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 25 Jul 2007 10:12:23 -0700 Subject: Add notes about bufmgr initialization failures. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 1 + src/mesa/drivers/dri/i915tex/intel_screen.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 4c3624382c..6e29199cd8 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -392,6 +392,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); if (test_alloc == NULL) { + fprintf(stderr, "TTM test allocation failed\n"); _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); free(bufmgr_ttm); return NULL; diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 89cf3ea913..a0471019e4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -536,6 +536,8 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __func__, __LINE__); return GL_FALSE; } + fprintf(stderr, "[%s:%u] Failed to init TTM buffer manager, falling back" + " to classic.\n", __func__, __LINE__); intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, intelScreen->tex.map, intelScreen->tex.size, -- cgit v1.2.3 From 9c61925da0f24dfc5f4cb1ee5d50e18bfe3f39ce Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 31 Jul 2007 09:22:43 -0700 Subject: bufmgr_fake: eliminate the referenced list, which is now just on_hardware. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 49 +++++---------------------- 1 file changed, 8 insertions(+), 41 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 003ac49f3b..dab723eac0 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -62,7 +62,6 @@ struct block { struct block *next, *prev; struct mem_block *mem; /* BM_MEM_AGP */ - unsigned referenced:1; unsigned on_hardware:1; unsigned fenced:1; @@ -86,7 +85,6 @@ typedef struct _bufmgr_fake { unsigned buf_nr; /* for generating ids */ - struct block referenced; /* after bmBufferOffset */ struct block on_hardware; /* after bmValidateBuffers */ struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ /* then to bufmgr->lru or free() */ @@ -236,11 +234,7 @@ static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block) if (!block) return; - if (block->referenced) { - _mesa_printf("tried to free block on referenced list\n"); - assert(0); - } - else if (block->on_hardware) { + if (block->on_hardware) { block->bo = NULL; } else if (block->fenced) { @@ -383,14 +377,6 @@ static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, } } - /* Also check the referenced list: - */ - foreach_s(block, tmp, &bufmgr_fake->referenced ) { - if (block->fenced && _fence_test(bufmgr_fake, block->fence)) { - block->fenced = 0; - } - } - DBG("%s: %d\n", __FUNCTION__, ret); return ret; } @@ -412,19 +398,6 @@ static void fence_blocks(dri_bufmgr_fake *bufmgr_fake, unsigned fence) move_to_tail(&bufmgr_fake->fenced, block); } - /* Also check the referenced list: - */ - foreach_s (block, tmp, &bufmgr_fake->referenced) { - if (block->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->bo, fence); - - block->fence = fence; - block->on_hardware = 0; - block->fenced = 1; - } - } - assert(is_empty_list(&bufmgr_fake->on_hardware)); } @@ -522,8 +495,6 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) { struct block *block, *tmp; - assert(is_empty_list(&bufmgr_fake->referenced)); - bufmgr_fake->need_fence = 1; bufmgr_fake->fail = 0; @@ -533,6 +504,9 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) */ dri_bufmgr_fake_wait_idle(bufmgr_fake); + /* Check that we hadn't released the lock without having fenced the last + * set of buffers. + */ assert(is_empty_list(&bufmgr_fake->fenced)); assert(is_empty_list(&bufmgr_fake->on_hardware)); @@ -752,12 +726,6 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) assert(bo_fake->block); assert(bo_fake->block->bo == &bo_fake->bo); - DBG("Add buf %d:%s (block %p, dirty %d) to referenced list\n", - bo_fake->id, bo_fake->name, bo_fake->block, bo_fake->dirty); - - move_to_tail(&bufmgr_fake->referenced, bo_fake->block); - bo_fake->block->referenced = 1; - bo->offset = bo_fake->block->mem->ofs; /* Upload the buffer contents if necessary */ @@ -775,12 +743,12 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) dri_bufmgr_fake_wait_idle(bufmgr_fake); memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size); - - bo_fake->block->referenced = 0; - bo_fake->block->on_hardware = 1; - move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + bo_fake->dirty = 0; } + bo_fake->block->on_hardware = 1; + move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + bufmgr_fake->need_fence = 1; } _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); @@ -880,7 +848,6 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake = calloc(1, sizeof(*bufmgr_fake)); /* Initialize allocator */ - make_empty_list(&bufmgr_fake->referenced); make_empty_list(&bufmgr_fake->fenced); make_empty_list(&bufmgr_fake->on_hardware); make_empty_list(&bufmgr_fake->lru); -- cgit v1.2.3 From f761c99d25aa71c4c761c1f876782a81c795fd5c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 1 Aug 2007 08:41:51 -0600 Subject: fix mem leak (bug 11793) --- src/mesa/drivers/dri/common/dri_drmpool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c index 878a148b39..592ac10542 100644 --- a/src/mesa/drivers/dri/common/dri_drmpool.c +++ b/src/mesa/drivers/dri/common/dri_drmpool.c @@ -51,6 +51,7 @@ pool_create(struct _DriBufferPool *pool, return NULL; if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); return NULL; } -- cgit v1.2.3 From 101563a838a9ed1f9cad5f99fcbf598cbdfba0df Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Aug 2007 15:55:42 -0700 Subject: Don't try to use kernel BO flags in dri_bufmgr_fake internals. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index dab723eac0..e0d23a3647 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -49,8 +49,9 @@ /* Internal flags: */ -#define BM_NO_BACKING_STORE DRM_BO_FLAG_MEM_PRIV0 -#define BM_NO_FENCE_SUBDATA DRM_BO_FLAG_MEM_PRIV1 +#define BM_NO_BACKING_STORE 0x00000001 +#define BM_NO_FENCE_SUBDATA 0x00000002 +#define BM_PINNED 0x00000004 /* Wrapper around mm.c's mem_block, which understands that you must * wait for fences to expire before memory can be freed. This is @@ -254,7 +255,7 @@ alloc_backing_store(dri_bo *bo) { dri_bo_fake *bo_fake = (dri_bo_fake *)bo; assert(!bo_fake->backing_store); - assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE))); bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64); } @@ -263,7 +264,7 @@ static void free_backing_store(dri_bo *bo) { dri_bo_fake *bo_fake = (dri_bo_fake *)bo; - assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE))); if (bo_fake->backing_store) { ALIGN_FREE(bo_fake->backing_store); @@ -280,7 +281,7 @@ set_dirty(dri_bo *bo) if (bo_fake->flags & BM_NO_BACKING_STORE) bo_fake->invalidate_cb(&bufmgr_fake->bufmgr, bo_fake->invalidate_ptr); - assert(!(bo_fake->flags & DRM_BO_FLAG_NO_EVICT)); + assert(!(bo_fake->flags & BM_PINNED)); DBG("set_dirty - buf %d\n", bo_fake->id); bo_fake->dirty = 1; @@ -575,7 +576,7 @@ dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->refcount = 1; bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; - bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + bo_fake->flags = BM_PINNED | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; DBG("drm_bo_alloc_static: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, @@ -619,7 +620,7 @@ dri_fake_bo_unreference(dri_bo *bo) /** * Map a buffer into bo->virtual, allocating either card memory space (If - * BM_NO_BACKING_STORE or DRM_BO_FLAG_NO_EVICT) or backing store, as necessary. + * BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary. */ static int dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) @@ -640,7 +641,7 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) _mesa_printf("%s: already mapped\n", __FUNCTION__); abort(); } - else if (bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT)) { + else if (bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED)) { if (!bo_fake->block && !evict_and_alloc_block(bo)) { DBG("%s: alloc failed\n", __FUNCTION__); @@ -734,7 +735,7 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) bo_fake->name, bo->size, bo_fake->block->mem->ofs); assert(!(bo_fake->flags & - (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); + (BM_NO_BACKING_STORE|BM_PINNED))); /* Actually, should be able to just wait for a fence on the memory, * which we would be tracking when we free it. Waiting for idle is -- cgit v1.2.3 From 21b37b9687b078297935062e3ad9f379b6f36519 Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Sun, 12 Aug 2007 13:41:13 +0200 Subject: fix spantmp2 READ_RGBA inline asm (#11931) --- src/mesa/drivers/dri/common/spantmp2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 50f3cf5581..53f5f846a0 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -114,7 +114,7 @@ do { \ GLuint p = *(volatile GLuint *) GET_PTR(_x, _y); \ __asm__ __volatile__( "bswap %0; rorl $8, %0" \ - : "=r" (p) : "r" (p) ); \ + : "=r" (p) : "0" (p) ); \ ((GLuint *)rgba)[0] = p; \ } while (0) # elif defined( MESA_BIG_ENDIAN ) -- cgit v1.2.3 From 2b77a8696b14bc36be359bf858189ade5fab8511 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:34:24 -0700 Subject: Don't forget to update buffer offset after validation. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 6e29199cd8..7f1e10fbc8 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -262,6 +262,8 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) /* XXX: add to fence list for sanity checking */ } + buf->offset = ttm_buf->drm_bo.offset; + return err; } -- cgit v1.2.3 From 64297acf9e96353fe724362248246acaf0be8cb8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:35:06 -0700 Subject: Fix bad printf on TTM fence_wait failure. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 7f1e10fbc8..2d4f518b31 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -339,7 +339,7 @@ dri_ttm_fence_wait(dri_fence *fence) _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); if (ret != 0) { _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", - __FILE__, __LINE__, fence_ttm->name); + __FILE__, __LINE__, ret, fence_ttm->name); abort(); } } -- cgit v1.2.3 From 3e168a0ec840af65863e197f4a884aae905b213e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:32:53 -0700 Subject: Convert TTM code to require the server provide buffers for front/back/depth. This removes the use of fake buffers from the driver, such that it could probably be removed from the interface. It also should assist in proper synchronization of access. --- src/mesa/drivers/dri/common/dri_bufmgr.h | 2 + src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 46 ++++----- src/mesa/drivers/dri/i915tex/intel_regions.c | 32 +++++-- src/mesa/drivers/dri/i915tex/intel_regions.h | 2 + src/mesa/drivers/dri/i915tex/intel_screen.c | 110 +++++++++++++--------- src/mesa/drivers/dri/i915tex/intel_screen.h | 1 + src/mesa/drivers/dri/i915tex/server/i830_common.h | 9 ++ 7 files changed, 121 insertions(+), 81 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 0f8e27923b..3be342926f 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -192,5 +192,7 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, unsigned int cookie), void *driver_priv); void dri_bufmgr_destroy(dri_bufmgr *bufmgr); +dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, + unsigned int handle); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 2d4f518b31..5128d95370 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -131,15 +131,30 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, return &ttm_buf->bo; } +/* Our TTM backend doesn't allow creation of static buffers, as that requires + * privelege for the non-fake case, and the lock in the fake case where we were + * working around the X Server not creating buffers and passing handles to us. + */ static dri_bo * dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, void *virtual, unsigned int location_mask) +{ + return NULL; +} + +/** Returns a dri_bo wrapping the given buffer object handle. + * + * This can be used when one application needs to pass a buffer object + * to another. + */ +dri_bo * +dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, + unsigned int handle) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; int ret; - unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -147,25 +162,14 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; - /* The mask argument doesn't do anything for us that we want other than - * determine which pool (TTM or local) the buffer is allocated into, so just - * pass all of the allocation class flags. - */ - flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE; - /* No hints we want to use. */ - hint = 0; - - ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, - NULL, drm_bo_type_fake, - flags, hint, &ttm_buf->drm_bo); + ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo); if (ret != 0) { free(ttm_buf); return NULL; } ttm_buf->bo.size = ttm_buf->drm_bo.size; ttm_buf->bo.offset = ttm_buf->drm_bo.offset; - ttm_buf->bo.virtual = virtual; + ttm_buf->bo.virtual = NULL; ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; @@ -367,7 +371,6 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush) { dri_bufmgr_ttm *bufmgr_ttm; - dri_bo *test_alloc; bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); bufmgr_ttm->fd = fd; @@ -388,18 +391,5 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy; - /* Attempt an allocation to make sure that the DRM was actually set up for - * TTM. - */ - test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", - 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); - if (test_alloc == NULL) { - fprintf(stderr, "TTM test allocation failed\n"); - _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); - free(bufmgr_ttm); - return NULL; - } - dri_bo_unreference(test_alloc); - return &bufmgr_ttm->bufmgr; } diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index 4e3cea5e05..4eac859a13 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -147,6 +147,7 @@ intel_region_release(struct intel_region **region) struct intel_region * intel_region_create_static(intelScreenPrivate *intelScreen, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height) @@ -159,9 +160,18 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", - offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT); + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } return region; } @@ -172,6 +182,7 @@ void intel_region_update_static(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height) @@ -188,9 +199,18 @@ intel_region_update_static(intelScreenPrivate *intelScreen, */ dri_bo_unreference(region->buffer); - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", - offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT); + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } } diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h index 9623cf7bd5..42d7b17711 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -73,6 +73,7 @@ void intel_region_release(struct intel_region **ib); extern struct intel_region *intel_region_create_static(intelScreenPrivate *intelScreen, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, @@ -81,6 +82,7 @@ extern void intel_region_update_static(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height); diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index a0471019e4..2721a90094 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -170,18 +170,26 @@ intel_fence_wait(void *private, unsigned int cookie) static struct intel_region * intel_recreate_static(intelScreenPrivate *intelScreen, struct intel_region *region, - GLuint mem_type, - GLuint offset, - void *virtual, - GLuint cpp, GLuint pitch, GLuint height) + intelRegion *region_desc, + GLuint mem_type) { if (region) { - intel_region_update_static(intelScreen, region, mem_type, offset, - virtual, cpp, pitch, height); + intel_region_update_static(intelScreen, region, mem_type, + region_desc->bo_handle, region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); } else { - region = intel_region_create_static(intelScreen, mem_type, offset, - virtual, cpp, pitch, height); + region = intel_region_create_static(intelScreen, mem_type, + region_desc->bo_handle, + region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); } + + assert(region->buffer != NULL); + return region; } @@ -203,57 +211,42 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen) intelScreen->front_region = intel_recreate_static(intelScreen, intelScreen->front_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->front.offset, - intelScreen->front.map, - intelScreen->cpp, - intelScreen->front.pitch / intelScreen->cpp, - intelScreen->height); - - intelScreen->rotated_region = - intel_recreate_static(intelScreen, - intelScreen->rotated_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->rotated.offset, - intelScreen->rotated.map, - intelScreen->cpp, - intelScreen->rotated.pitch / - intelScreen->cpp, intelScreen->height); + &intelScreen->front, + DRM_BO_FLAG_MEM_TT); + /* The rotated region is only used for old DDXes that didn't handle rotation +\ * on their own. + */ + if (intelScreen->driScrnPriv->ddxMinor < 8) { + intelScreen->rotated_region = + intel_recreate_static(intelScreen, + intelScreen->rotated_region, + &intelScreen->rotated, + DRM_BO_FLAG_MEM_TT); + } intelScreen->back_region = intel_recreate_static(intelScreen, intelScreen->back_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->back.offset, - intelScreen->back.map, - intelScreen->cpp, - intelScreen->back.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->back, + DRM_BO_FLAG_MEM_TT); if (intelScreen->third.handle) { intelScreen->third_region = intel_recreate_static(intelScreen, intelScreen->third_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->third.offset, - intelScreen->third.map, - intelScreen->cpp, - intelScreen->third.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->third, + DRM_BO_FLAG_MEM_TT); } - /* Still assuming front.cpp == depth.cpp + /* Still assumes front.cpp == depth.cpp. We can kill this when we move to + * private buffers. */ intelScreen->depth_region = intel_recreate_static(intelScreen, intelScreen->depth_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->depth.offset, - intelScreen->depth.map, - intelScreen->cpp, - intelScreen->depth.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->depth, + DRM_BO_FLAG_MEM_TT); } /** @@ -396,6 +389,18 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; + if (intelScreen->driScrnPriv->ddxMinor >= 9) { + intelScreen->front.bo_handle = sarea->front_bo_handle; + intelScreen->back.bo_handle = sarea->back_bo_handle; + intelScreen->third.bo_handle = sarea->third_bo_handle; + intelScreen->depth.bo_handle = sarea->depth_bo_handle; + } else { + intelScreen->front.bo_handle = -1; + intelScreen->back.bo_handle = -1; + intelScreen->third.bo_handle = -1; + intelScreen->depth.bo_handle = -1; + } + intelScreen->tex.offset = sarea->tex_offset; intelScreen->logTextureGranularity = sarea->log_tex_granularity; intelScreen->tex.handle = sarea->tex_handle; @@ -526,10 +531,21 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, - DRM_FENCE_TYPE_EXE, - DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW); + /* If we've got a new enough DDX that's initializing TTM and giving us + * object handles for the shared buffers, use that. + */ + intelScreen->ttm = GL_FALSE; + if (getenv("INTEL_NO_TTM") == NULL && + intelScreen->driScrnPriv->ddxMinor >= 9 && + intelScreen->front.bo_handle != -1) { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + if (intelScreen->bufmgr != NULL) + intelScreen->ttm = GL_TRUE; + } + /* Otherwise, use the classic buffer manager. */ if (intelScreen->bufmgr == NULL) { if (intelScreen->tex.size == 0) { fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index 168793d05a..aa0ef2c509 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -45,6 +45,7 @@ typedef struct char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ int pitch; /* row stride, in bytes */ + unsigned int bo_handle; /* buffer object id if available, or -1 */ } intelRegion; typedef struct diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index 7a76957c6a..bd2bec3eae 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -136,6 +136,15 @@ typedef struct { int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drmI830Sarea; /* Flags for perf_boxes -- cgit v1.2.3 From e3745dac59602a9d21b49d602646de5aef95075f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 18 Sep 2007 15:46:16 -0700 Subject: Add some error reporting and a couple of assertions to TTM bufmgr. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 5128d95370..8c36502b85 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -220,6 +220,8 @@ dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) if (write_enable) flags |= DRM_BO_FLAG_WRITE; + assert(buf->virtual == NULL); + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); } @@ -234,6 +236,8 @@ dri_ttm_bo_unmap(dri_bo *buf) bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + assert(buf->virtual != NULL); + buf->virtual = NULL; return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); @@ -264,6 +268,9 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) if (err == 0) { /* XXX: add to fence list for sanity checking */ + } else { + fprintf(stderr, "failed to validate buffer (%s): %s\n", + ttm_buf->name, strerror(err)); } buf->offset = ttm_buf->drm_bo.offset; @@ -294,6 +301,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { + fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(ret)); free(fence_ttm); return NULL; } -- cgit v1.2.3 From b7fd06a871893d8ed482d16207136e324bb7d85c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 09:20:48 -0700 Subject: Fix flipped sign to strerror. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 8c36502b85..e264048b70 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -270,7 +270,7 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) /* XXX: add to fence list for sanity checking */ } else { fprintf(stderr, "failed to validate buffer (%s): %s\n", - ttm_buf->name, strerror(err)); + ttm_buf->name, strerror(-err)); } buf->offset = ttm_buf->drm_bo.offset; @@ -301,7 +301,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { - fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(ret)); + fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret)); free(fence_ttm); return NULL; } -- cgit v1.2.3 From 75912596741d1afe5827dab6913c3d810eda8788 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 11:38:32 -0700 Subject: Add disabled-by-default tracing of TTM bufmgr operations. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index e264048b70..f864b1bc89 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -42,6 +42,8 @@ #include "string.h" #include "imports.h" +#define BUFMGR_DEBUG 0 + typedef struct _dri_bufmgr_ttm { dri_bufmgr bufmgr; @@ -128,6 +130,10 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->name = name; ttm_buf->refcount = 1; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return &ttm_buf->bo; } @@ -174,6 +180,11 @@ dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, ttm_buf->name = name; ttm_buf->refcount = 1; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo, + ttm_buf->name); +#endif + return &ttm_buf->bo; } @@ -222,6 +233,10 @@ dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) assert(buf->virtual == NULL); +#if BUFMGR_DEBUG + fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); } @@ -240,6 +255,10 @@ dri_ttm_bo_unmap(dri_bo *buf) buf->virtual = NULL; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); } @@ -275,6 +294,10 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) buf->offset = ttm_buf->drm_bo.offset; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return err; } @@ -305,6 +328,12 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, free(fence_ttm); return NULL; } + +#if BUFMGR_DEBUG + fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence, + fence_ttm->name); +#endif + return &fence_ttm->fence; } @@ -354,6 +383,11 @@ dri_ttm_fence_wait(dri_fence *fence) __FILE__, __LINE__, ret, fence_ttm->name); abort(); } + +#if BUFMGR_DEBUG + fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence, + fence_ttm->name); +#endif } static void -- cgit v1.2.3 From d0350dadaa52064f67e4e9001145af14478b2849 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 Sep 2007 16:16:54 -0700 Subject: Fix buffer/fence reference counting due to Destroy vs Unreference difference. While here, remove the unnecessary fence type saving for the wait ioctl, as a 0 argument for type means "use your other saved copy". --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 46 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index f864b1bc89..bda8e34190 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -59,6 +59,11 @@ typedef struct _dri_bo_ttm { int refcount; /* Protected by bufmgr->mutex */ drmBO drm_bo; const char *name; + /** + * Note whether we are the owner of the buffer, to determine if we must + * drmBODestroy or drmBOUnreference to unreference the buffer. + */ + GLboolean owner; } dri_bo_ttm; typedef struct _dri_fence_ttm @@ -66,8 +71,6 @@ typedef struct _dri_fence_ttm dri_fence fence; int refcount; /* Protected by bufmgr->mutex */ - /** Fence type from when the fence was created, used for later waits */ - unsigned int type; const char *name; drmFence drm_fence; } dri_fence_ttm; @@ -129,6 +132,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; + ttm_buf->owner = GL_TRUE; #if BUFMGR_DEBUG fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); @@ -179,6 +183,7 @@ dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; + ttm_buf->owner = GL_FALSE; #if BUFMGR_DEBUG fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo, @@ -210,7 +215,24 @@ dri_ttm_bo_unreference(dri_bo *buf) _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); if (--ttm_buf->refcount == 0) { - drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + int ret; + + /* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead + * of simply unreferencing is madness, and leads to behaviors we may not + * want (making the buffer unsharable). + */ + if (ttm_buf->owner) + ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo); + else + ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + if (ret != 0) { + fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name, + strerror(-ret)); + } +#if BUFMGR_DEBUG + fprintf(stderr, "bo_unreference final: %p (%s)\n", + &ttm_buf->bo, ttm_buf->name); +#endif _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); free(buf); return; @@ -320,7 +342,6 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->refcount = 1; fence_ttm->name = name; - fence_ttm->type = type; fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { @@ -359,7 +380,19 @@ dri_ttm_fence_unreference(dri_fence *fence) _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); if (--fence_ttm->refcount == 0) { - drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + int ret; + + /* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers + * instead of simply unreferencing is madness, and leads to behaviors we + * may not want (making the fence unsharable). This behavior by the DRM + * ioctls should be fixed, and drmFenceDestroy eliminated. + */ + ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + if (ret != 0) { + fprintf(stderr, "drmFenceDestroy failed (%s): %s\n", + fence_ttm->name, strerror(-ret)); + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); free(fence); return; @@ -375,8 +408,7 @@ dri_ttm_fence_wait(dri_fence *fence) int ret; _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); - ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, - fence_ttm->type); + ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0); _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); if (ret != 0) { _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", -- cgit v1.2.3 From f388d62b39e9273dd8aac425da54015af91192d8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 25 Sep 2007 16:22:00 +1000 Subject: drm: update bufmgr code to reflect changes in drm interface --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/common') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index bda8e34190..235398eb87 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -305,7 +305,7 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) mask = DRM_BO_MASK_MEM; mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE); - err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, mask, 0); + err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, 0, flags, mask, 0); if (err == 0) { /* XXX: add to fence list for sanity checking */ @@ -343,7 +343,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->refcount = 1; fence_ttm->name = name; fence_ttm->fence.bufmgr = bufmgr; - ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); + ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence); if (ret) { fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret)); free(fence_ttm); -- cgit v1.2.3