dri: remove ttm common code since superioctl is device specific
authorDave Airlie <airlied@redhat.com>
Fri, 12 Oct 2007 00:59:38 +0000 (10:59 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 12 Oct 2007 00:59:38 +0000 (10:59 +1000)
src/mesa/drivers/dri/common/dri_bufmgr_ttm.c [deleted file]

diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
deleted file mode 100644 (file)
index 84ac0b2..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-/**************************************************************************
- * 
- * 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"
-
-#define BUFMGR_DEBUG 0
-#define MAX_RELOCS 4096
-
-struct ttm_buffer_reloc
-{
-   dri_bo *buf;
-   GLuint offset;
-   GLuint delta;                /* not needed? */
-   GLuint validate_flags;
-};
-
-typedef struct _dri_bufmgr_ttm {
-   dri_bufmgr bufmgr;
-
-   int fd;
-   _glthread_Mutex mutex;
-   unsigned int fence_type;
-   unsigned int fence_type_flush;
-
-   /** ttm relocation list */
-   struct ttm_buffer_reloc reloc[MAX_RELOCS];
-   GLuint nr_relocs;
-   GLboolean performed_rendering;
-
-} dri_bufmgr_ttm;
-
-typedef struct _dri_bo_ttm {
-   dri_bo bo;
-
-   int refcount;               /* Protected by bufmgr->mutex */
-   drmBO drm_bo;
-   const char *name;
-   /**
-    * Note whether we are the owner of the buffer, to determine if we must
-    * drmBODestroy or drmBOUnreference to unreference the buffer.
-    */
-   GLboolean owner;
-} dri_bo_ttm;
-
-typedef struct _dri_fence_ttm
-{
-   dri_fence fence;
-
-   int refcount;               /* Protected by bufmgr->mutex */
-   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 location_mask)
-{
-   dri_bufmgr_ttm *ttm_bufmgr;
-   dri_bo_ttm *ttm_buf;
-   unsigned int pageSize = getpagesize();
-   int ret;
-   unsigned int flags, hint;
-
-   ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
-
-   ttm_buf = malloc(sizeof(*ttm_buf));
-   if (!ttm_buf)
-      return NULL;
-
-   /* The mask argument doesn't do anything for us that we want other than
-    * determine which pool (TTM or local) the buffer is allocated into, so just
-    * pass all of the allocation class flags.
-    */
-   flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
-      DRM_BO_FLAG_EXE;
-   /* No hints we want to use. */
-   hint = 0;
-
-   ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize,
-                    NULL, drm_bo_type_dc,
-                     flags, hint, &ttm_buf->drm_bo);
-   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->name = name;
-   ttm_buf->refcount = 1;
-   ttm_buf->owner = GL_TRUE;
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
-   return &ttm_buf->bo;
-}
-
-/* Our TTM backend doesn't allow creation of static buffers, as that requires
- * privelege for the non-fake case, and the lock in the fake case where we were
- * working around the X Server not creating buffers and passing handles to us.
- */
-static dri_bo *
-dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
-                    unsigned long offset, unsigned long size, void *virtual,
-                    unsigned int location_mask)
-{
-   return NULL;
-}
-
-/** Returns a dri_bo wrapping the given buffer object handle.
- *
- * This can be used when one application needs to pass a buffer object
- * to another.
- */
-dri_bo *
-dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
-                             unsigned int handle)
-{
-   dri_bufmgr_ttm *ttm_bufmgr;
-   dri_bo_ttm *ttm_buf;
-   int ret;
-
-   ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
-
-   ttm_buf = malloc(sizeof(*ttm_buf));
-   if (!ttm_buf)
-      return NULL;
-
-   ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
-   if (ret != 0) {
-      free(ttm_buf);
-      return NULL;
-   }
-   ttm_buf->bo.size = ttm_buf->drm_bo.size;
-   ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
-   ttm_buf->bo.virtual = NULL;
-   ttm_buf->bo.bufmgr = bufmgr;
-   ttm_buf->name = name;
-   ttm_buf->refcount = 1;
-   ttm_buf->owner = GL_FALSE;
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo,
-          ttm_buf->name);
-#endif
-
-   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) {
-      int ret;
-
-      /* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead
-       * of simply unreferencing is madness, and leads to behaviors we may not
-       * want (making the buffer unsharable).
-       */
-      if (ttm_buf->owner)
-        ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo);
-      else
-        ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
-      if (ret != 0) {
-        fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name,
-                strerror(-ret));
-      }
-#if BUFMGR_DEBUG
-      fprintf(stderr, "bo_unreference final: %p (%s)\n",
-             &ttm_buf->bo, ttm_buf->name);
-#endif
-      _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-      free(buf);
-      return;
-   }
-   _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;
-
-   assert(buf->virtual == NULL);
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
-   return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
-}
-
-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;
-
-   assert(buf->virtual != NULL);
-
-   buf->virtual = NULL;
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
-   return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
-}
-
-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, 0, flags, mask, 0);
-
-   if (err == 0) {
-      /* XXX: add to fence list for sanity checking */
-   } else {
-      fprintf(stderr, "failed to validate buffer (%s): %s\n",
-             ttm_buf->name, strerror(-err));
-   }
-
-   buf->offset = ttm_buf->drm_bo.offset;
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
-#endif
-
-   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->fence.bufmgr = bufmgr;
-   ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence);
-   if (ret) {
-      fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret));
-      free(fence_ttm);
-      return NULL;
-   }
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence,
-          fence_ttm->name);
-#endif
-
-   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) {
-      int ret;
-
-      /* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers
-       * instead of simply unreferencing is madness, and leads to behaviors we
-       * may not want (making the fence unsharable).  This behavior by the DRM
-       * ioctls should be fixed, and drmFenceDestroy eliminated.
-       */
-      ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence);
-      if (ret != 0) {
-        fprintf(stderr, "drmFenceDestroy failed (%s): %s\n",
-                fence_ttm->name, strerror(-ret));
-      }
-
-      _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-      free(fence);
-      return;
-   }
-   _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, 0);
-   _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
-   if (ret != 0) {
-      _mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
-                  __FILE__, __LINE__, ret, fence_ttm->name);
-      abort();
-   }
-
-#if BUFMGR_DEBUG
-   fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
-          fence_ttm->name);
-#endif
-}
-
-static void
-dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
-{
-   dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
-
-   _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
-   free(bufmgr);
-}
-
-
-static void
-dri_ttm_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
-                   dri_bo *relocatee)
-{
-   dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
-   struct ttm_buffer_reloc *r = &bufmgr_ttm->reloc[bufmgr_ttm->nr_relocs++];
-   
-   assert(bufmgr_ttm->nr_relocs <= MAX_RELOCS);
-
-   dri_bo_reference(relocatee);
-
-   r->buf = relocatee;
-   r->offset = offset;
-   r->delta = delta;
-   r->validate_flags = flags;
-
-   return;
-}
-
-
-static int
-relocation_sort(const void *a_in, const void *b_in) {
-   const struct ttm_buffer_reloc *a = a_in, *b = b_in;
-
-   return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
-}
-
-static void *
-dri_ttm_process_reloc(dri_bo *batch_buf)
-{
-   dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
-   GLuint i;
-   GLuint *ptr;
-
-   assert(batch_buf->virtual != NULL);
-   ptr = batch_buf->virtual;
-
-   bufmgr_ttm->performed_rendering = GL_FALSE;
-
-   /* Sort our relocation list in terms of referenced buffer pointer.
-    * This lets us uniquely validate the buffers with the sum of all the flags,
-    * while avoiding O(n^2) on number of relocations.
-    */
-   qsort(bufmgr_ttm->reloc, bufmgr_ttm->nr_relocs, sizeof(bufmgr_ttm->reloc[0]),
-        relocation_sort);
-
-   /* Perform the necessary validations of buffers, and enter the relocations
-    * in the batchbuffer.
-    */
-   for (i = 0; i < bufmgr_ttm->nr_relocs; i++) {
-      struct ttm_buffer_reloc *r = &bufmgr_ttm->reloc[i];
-
-      if (r->validate_flags & DRM_BO_FLAG_WRITE)
-        bufmgr_ttm->performed_rendering = GL_TRUE;
-
-      /* If this is the first time we've seen this buffer in the relocation
-       * list, figure out our flags and validate it.
-       */
-      if (i == 0 || bufmgr_ttm->reloc[i - 1].buf != r->buf) {
-        uint32_t validate_flags;
-        int j, ret;
-
-        /* Accumulate the flags we need for validating this buffer. */
-        validate_flags = r->validate_flags;
-        for (j = i + 1; j < bufmgr_ttm->nr_relocs; j++) {
-           if (bufmgr_ttm->reloc[j].buf != r->buf)
-              break;
-           validate_flags |= bufmgr_ttm->reloc[j].validate_flags;
-        }
-
-        /* Validate.  If we fail, fence to clear the unfenced list and bail
-         * out.
-         */
-        ret = dri_bo_validate(r->buf, validate_flags);
-        if (ret != 0) {
-           dri_fence *fo;
-           dri_bo_unmap(batch_buf);
-           fo = dri_fence_validated(batch_buf->bufmgr,
-                                    "batchbuffer failure fence", GL_TRUE);
-           dri_fence_unreference(fo);
-           goto done;
-        }
-      }
-      ptr[r->offset / 4] = r->buf->offset + r->delta;
-      dri_bo_unreference(r->buf);
-   }
-   dri_bo_unmap(batch_buf);
-
-   dri_bo_validate(batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
-
-   bufmgr_ttm->nr_relocs = 0;
- done:
-   return NULL;
-}
-
-static void
-dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
-{
-   dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
-   dri_fence *fo;
-
-   fo = dri_fence_validated(batch_buf->bufmgr, "Batch fence", GL_TRUE);
-
-   if (bufmgr_ttm->performed_rendering) {
-      dri_fence_unreference(*last_fence);
-      *last_fence = fo;
-   } else {
-      dri_fence_unreference(fo);
-   }
-}
-
-/**
- * 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;
-   bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
-   bufmgr_ttm->bufmgr.emit_reloc = dri_ttm_emit_reloc;
-   bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
-   bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;   
-   return &bufmgr_ttm->bufmgr;
-}