diff options
Diffstat (limited to 'src/mesa')
34 files changed, 1786 insertions, 1222 deletions
| diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 6f2314ee8c..49c366ea41 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 eaa4fb09c7..154e7841a0 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -1,499 +1,134 @@ -/************************************************************************** - *  - * 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 <eric@anholt.net>   * - * 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 <thomas-at-tungstengraphics-dot-com> - *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>   */ -#include <xf86drm.h> -#include <stdlib.h> -#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) -{ -    unsigned ret; - -    _glthread_LOCK_MUTEX(bmMutex); -    ret = fence->fence.flags; -    _glthread_UNLOCK_MUTEX(bmMutex); -     -    return ret; -} - - -DriFenceObject * -driFenceReference(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)  { -   _glthread_LOCK_MUTEX(bmMutex); -   ++fence->refCount; -   _glthread_UNLOCK_MUTEX(bmMutex); -   return fence; +   return bufmgr->bo_alloc(bufmgr, name, size, alignment, flags, hint);  } -void -driFenceUnReference(DriFenceObject * fence) -{ -   if (!fence) -      return; - -   _glthread_LOCK_MUTEX(bmMutex); -   if (--fence->refCount == 0) { -      drmFenceDestroy(fence->fd, &fence->fence); -      free(fence); -   } -   _glthread_UNLOCK_MUTEX(bmMutex); -} - -void -driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) -{ -   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); -} - -int -driFenceSignaled(DriFenceObject * fence, unsigned type) +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)  { -   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) -{ -   struct _DriBufferPool *pool; -   void *priv; - -   _glthread_LOCK_MUTEX(buf->mutex); -   pool = buf->pool; -   priv = buf->private; -   _glthread_UNLOCK_MUTEX(buf->mutex); -    -   assert(priv != NULL); -   BM_CKFATAL(buf->pool->waitIdle(pool, priv, lazy)); -} - -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; +   return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, +				  flags, hint);  }  void -driBOUnmap(struct _DriBufferObject *buf) +dri_bo_reference(dri_bo *bo)  { -   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; +   bo->bufmgr->bo_reference(bo);  }  void -driBOUnReference(struct _DriBufferObject *buf) +dri_bo_unreference(dri_bo *bo)  { -   int tmp; - -   if (!buf) +   if (bo == NULL)        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, DRM_BO_HINT_DONT_FENCE,  -				  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); +   bo->bufmgr->bo_unreference(bo);  } -void -driBOSetStatic(struct _DriBufferObject *buf, -               unsigned long offset, -               unsigned long size, void *virtual, unsigned flags) +int +dri_bo_map(dri_bo *buf, GLboolean write_enable)  { -   _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); +   return buf->bufmgr->bo_map(buf, write_enable);  } - - -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 +dri_bo_validate(dri_bo *buf, unsigned int flags)  { -   int i; - -   for (i = 0; i < n; ++i) { -      driBOUnReference(buffers[i]); -   } +   return buf->bufmgr->bo_validate(buf, flags);  } - -void -driInitBufMgr(int fd) +dri_fence * +dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed)  { -   ; +   return bufmgr->fence_validated(bufmgr, name, flushed);  } -  void -driBOCreateList(int target, drmBOList * list) +dri_fence_wait(dri_fence *fence)  { -   _glthread_LOCK_MUTEX(bmMutex); -   BM_CKFATAL(drmBOCreateList(target, list)); -   _glthread_UNLOCK_MUTEX(bmMutex); +   fence->bufmgr->fence_wait(fence);  }  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)); -   } +   if (fence == NULL) +      return; -   _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) +dri_bo_get_subdata(dri_bo *bo, unsigned long offset, +		   unsigned long size, void *data)  { -   _glthread_LOCK_MUTEX(bmMutex); -   BM_CKFATAL(drmBOValidateList(fd, list)); -   _glthread_UNLOCK_MUTEX(bmMutex); -} - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ -   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..62ed9d3821 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,72 +29,174 @@  /*   * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>   *          Keith Whitwell <keithw-at-tungstengraphics-dot-com> + *	    Eric Anholt <eric@anholt.net>   */  #ifndef _DRI_BUFMGR_H_  #define _DRI_BUFMGR_H_  #include <xf86drm.h> +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); + +   /** +    * 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. +    */ +}; + +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_wait(dri_fence *fence); +void dri_fence_reference(dri_fence *fence); +void dri_fence_unreference(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); -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); -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); +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); -extern void driBOFence(struct _DriBufferObject *buf, -                       struct _DriFenceObject *fence); +dri_bufmgr *dri_bufmgr_ttm_init(int fd, unsigned int fence_type, +				unsigned int fence_type_flush); -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); +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..daa09cc5cd --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -0,0 +1,874 @@ +/************************************************************************** + *  + * 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 - bufmgr_fake->low_offset; +   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, 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_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; + +   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, 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 = 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); + +   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; + +   bufmgr_fake->fence_emit = fence_emit; +   bufmgr_fake->fence_wait = fence_wait; +   bufmgr_fake->driver_priv = driver_priv; + +   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 <thomas-at-tungstengraphics-dot-com> + *          Keith Whitwell <keithw-at-tungstengraphics-dot-com> + *	    Eric Anholt <eric@anholt.net> + */ + +#include <xf86drm.h> +#include <stdlib.h> +#include <unistd.h> +#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 <thomas-at-tungstengraphics-dot-com> - */ - -#ifndef _DRI_BUFPOOL_H_ -#define _DRI_BUFPOOL_H_ - -#include <xf86drm.h> -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 878a148b39..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 <thomas-at-tungstengraphics-dot-com> - */ - -#include <xf86drm.h> -#include <stdlib.h> -#include <unistd.h> -#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, DRM_BO_HINT_DONT_FENCE, 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; -} diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index b218929dce..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 @@ -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..67fca371a7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -77,65 +77,38 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count)     fprintf(stderr, "END BATCH\n\n\n");  } +/*====================================================================== + * Public functions + */  void  intel_batchbuffer_reset(struct intel_batchbuffer *batch)  { +   struct intel_context *intel = batch->intel; -   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); +   if (batch->buf != NULL) { +      dri_bo_unreference(batch->buf); +      batch->buf = NULL;     } -   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->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;  } -/*====================================================================== - * Public functions - */  struct intel_batchbuffer *  intel_batchbuffer_alloc(struct intel_context *intel)  {     struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);     batch->intel = intel; - -   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 +116,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 +139,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 +176,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 +211,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 +219,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 +236,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 +251,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 +266,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..82a3d49fca 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -16,18 +16,18 @@ struct intel_context;  struct buffer_reloc  { -   struct _DriBufferObject *buf; +   dri_bo *buf;     GLuint offset;     GLuint delta;                /* not needed? */ +   GLuint validate_flags;  };  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 +48,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 +64,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 +111,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_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index dbe4ba2ac5..5d97f08434 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); +      intel->first_swap_fence = intel->batch->last_fence; +      dri_fence_reference(intel->first_swap_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 91c45ad95b..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,17 +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); -   LOCK_HARDWARE(intel); -   driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0); -   UNLOCK_HARDWARE(intel); +   dri_bo_unreference(intel_obj->buffer); +   intel_obj->buffer = NULL;  }  /* Break the COW tie to the region.  Both the pbo and the region end @@ -109,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); @@ -139,9 +136,15 @@ intel_bufferobj_data(GLcontext * ctx,     if (intel_obj->region)        intel_bufferobj_release_region(intel, intel_obj); -   LOCK_HARDWARE(intel); -   driBOData(intel_obj->buffer, size, data, 0); -   UNLOCK_HARDWARE(intel); +   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);  } @@ -166,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);  } @@ -183,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);  } @@ -206,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;  } @@ -222,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 20b2b41ef2..4f58f56ada 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -302,9 +302,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); @@ -346,15 +345,7 @@ intelInitContext(struct intel_context *intel,     drmI830Sarea *saPriv = (drmI830Sarea *)        (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset);     int fthrottle_mode; -   GLboolean havePools; -   DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); -   havePools = intelCreatePools(intelScreen); -   DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - -   if (!havePools) -      return GL_FALSE; -          if (!_mesa_initialize_context(&intel->ctx,                                   mesaVis, shareCtx,                                   functions, (void *) intel)) @@ -448,7 +439,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 && @@ -521,13 +511,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;        } @@ -671,14 +661,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..e75dd64fe1 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; @@ -216,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; @@ -256,7 +250,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 7d19bd07d3..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,19 +87,16 @@ 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)  {     struct intel_region *region = calloc(sizeof(*region), 1); -   struct intel_context *intel = intelScreenContext(intelScreen);     DBG("%s\n", __FUNCTION__); @@ -99,18 +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); -   LOCK_HARDWARE(intel); -   driBOData(region->buffer, pitch * cpp * height, NULL, 0); -   UNLOCK_HARDWARE(intel); +   region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", +				 pitch * cpp * height, 64, 0, 0);     return region;  } @@ -141,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; @@ -163,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;  } @@ -198,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);  } @@ -379,37 +373,33 @@ 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,                           struct intel_region *region)  { -   struct intel_context *intel = intelScreenContext(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); -    -   LOCK_HARDWARE(intel); -   driBOData(region->buffer, -             region->cpp * region->pitch * region->height, NULL, 0); -   UNLOCK_HARDWARE(intel); +   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 @@ -465,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 dd01161b5b..0005cfad9d 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, @@ -386,45 +418,6 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,        intelPrintSAREA(sarea);  } -GLboolean -intelCreatePools(intelScreenPrivate *intelScreen) -{ -   unsigned batchPoolSize = 1024*1024; -   __DRIscreenPrivate * sPriv = intelScreen->driScrnPriv; - -   if (intelScreen->havePools) -      return GL_TRUE; - -   batchPoolSize /= intelScreen->maxBatchSize; -   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; -   } -    -   intel_recreate_static_regions(intelScreen); -   intelScreen->havePools = GL_TRUE; - -   return GL_TRUE; -} -  static GLboolean  intelInitDriver(__DRIscreenPrivate * sPriv) @@ -460,10 +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; +   else +      intelScreen->maxBatchSize = BATCH_SZ;     intelScreen->mem = gDRIPriv->mem;     intelScreen->cpp = gDRIPriv->cpp; @@ -489,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) @@ -554,6 +530,22 @@ 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_fake_init(intelScreen->tex.offset, +						 intelScreen->tex.map, +						 intelScreen->tex.size, +						 intel_fence_emit, +						 intel_fence_wait, +						 intelScreen); +   } + +   intel_recreate_static_regions(intelScreen); +     return GL_TRUE;  } @@ -565,11 +557,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv)     intelUnmapScreenRegions(intelScreen); -   if (intelScreen->havePools) { -      driPoolTakeDown(intelScreen->regionPool); -      driPoolTakeDown(intelScreen->staticPool); -      driPoolTakeDown(intelScreen->batchPool); -   } +   /* XXX: bufmgr teardown */     FREE(intelScreen);     sPriv->private = NULL;  } @@ -891,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; diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index bac43aaddd..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,12 +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; -   GLboolean havePools; + +   /** +    * This value indicates that the kernel memory manager is being used +    * instead of the fake client-side memory manager. +    */ +   GLboolean ttm;  } intelScreenPrivate; @@ -122,16 +125,9 @@ 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  intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); -extern GLboolean -intelCreatePools(intelScreenPrivate *intelScreen);  #endif 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);   } | 
