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/Makefile.template | 3 +- 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 ------- 7 files changed, 1455 insertions(+), 797 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') diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 5261a4b55d..3d0389c60c 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -13,7 +13,8 @@ COMMON_SOURCES = \ COMMON_BM_SOURCES = \ ../common/dri_bufmgr.c \ - ../common/dri_drmpool.c + ../common/dri_bufmgr_ttm.c \ + ../common/dri_bufmgr_fake.c ifeq ($(WINDOW_SYSTEM),dri) 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') 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 1f08f5d97068ea89f0fa527520a2ccb0a69ea50b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:36:26 -0700 Subject: Rename the i915tex_dri.so driver to just i915_dri.so again. --- src/mesa/drivers/dri/i915tex/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 27fb29e9c2..c6a29149c7 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -LIBNAME = i915tex_dri.so +LIBNAME = i915_dri.so MINIGLX_SOURCES = server/intel_dri.c -- cgit v1.2.3 From b12b24a430e2d328cbe102612b8a152e5c925cbf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:36:43 -0700 Subject: Restore missing intel_batchbuffer_reset() which was needed. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 55e40d5d97..67fca371a7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -80,12 +80,16 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) /*====================================================================== * Public functions */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) { - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } - batch->intel = intel; batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", intel->intelScreen->maxBatchSize, 4096, DRM_BO_FLAG_MEM_TT | @@ -94,9 +98,17 @@ intel_batchbuffer_alloc(struct intel_context *intel) batch->map = batch->buf->virtual; batch->size = intel->intelScreen->maxBatchSize; batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + batch->intel = intel; batch->last_fence = NULL; intel_batchbuffer_reset(batch); + return batch; } -- cgit v1.2.3 From 4cf2cc0d18df67d1d550b777c8db2e088f1c4188 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 11:29:55 -0700 Subject: Ratchet required version down to 1.5 (pre-TTM). --- src/mesa/drivers/dri/i915tex/intel_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index a1b8070f81..e268af91f1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -879,7 +879,7 @@ __driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 5, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; + static const __DRIversion drm_expected = { 1, 5, 0 }; dri_interface = interface; -- 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') 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 180f0bb964cd7aa233233dbe3bc6605e07ef1d4c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:09:34 -0700 Subject: Kill old struct bufmgr members. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 1 - src/mesa/drivers/dri/i915tex/intel_context.h | 5 ----- 2 files changed, 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index 302a605d3c..82a3d49fca 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -24,7 +24,6 @@ struct buffer_reloc struct intel_batchbuffer { - struct bufmgr *bm; struct intel_context *intel; dri_bo *buf; diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 429f53cb51..e75dd64fe1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -215,11 +215,6 @@ struct intel_context GLboolean hw_stipple; GLboolean strict_conformance; - /* AGP memory buffer manager: - */ - struct bufmgr *bm; - - /* State for intelvb.c and inteltris.c. */ GLuint RenderIndex; -- 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') 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') 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') 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') 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') 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 c085e350df593ab2af60f53b86265db4c3eab38a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 13:47:46 -0700 Subject: Fix a refcounting mistake with first_swap_fence. --- src/mesa/drivers/dri/i915tex/intel_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index ef596bdfc5..5d97f08434 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -152,8 +152,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, if (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; + dri_fence_reference(intel->first_swap_fence); } UNLOCK_HARDWARE(intel); -- cgit v1.2.3 From 8b8d4d3e106b1ca7174c834a2f9b494922fc6e72 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 10:49:32 -0700 Subject: Notify the fake buffer manager on contended lock take. --- src/mesa/drivers/dri/i915tex/intel_context.c | 10 ++++++++++ src/mesa/drivers/dri/i915tex/server/i830_common.h | 1 + 2 files changed, 11 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 4f58f56ada..696845a7fc 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -638,6 +638,16 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + /* If the last consumer of the texture memory wasn't us, notify the fake + * bufmgr and record the new owner. We should have the memory shared + * between contexts of a single fake bufmgr, but this will at least make + * things correct for now. + */ + if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { + sarea->texAge = intel->hHWContext; + dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + } + if (sarea->width != intelScreen->width || sarea->height != intelScreen->height || sarea->rotation != intelScreen->current_rotation) { diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index d4d58886ce..7a76957c6a 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -85,6 +85,7 @@ typedef struct { int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ int pf_active; -- cgit v1.2.3 From 2b325a9f32e4478d324feaa9fcc3706b8bae4a3b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 10:53:33 -0700 Subject: Remove unused intel_batchpool.c. This may need to be implemented again, but probably not as a buffer manager (pool). --- src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 ------------------------- 1 file changed, 418 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c (limited to 'src/mesa/drivers/dri') 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 2503b8a62a..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, DRM_BO_HINT_DONT_FENCE, &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; -} -- cgit v1.2.3 From b0b84529cf1d61d3a53d402f039b442260788624 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 11:08:55 -0700 Subject: Enable INTEL_DEBUG environment variable. --- src/mesa/drivers/dri/i915tex/intel_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index e75dd64fe1..d03c4c5dd1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -342,7 +342,7 @@ __memcpy(void *to, const void *from, size_t n) /* ================================================================ * Debugging: */ -#define DO_DEBUG 0 +#define DO_DEBUG 1 #if DO_DEBUG extern int INTEL_DEBUG; #else -- cgit v1.2.3 From b1fcabefa2f3fa81a20c1556383458315bb49bbf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 13:06:12 -0700 Subject: Don't read beyond the end of the buffer with INTEL_DEBUG=bat. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 67fca371a7..42ec0ae980 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -67,13 +67,23 @@ */ static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint size) { int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", size / 4); + for (i = 0; i < size / 4; i += 4) { + char dw1[11], dw2[11] = "", dw3[11] = "", dw4[11] = ""; + + sprintf(dw1, "0x%08x", ptr[i]); + if (i + 1 < size / 4) + sprintf(dw2, "0x%08x", ptr[i + 1]); + if (i + 2 < size / 4) + sprintf(dw3, "0x%08x", ptr[i + 2]); + if (i + 3 < size / 4) + sprintf(dw4, "0x%08x", ptr[i + 3]); + fprintf(stderr, "0x%x:\t%s %s %s %s\n", offset + i * 4, + dw1, dw2, dw3, dw4); + } fprintf(stderr, "END BATCH\n\n\n"); } -- 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') 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 fb7e21514f96c36e4c5abcb6621d48cb16a8c1e1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 31 May 2007 09:34:08 -0700 Subject: Remove some stale comments. --- src/mesa/drivers/dri/i915tex/intel_regions.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index e0574ac57b..4e3cea5e05 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -159,7 +159,6 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, DRM_BO_FLAG_MEM_TT); @@ -189,7 +188,6 @@ intel_region_update_static(intelScreenPrivate *intelScreen, */ 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); -- 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') 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 7a452b21a2fa329871062a6ee49f0d0f4928d01c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Jun 2007 16:20:34 -0700 Subject: Correct a mis-count in a LOAD_STATE_IMMEDIATE_1 length argument. --- src/mesa/drivers/dri/i915tex/i915_vtbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 2a3ccd01a0..5d6ad8d86c 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -197,7 +197,7 @@ i915_emit_invarient_state(struct intel_context *intel) /* Need to initialize this to zero. */ - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1)); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0); OUT_BATCH(0); /* XXX: Use this */ -- cgit v1.2.3 From 2754ac0878cbcfa13a4c16b8858500d812d9bb8a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Jun 2007 16:58:15 -0700 Subject: Replace intel_dump_batchbuffer with a more informational version. --- src/mesa/drivers/dri/i915tex/Makefile | 1 + src/mesa/drivers/dri/i915tex/i915_disasm.c | 617 +++++++++++++++++++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 23 +- 3 files changed, 619 insertions(+), 22 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/i915_disasm.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index c6a29149c7..eb704e1538 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -33,6 +33,7 @@ DRIVER_SOURCES = \ intel_pixel_draw.c \ intel_buffers.c \ intel_blit.c \ + i915_disasm.c \ i915_tex.c \ i915_texstate.c \ i915_context.c \ diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c new file mode 100644 index 0000000000..5e49df9e1c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -0,0 +1,617 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * 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, 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 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 + * + */ + +#include +#include +#include + +#include "i915_disasm.h" +#include "i915_reg.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +FILE *out; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect (%d)\n", len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect, %d starting from %d\n", + len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +i915_disasm(uint32_t *data, int count, uint32_t hw_offset) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 26eecb9440..1edbb618d3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -66,27 +66,6 @@ * modifying cliprects ??? */ -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint size) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", size / 4); - for (i = 0; i < size / 4; i += 4) { - char dw1[11], dw2[11] = "", dw3[11] = "", dw4[11] = ""; - - sprintf(dw1, "0x%08x", ptr[i]); - if (i + 1 < size / 4) - sprintf(dw2, "0x%08x", ptr[i + 1]); - if (i + 2 < size / 4) - sprintf(dw3, "0x%08x", ptr[i + 2]); - if (i + 3 < size / 4) - sprintf(dw4, "0x%08x", ptr[i + 3]); - fprintf(stderr, "0x%x:\t%s %s %s %s\n", offset + i * 4, - dw1, dw2, dw3, dw4); - } - fprintf(stderr, "END BATCH\n\n\n"); -} - /*====================================================================== * Public functions */ @@ -166,7 +145,7 @@ do_flush_locked(struct intel_batchbuffer *batch, } if (INTEL_DEBUG & DEBUG_BATCH) - intel_dump_batchbuffer(0, ptr, used); + i915_disasm(ptr, used / 4, 0); dri_bo_unmap(batch->buf); batch->map = 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') 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') 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 1a49cd7f5b22eb326b25bddf24a02f68b8150a8d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 09:49:24 -0700 Subject: Add missing i915_disasm.h header and adjust copyright formatting on the .c --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 6 +++--- src/mesa/drivers/dri/i915tex/i915_disasm.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/i915_disasm.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 5e49df9e1c..29db5763f0 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -17,9 +17,9 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 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. + * 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 diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.h b/src/mesa/drivers/dri/i915tex/i915_disasm.h new file mode 100644 index 0000000000..c74b036068 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.h @@ -0,0 +1,28 @@ +/* + * 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, 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 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 + * + */ + +int i915_disasm(uint32_t *data, int count, uint32_t hw_offset); -- 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') 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 f3f29d632e8a51914b87e087d6ab4d1d6f47b7d7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 12:53:07 -0700 Subject: Add decoding of inline primitives in debug output. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 138 ++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 11 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 29db5763f0..ebb634654f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -40,7 +40,9 @@ return count; \ } while (0) -FILE *out; +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; static float int_as_float(uint32_t intval) @@ -303,6 +305,17 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) if (data[0] & (1 << (4 + word))) { if (i >= count) BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + instr_out(data, hw_offset, i++, "S%d\n", word); } } @@ -437,17 +450,122 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, { char immediate = (data[0] & (1 << 23)) == 0; unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } /* XXX: 3DPRIM_DIB not supported */ if (immediate) { len = (data[0] & 0x0003ffff) + 2; - instr_out(data, hw_offset, 0, "3DPRIMITIVE inline\n"); + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); if (count < len) BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); - for (i = 1; i < len; i++) { - instr_out(data, hw_offset, i, - " vertex data (%f float)\n", - int_as_float(data[i])); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } } } else { /* indirect vertices */ @@ -459,7 +577,7 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, "3DPRIMITIVE random indirect"); } instr_out(data, hw_offset, 0, - "3DPRIMITIVE random indirect (%d)\n", len); + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); if (len == 0) { /* vertex indices continue until 0xffff is found */ for (i = 1; i < count; i++) { @@ -503,15 +621,13 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, if (count < 2) BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); instr_out(data, hw_offset, 0, - "3DPRIMITIVE sequential indirect, %d starting from %d\n", - len, data[1] & 0xffff); + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); instr_out(data, hw_offset, 1, " start\n"); return 2; } } - - return len; } -- cgit v1.2.3 From 5d9dc02cbecd94f822f853fd01878784596f4eba Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 12:57:15 -0700 Subject: Reset saved state for disasm when we've lost the context. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 7 +++++++ src/mesa/drivers/dri/i915tex/i915_disasm.h | 1 + src/mesa/drivers/dri/i915tex/intel_context.c | 3 +++ 3 files changed, 11 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index ebb634654f..6ac34a1480 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -731,3 +731,10 @@ i915_disasm(uint32_t *data, int count, uint32_t hw_offset) return failures; } + +void i915_disasm_context_reset() +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.h b/src/mesa/drivers/dri/i915tex/i915_disasm.h index c74b036068..5eb620f9a4 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.h +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.h @@ -26,3 +26,4 @@ */ int i915_disasm(uint32_t *data, int count, uint32_t hw_offset); +void i915_disasm_context_reset(); diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 696845a7fc..9d3f946830 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -59,6 +59,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" +#include "i915_disasm.h" #include "drirenderbuffer.h" #include "vblank.h" @@ -646,6 +647,8 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { sarea->texAge = intel->hHWContext; dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + if (INTEL_DEBUG & DEBUG_BATCH) + i915_disasm_context_reset(); } if (sarea->width != intelScreen->width || -- cgit v1.2.3 From 23e0ca2ebb0d123c7a40bb8b3687adb407c95504 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jul 2007 13:56:38 -0700 Subject: Fix copy'n'pasteo that broke display lists. --- src/mesa/drivers/dri/i915tex/intel_buffer_objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 1b95bfd47a..3c73c402d9 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -185,7 +185,7 @@ intel_bufferobj_get_subdata(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - dri_bo_subdata(intel_obj->buffer, offset, size, data); + dri_bo_get_subdata(intel_obj->buffer, offset, size, data); } -- 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') 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') 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') 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 5e2acfee78c9e72d67d822974e9986fe99920ccf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 31 Jul 2007 09:21:20 -0700 Subject: Don't initialize extensions we can't support when !ttm. --- src/mesa/drivers/dri/i915tex/intel_context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index cd4333d0d3..3eb58bdd9c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -177,7 +177,6 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_mirrored_repeat", NULL}, {"GL_ARB_texture_rectangle", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, @@ -188,7 +187,6 @@ const struct dri_extension card_extensions[] = { {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, #if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, @@ -211,6 +209,12 @@ const struct dri_extension card_extensions[] = { {NULL, NULL} }; +const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; + extern const struct tnl_pipeline_stage _intel_render_stage; static const struct tnl_pipeline_stage *intel_pipeline[] = { @@ -468,6 +472,9 @@ intelInitContext(struct intel_context *intel, /* GL_TRUE, */ GL_FALSE); + if (intelScreen->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; -- 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') 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 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') 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 327e6551197e6069150200878b4e6e7a595e2bee Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:28:12 -0700 Subject: Add decode for XY_COLOR_BLT and XY_SRC_COPY_BLT. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 87 +++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 6ac34a1480..292b6e3a3b 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -134,7 +134,8 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) static int decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) { - unsigned int opcode; + unsigned int opcode, len; + char *format; struct { uint32_t opcode; @@ -169,11 +170,93 @@ decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, }; + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); opcode++) { if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { - unsigned int len = 1, i; + unsigned int i; + len = 1; instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); if (opcodes_2d[opcode].max_len > 1) { len = (data[0] & 0x000000ff) + 2; -- 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') 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') 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 b6ad5e7de8dc84ee42eeeb62d2112f096413b335 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:36:35 -0700 Subject: Move i915_disasm to later so we can use the hardware offset. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 1edbb618d3..5aabef96ae 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -27,6 +27,7 @@ #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "i915_disasm.h" /* Relocations in kernel space: * - pass dma buffer seperately @@ -144,9 +145,6 @@ do_flush_locked(struct intel_batchbuffer *batch, dri_bo_unreference(r->buf); } - if (INTEL_DEBUG & DEBUG_BATCH) - i915_disasm(ptr, used / 4, 0); - dri_bo_unmap(batch->buf); batch->map = NULL; batch->ptr = NULL; @@ -196,6 +194,12 @@ do_flush_locked(struct intel_batchbuffer *batch, } intel->vtbl.lost_hardware(intel); } + + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + i915_disasm(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } } -- 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') 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') 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') 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') 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 c1ecc383204914567c6de1587d7b9559ec72ce6e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 11:41:25 -0700 Subject: Uniquely validate the batchbuffer-referenced buffers. Otherwise, for multiple references by the batchbuffer, the kernel would see the buffer already on the unfenced list and wait for it to leave the list before continuing, leading to hanging and eventual -EBUSY. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 47 +++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 5515d6c235..8ee48b5a68 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -116,6 +116,14 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch) free(batch); } +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + /* TODO: Push this whole function into bufmgr. */ static void @@ -132,13 +140,49 @@ do_flush_locked(struct intel_batchbuffer *batch, assert(batch->buf->virtual != NULL); ptr = batch->buf->virtual; + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ for (i = 0; i < batch->nr_relocs; i++) { struct buffer_reloc *r = &batch->reloc[i]; if (r->validate_flags & DRM_BO_FLAG_WRITE) performed_rendering = GL_TRUE; - dri_bo_validate(r->buf, r->validate_flags); + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } ptr[r->offset / 4] = r->buf->offset + r->delta; dri_bo_unreference(r->buf); } @@ -193,6 +237,7 @@ do_flush_locked(struct intel_batchbuffer *batch, intel->vtbl.lost_hardware(intel); } +done: if (INTEL_DEBUG & DEBUG_BATCH) { dri_bo_map(batch->buf, GL_FALSE); intel_decode(ptr, used / 4, batch->buf->offset); -- 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') 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