WIP 965 conversion to dri_bufmgr.
authorEric Anholt <eric@anholt.net>
Thu, 27 Sep 2007 17:16:04 +0000 (10:16 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 27 Sep 2007 18:15:51 +0000 (11:15 -0700)
28 files changed:
src/mesa/drivers/dri/i915/Makefile
src/mesa/drivers/dri/i915/intel_batchbuffer.c [deleted file]
src/mesa/drivers/dri/i915/intel_batchbuffer.h [deleted file]
src/mesa/drivers/dri/i965/Makefile
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/brw_state_pool.c
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_wm_state.c
src/mesa/drivers/dri/i965/bufmgr.h [deleted file]
src/mesa/drivers/dri/i965/bufmgr_fake.c [deleted file]
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_batchbuffer.h
src/mesa/drivers/dri/i965/intel_blit.c
src/mesa/drivers/dri/i965/intel_blit.h
src/mesa/drivers/dri/i965/intel_buffer_objects.c
src/mesa/drivers/dri/i965/intel_buffer_objects.h
src/mesa/drivers/dri/i965/intel_context.c
src/mesa/drivers/dri/i965/intel_ioctl.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_regions.c
src/mesa/drivers/dri/i965/intel_regions.h
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/intel_screen.h
src/mesa/drivers/dri/i965/intel_tex_layout.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex_validate.c
src/mesa/drivers/dri/intel/intel_batchbuffer.c [new file with mode: 0644]
src/mesa/drivers/dri/intel/intel_batchbuffer.h [new file with mode: 0644]

index d3d0bd570c154e52d6a238996c7ef45f15148b31..0e2cdcb24007d3219e4f9e4861b332f057e9f04f 100644 (file)
@@ -66,6 +66,7 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \
 
 include ../Makefile.template
 
+intel_batchbuffer.o: ../intel/intel_batchbuffer.o
 intel_tex_layout.o: ../intel/intel_tex_layout.c
 
 symlinks:
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
deleted file mode 100644 (file)
index 8ee48b5..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/**************************************************************************
- * 
- * 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.
- * 
- **************************************************************************/
-
-#include "intel_batchbuffer.h"
-#include "intel_ioctl.h"
-#include "intel_decode.h"
-#include "i915_debug.h"
-
-/* Relocations in kernel space:
- *    - pass dma buffer seperately
- *    - memory manager knows how to patch
- *    - pass list of dependent buffers
- *    - pass relocation list
- *
- * Either:
- *    - get back an offset for buffer to fire
- *    - memory manager knows how to fire buffer
- *
- * Really want the buffer to be AGP and pinned.
- *
- */
-
-/* Cliprect fence: The highest fence protecting a dma buffer
- * containing explicit cliprect information.  Like the old drawable
- * lock but irq-driven.  X server must wait for this fence to expire
- * before changing cliprects [and then doing sw rendering?].  For
- * other dma buffers, the scheduler will grab current cliprect info
- * and mix into buffer.  X server must hold the lock while changing
- * cliprects???  Make per-drawable.  Need cliprects in shared memory
- * -- beats storing them with every cmd buffer in the queue.
- *
- * ==> X server must wait for this fence to expire before touching the
- * framebuffer with new cliprects.
- *
- * ==> Cliprect-dependent buffers associated with a
- * cliprect-timestamp.  All of the buffers associated with a timestamp
- * must go to hardware before any buffer with a newer timestamp.
- *
- * ==> Dma should be queued per-drawable for correct X/GL
- * synchronization.  Or can fences be used for this?
- *
- * Applies to: Blit operations, metaops, X server operations -- X
- * server automatically waits on its own dma to complete before
- * modifying cliprects ???
- */
-
-void
-intel_batchbuffer_reset(struct intel_batchbuffer *batch)
-{
-   struct intel_context *intel = batch->intel;
-
-   if (batch->buf != NULL) {
-      dri_bo_unreference(batch->buf);
-      batch->buf = NULL;
-   }
-
-   batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer",
-                            intel->intelScreen->maxBatchSize, 4096,
-                            DRM_BO_FLAG_MEM_TT);
-   dri_bo_map(batch->buf, GL_TRUE);
-   batch->map = batch->buf->virtual;
-   batch->size = intel->intelScreen->maxBatchSize;
-   batch->ptr = batch->map;
-}
-
-struct intel_batchbuffer *
-intel_batchbuffer_alloc(struct intel_context *intel)
-{
-   struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
-
-   batch->intel = intel;
-   batch->last_fence = NULL;
-   intel_batchbuffer_reset(batch);
-
-   return batch;
-}
-
-void
-intel_batchbuffer_free(struct intel_batchbuffer *batch)
-{
-   if (batch->last_fence) {
-      dri_fence_wait(batch->last_fence);
-      dri_fence_unreference(batch->last_fence);
-      batch->last_fence = NULL;
-   }
-   if (batch->map) {
-      dri_bo_unmap(batch->buf);
-      batch->map = NULL;
-   }
-   dri_bo_unreference(batch->buf);
-   batch->buf = NULL;
-   free(batch);
-}
-
-static int
-relocation_sort(const void *a_in, const void *b_in) {
-   const struct buffer_reloc *a = a_in, *b = b_in;
-
-   return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
-}
-
-
-/* TODO: Push this whole function into bufmgr.
- */
-static void
-do_flush_locked(struct intel_batchbuffer *batch,
-                GLuint used,
-                GLboolean ignore_cliprects, GLboolean allow_unlock)
-{
-   GLuint *ptr;
-   GLuint i;
-   struct intel_context *intel = batch->intel;
-   dri_fence *fo;
-   GLboolean performed_rendering = GL_FALSE;
-
-   assert(batch->buf->virtual != NULL);
-   ptr = batch->buf->virtual;
-
-   /* Sort our relocation list in terms of referenced buffer pointer.
-    * This lets us uniquely validate the buffers with the sum of all the flags,
-    * while avoiding O(n^2) on number of relocations.
-    */
-   qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]),
-        relocation_sort);
-
-   /* Perform the necessary validations of buffers, and enter the relocations
-    * in the batchbuffer.
-    */
-   for (i = 0; i < batch->nr_relocs; i++) {
-      struct buffer_reloc *r = &batch->reloc[i];
-
-      if (r->validate_flags & DRM_BO_FLAG_WRITE)
-        performed_rendering = GL_TRUE;
-
-      /* If this is the first time we've seen this buffer in the relocation
-       * list, figure out our flags and validate it.
-       */
-      if (i == 0 || batch->reloc[i - 1].buf != r->buf) {
-        uint32_t validate_flags;
-        int j, ret;
-
-        /* Accumulate the flags we need for validating this buffer. */
-        validate_flags = r->validate_flags;
-        for (j = i + 1; j < batch->nr_relocs; j++) {
-           if (batch->reloc[j].buf != r->buf)
-              break;
-           validate_flags |= batch->reloc[j].validate_flags;
-        }
-
-        /* Validate.  If we fail, fence to clear the unfenced list and bail
-         * out.
-         */
-        ret = dri_bo_validate(r->buf, validate_flags);
-        if (ret != 0) {
-           dri_bo_unmap(batch->buf);
-           fo = dri_fence_validated(intel->intelScreen->bufmgr,
-                                    "batchbuffer failure fence", GL_TRUE);
-           dri_fence_unreference(fo);
-           goto done;
-        }
-      }
-      ptr[r->offset / 4] = r->buf->offset + r->delta;
-      dri_bo_unreference(r->buf);
-   }
-
-   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
-    * single buffer.
-    */
-
-   if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
-      intel_batch_ioctl(batch->intel,
-                        batch->buf->offset,
-                        used, ignore_cliprects, allow_unlock);
-   }
-
-   /* 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);
-
-   if (performed_rendering) {
-      dri_fence_unreference(batch->last_fence);
-      batch->last_fence = 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);
-      }
-      intel->vtbl.lost_hardware(intel);
-   }
-
-done:
-   if (INTEL_DEBUG & DEBUG_BATCH) {
-      dri_bo_map(batch->buf, GL_FALSE);
-      intel_decode(ptr, used / 4, batch->buf->offset);
-      dri_bo_unmap(batch->buf);
-   }
-}
-
-
-void
-intel_batchbuffer_flush(struct intel_batchbuffer *batch)
-{
-   struct intel_context *intel = batch->intel;
-   GLuint used = batch->ptr - batch->map;
-   GLboolean was_locked = intel->locked;
-
-   if (used == 0)
-      return;
-
-   /* Add the MI_BATCH_BUFFER_END.  Always add an MI_FLUSH - this is a
-    * performance drain that we would like to avoid.
-    */
-   if (used & 4) {
-      ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
-      ((int *) batch->ptr)[1] = 0;
-      ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END;
-      used += 12;
-   }
-   else {
-      ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
-      ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END;
-      used += 8;
-   }
-
-   /* TODO: Just pass the relocation list and dma buffer up to the
-    * kernel.
-    */
-   if (!was_locked)
-      LOCK_HARDWARE(intel);
-
-   do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
-                  GL_FALSE);
-
-   if (!was_locked)
-      UNLOCK_HARDWARE(intel);
-
-   /* Reset the buffer:
-    */
-   intel_batchbuffer_reset(batch);
-}
-
-void
-intel_batchbuffer_finish(struct intel_batchbuffer *batch)
-{
-   intel_batchbuffer_flush(batch);
-   if (batch->last_fence != NULL)
-      dri_fence_wait(batch->last_fence);
-}
-
-
-/*  This is the only way buffers get added to the validate list.
- */
-GLboolean
-intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
-                             dri_bo *buffer,
-                             GLuint flags, GLuint delta)
-{
-   struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
-
-   assert(batch->nr_relocs <= MAX_RELOCS);
-
-   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;
-}
-
-
-
-void
-intel_batchbuffer_data(struct intel_batchbuffer *batch,
-                       const void *data, GLuint bytes, GLuint flags)
-{
-   assert((bytes & 3) == 0);
-   intel_batchbuffer_require_space(batch, bytes, flags);
-   __memcpy(batch->ptr, data, bytes);
-   batch->ptr += bytes;
-}
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h
deleted file mode 100644 (file)
index 850a91e..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef INTEL_BATCHBUFFER_H
-#define INTEL_BATCHBUFFER_H
-
-#include "mtypes.h"
-#include "dri_bufmgr.h"
-
-struct intel_context;
-
-#define BATCH_SZ 16384
-#define BATCH_RESERVED 16
-
-#define MAX_RELOCS 4096
-
-#define INTEL_BATCH_NO_CLIPRECTS 0x1
-#define INTEL_BATCH_CLIPRECTS    0x2
-
-struct buffer_reloc
-{
-   dri_bo *buf;
-   GLuint offset;
-   GLuint delta;                /* not needed? */
-   GLuint validate_flags;
-};
-
-struct intel_batchbuffer
-{
-   struct intel_context *intel;
-
-   dri_bo *buf;
-   dri_fence *last_fence;
-   GLuint flags;
-
-   drmBOList list;
-   GLuint list_count;
-   GLubyte *map;
-   GLubyte *ptr;
-
-   struct buffer_reloc reloc[MAX_RELOCS];
-   GLuint nr_relocs;
-   GLuint size;
-};
-
-struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
-                                                  *intel);
-
-void intel_batchbuffer_free(struct intel_batchbuffer *batch);
-
-
-void intel_batchbuffer_finish(struct intel_batchbuffer *batch);
-
-void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
-
-void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
-
-
-/* Unlike bmBufferData, this currently requires the buffer be mapped.
- * Consider it a convenience function wrapping multple
- * intel_buffer_dword() calls.
- */
-void intel_batchbuffer_data(struct intel_batchbuffer *batch,
-                            const void *data, GLuint bytes, GLuint flags);
-
-void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
-                                     GLuint bytes);
-
-GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
-                                       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
- * be passed as structs rather than dwords, but that's a little bit of
- * work...
- */
-static INLINE GLuint
-intel_batchbuffer_space(struct intel_batchbuffer *batch)
-{
-   return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
-}
-
-
-static INLINE void
-intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
-{
-   assert(batch->map);
-   assert(intel_batchbuffer_space(batch) >= 4);
-   *(GLuint *) (batch->ptr) = dword;
-   batch->ptr += 4;
-}
-
-static INLINE void
-intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
-                                GLuint sz, GLuint flags)
-{
-   assert(sz < batch->size - 8);
-   if (intel_batchbuffer_space(batch) < sz ||
-       (batch->flags != 0 && flags != 0 && batch->flags != flags))
-      intel_batchbuffer_flush(batch);
-
-   batch->flags |= flags;
-}
-
-/* Here are the crusty old macros, to be removed:
- */
-#define BATCH_LOCALS
-
-#define BEGIN_BATCH(n, flags) do {                             \
-   assert(!intel->prim.flush);                                 \
-   intel_batchbuffer_require_space(intel->batch, (n)*4, flags);        \
-} while (0)
-
-#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d)
-
-#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)
-
-
-#endif
index 5748d7ff05ed33e27deac7b4168fc597937a45dc..07256ce1e5812b515c1d40ebb7bb59d1cc7c50ac 100644 (file)
@@ -5,7 +5,6 @@ include $(TOP)/configs/current
 LIBNAME = i965_dri.so
 
 DRIVER_SOURCES = \
-       bufmgr_fake.c \
        intel_batchbuffer.c \
        intel_blit.c \
        intel_buffer_objects.c \
@@ -92,6 +91,7 @@ DRIVER_DEFINES = -I../intel
 
 include ../Makefile.template
 
+intel_batchbuffer.o: ../intel/intel_batchbuffer.o
 intel_tex_layout.o: ../intel/intel_tex_layout.c
 
 server:
index aa797b72ce624fa810c58b402a1fb04285bd692a..279baf8c835268c248679fc0392f448fdaa751dc 100644 (file)
@@ -242,7 +242,7 @@ struct brw_surface_binding_table {
 struct brw_cache;
 
 struct brw_mem_pool {
-   struct buffer *buffer;
+   dri_bo *buffer;
 
    GLuint size;
    GLuint offset;              /* offset of first free byte */
@@ -605,7 +605,7 @@ struct brw_context
       GLuint nr_surfaces;      
 
       GLuint max_threads;
-      struct buffer *scratch_buffer;
+      dri_bo *scratch_buffer;
       GLuint scratch_buffer_size;
 
       GLuint sampler_count;
index fc2e3035af1023028d7b4af835430be3e1614b5e..5f6f0ef5a6254d49c68ca3da10114b109775c5fb 100644 (file)
@@ -58,7 +58,7 @@ struct brw_array_state {
         GLuint dword;
       } vb0;
    
-      struct buffer *buffer;
+      dri_bo *buffer;
       GLuint offset;
 
       GLuint max_index;   
@@ -68,7 +68,7 @@ struct brw_array_state {
 };
 
 
-static struct buffer *array_buffer( const struct gl_client_array *array )
+static dri_bo *array_buffer( const struct gl_client_array *array )
 {
    return intel_bufferobj_buffer(intel_buffer_object(array->BufferObj));
 }
@@ -620,7 +620,7 @@ void brw_upload_indices( struct brw_context *brw,
     */
    {
       struct brw_indexbuffer ib;
-      struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj));
+      dri_bo *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj));
 
       memset(&ib, 0, sizeof(ib));
    
index 708ae857ab5158007b11dc809e772fa204587c6e..9677c73583c8e7a62ac743c51adf17b06599ff4c 100644 (file)
@@ -34,7 +34,7 @@
 #include "imports.h"
 
 #include "intel_ioctl.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 GLboolean brw_pool_alloc( struct brw_mem_pool *pool,
                          GLuint size,
index 92c07c29624e9bbda05ae1805e5975bf36118785..d5e575ef66ac56c4b58896b3bdc3a0dcd94fe12e 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "brw_context.h"
 #include "brw_state.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 #include "intel_batchbuffer.h"
 
 /* This is used to initialize brw->state.atoms[].  We could use this
index 5b4f2abd0e269740cb07d035d44a0b8ddbff3d22..b1de66d98842f9922046190e6c49122620c1bb5b 100644 (file)
@@ -34,7 +34,7 @@
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 /***********************************************************************
  * WM unit - fragment programs and rasterization
diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h
deleted file mode 100644 (file)
index b31c2e6..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/**************************************************************************
- * 
- * 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.
- * 
- **************************************************************************/
-
-#ifndef BUFMGR_H
-#define BUFMGR_H
-
-#include "intel_context.h"
-
-
-/* The buffer manager context.  Opaque.
- */
-struct bufmgr;
-struct buffer;
-
-
-struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); 
-
-/* Flags for validate and other calls.  If both NO_UPLOAD and NO_EVICT
- * are specified, ValidateBuffers is essentially a query.
- */
-#define BM_MEM_LOCAL   0x1
-#define BM_MEM_AGP     0x2
-#define BM_MEM_VRAM    0x4     /* not yet used */
-#define BM_WRITE       0x8     /* not yet used */
-#define BM_READ        0x10    /* not yet used */
-#define BM_NO_UPLOAD   0x20
-#define BM_NO_EVICT    0x40
-#define BM_NO_MOVE     0x80    /* not yet used */
-#define BM_NO_ALLOC    0x100   /* legacy "fixed" buffers only */
-#define BM_CLIENT      0x200   /* for map - pointer will be accessed
-                                * without dri lock */
-
-#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM)
-
-
-
-
-/* Create a pool of a given memory type, from a certain offset and a
- * certain size.  
- *
- * Also passed in is a virtual pointer to the start of the pool.  This
- * is useful in the faked-out version in i915 so that MapBuffer can
- * return a pointer to a buffer residing in AGP space.  
- *
- * Flags passed into a pool are inherited by all buffers allocated in
- * that pool.  So pools representing the static front,back,depth
- * buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match
- * the behaviour of the legacy allocations.
- *
- * Returns -1 for failure, pool number for success.
- */
-int bmInitPool( struct intel_context *, 
-               unsigned long low_offset,
-               void *low_virtual,
-               unsigned long size,
-               unsigned flags);
-
-
-/* Stick closely to ARB_vbo semantics - they're well defined and
- * understood, and drivers can just pass the calls through without too
- * much thunking.
- */
-void bmGenBuffers(struct intel_context *, const char *, unsigned n, struct buffer **buffers,
-                 int align );
-void bmDeleteBuffers(struct intel_context *, unsigned n, struct buffer **buffers);
-
-
-/* Hook to inform faked buffer manager about fixed-position
- * front,depth,back buffers.  These may move to a fully memory-managed
- * scheme, or they may continue to be managed as is.
- */
-struct buffer *bmGenBufferStatic(struct intel_context *,
-                                unsigned pool);
-
-/* On evict, buffer manager will call invalidate_cb() to note that the
- * buffer needs to be reloaded.
- *
- * Buffer is uploaded by calling bmMapBuffer() and copying data into
- * the returned pointer.
- *
- * This is basically a big hack to get some more performance by
- * turning off backing store for buffers where we either have it
- * already (textures) or don't need it (batch buffers, temporary
- * vbo's).
- */
-void bmBufferSetInvalidateCB(struct intel_context *,
-                            struct buffer *buf,
-                            void (*invalidate_cb)( struct intel_context *, void *ptr ),
-                            void *ptr,
-                            GLboolean dont_fence_subdata);
-
-
-/* The driver has more intimate knowledge of the hardare than a GL
- * client would, so flags here is more proscriptive than the usage
- * values in the ARB_vbo interface:
- */
-int bmBufferData(struct intel_context *, 
-                 struct buffer *buf, 
-                 unsigned size, 
-                 const void *data, 
-                 unsigned flags );
-
-int bmBufferSubData(struct intel_context *, 
-                    struct buffer *buf, 
-                    unsigned offset, 
-                    unsigned size, 
-                    const void *data );
-
-/* In this version, taking the offset will provoke an upload on
- * buffers not already resident in AGP:
- */
-unsigned bmBufferOffset(struct intel_context *, 
-                       struct buffer *buf);
-
-
-/* Extract data from the buffer:
- */
-void bmBufferGetSubData(struct intel_context *, 
-                       struct buffer *buf, 
-                       unsigned offset, 
-                       unsigned size, 
-                       void *data );
-
-void *bmMapBuffer( struct intel_context *,
-                  struct buffer *buf, 
-                  unsigned access );
-
-void bmUnmapBuffer( struct intel_context *,
-                   struct buffer *buf );
-
-/* Pertains to all buffers who's offset has been taken since the last
- * fence or release.
- */
-int bmValidateBuffers( struct intel_context * );
-void bmReleaseBuffers( struct intel_context * );
-
-GLuint bmCtxId( struct intel_context *intel );
-
-
-GLboolean bmError( struct intel_context * );
-void bmEvictAll( struct intel_context * );
-
-void *bmFindVirtual( struct intel_context *intel,
-                    unsigned int offset,
-                    size_t sz );
-
-/* This functionality is used by the buffer manager, not really sure
- * if we need to be exposing it in this way, probably libdrm will
- * offer equivalent calls.
- *
- * For now they can stay, but will likely change/move before final:
- */
-unsigned bmSetFence( struct intel_context * );
-unsigned bmSetFenceLock( struct intel_context * );
-unsigned bmLockAndFence( struct intel_context *intel );
-int bmTestFence( struct intel_context *, unsigned fence );
-void bmFinishFence( struct intel_context *, unsigned fence );
-void bmFinishFenceLock( struct intel_context *, unsigned fence );
-
-void bm_fake_NotifyContendedLockTake( struct intel_context * );
-
-extern int INTEL_DEBUG;
-#define DEBUG_BUFMGR 0x10000000
-
-#define DBG(...)  do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0)
-
-#endif
diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c
deleted file mode 100644 (file)
index a851211..0000000
+++ /dev/null
@@ -1,1360 +0,0 @@
-/**************************************************************************
- * 
- * 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 "bufmgr.h"
-
-#include "intel_context.h"
-#include "intel_ioctl.h"
-#include "intel_batchbuffer.h"
-
-#include "simple_list.h"
-#include "mm.h"
-#include "imports.h"
-
-#define BM_POOL_MAX 8
-
-/* Internal flags:
- */
-#define BM_NO_BACKING_STORE   0x2000
-#define BM_NO_FENCE_SUBDATA   0x4000
-
-
-static int check_fenced( struct intel_context *intel );
-
-static int nr_attach = 0;
-
-/* 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 pool *pool;          /* BM_MEM_AGP */
-   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 */
-
-   struct buffer *buf;
-   void *virtual;
-};
-
-
-struct buffer {
-   unsigned id;                        /* debug only */
-   const char *name;
-   unsigned size;
-
-   unsigned mapped:1;          
-   unsigned dirty:1;           
-   unsigned alignment:13;
-   unsigned flags:16;
-
-   struct block *block;
-   void *backing_store;
-   void (*invalidate_cb)( struct intel_context *, void * );
-   void *invalidate_ptr;
-};
-
-struct pool {
-   unsigned size;
-   unsigned low_offset;
-   struct buffer *static_buffer;
-   unsigned flags;
-   struct mem_block *heap;
-   void *virtual;
-   struct block lru;           /* only allocated, non-fence-pending blocks here */
-};
-
-struct bufmgr {
-   _glthread_Mutex mutex;      /**< for thread safety */
-   struct pool pool[BM_POOL_MAX];
-   unsigned nr_pools;
-
-   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 pool->lru or free() */
-
-   unsigned ctxId;
-   unsigned last_fence;
-   unsigned free_on_hardware;
-
-   unsigned fail:1;
-   unsigned need_fence:1;
-};
-
-#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;
-}
-
-int bmTestFence( struct intel_context *intel, unsigned fence )
-{
-   /* Slight problem with wrap-around:
-    */
-   return fence == 0 || FENCE_LTE(fence, intel->sarea->last_dispatch);
-}
-
-#define LOCK(bm) \
-  int dolock = nr_attach > 1; \
-  if (dolock) _glthread_LOCK_MUTEX(bm->mutex)
-
-#define UNLOCK(bm) \
-  if (dolock) _glthread_UNLOCK_MUTEX(bm->mutex)
-
-
-
-static GLboolean alloc_from_pool( struct intel_context *intel,                         
-                                 unsigned pool_nr,
-                                 struct buffer *buf )
-{
-   struct bufmgr *bm = intel->bm;
-   struct pool *pool = &bm->pool[pool_nr];
-   struct block *block = (struct block *)calloc(sizeof *block, 1);
-   GLuint sz, align = (1<<buf->alignment);
-
-   if (!block)
-      return GL_FALSE;
-
-   sz = (buf->size + align-1) & ~(align-1);
-
-   block->mem = mmAllocMem(pool->heap, 
-                          sz, 
-                          buf->alignment, 0);
-   if (!block->mem) {
-      free(block);
-      return GL_FALSE;
-   }
-
-   make_empty_list(block);
-
-   /* Insert at head or at tail???   
-    */
-   insert_at_tail(&pool->lru, block);
-
-   block->pool = pool;
-   block->virtual = pool->virtual + block->mem->ofs;
-   block->buf = buf;
-
-   buf->block = block;
-
-   return GL_TRUE;
-}
-
-
-
-
-
-
-
-
-/* Release the card storage associated with buf:
- */
-static void free_block( struct intel_context *intel, struct block *block )
-{
-   DBG("free block %p\n", block);
-
-   if (!block) 
-      return;
-
-   check_fenced(intel);
-
-   if (block->referenced) {
-      _mesa_printf("tried to free block on referenced list\n");
-      assert(0);
-   }
-   else if (block->on_hardware) {
-      block->buf = NULL;
-      intel->bm->free_on_hardware += block->mem->size;
-   }
-   else if (block->fenced) {
-      block->buf = NULL;
-   }
-   else {
-      DBG("    - free immediately\n");
-      remove_from_list(block);
-
-      mmFreeMem(block->mem);
-      free(block);
-   }
-}
-
-
-static void alloc_backing_store( struct intel_context *intel, struct buffer *buf )
-{
-   assert(!buf->backing_store);
-   assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)));
-
-   buf->backing_store = ALIGN_MALLOC(buf->size, 64);
-}
-
-static void free_backing_store( struct intel_context *intel, struct buffer *buf )
-{
-   assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)));
-         
-   if (buf->backing_store) {
-      ALIGN_FREE(buf->backing_store);
-      buf->backing_store = NULL;
-   }
-}
-
-
-
-
-
-
-static void set_dirty( struct intel_context *intel,
-                             struct buffer *buf )
-{
-   if (buf->flags & BM_NO_BACKING_STORE)
-      buf->invalidate_cb(intel, buf->invalidate_ptr);
-
-   assert(!(buf->flags & BM_NO_EVICT));
-
-   DBG("set_dirty - buf %d\n", buf->id);
-   buf->dirty = 1;
-}
-
-
-static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool )
-{
-   struct bufmgr *bm = intel->bm;
-   struct block *block, *tmp;
-   int i;
-
-   DBG("%s\n", __FUNCTION__);
-
-   for (i = 0; i < bm->nr_pools; i++) {
-      if (!(bm->pool[i].flags & BM_NO_EVICT)) {
-        foreach_s(block, tmp, &bm->pool[i].lru) {
-
-           if (block->buf &&
-               (block->buf->flags & BM_NO_FENCE_SUBDATA))
-              continue;
-
-           if (block->fence && max_fence &&
-               !FENCE_LTE(block->fence, max_fence))
-              return 0;
-
-           set_dirty(intel, block->buf);
-           block->buf->block = NULL;
-
-           free_block(intel, block);
-           *pool = i;
-           return 1;
-        }
-      }
-   }
-
-
-   return 0;
-}
-
-
-#define foreach_s_rev(ptr, t, list)   \
-        for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev)
-
-static int evict_mru( struct intel_context *intel, GLuint *pool )
-{
-   struct bufmgr *bm = intel->bm;
-   struct block *block, *tmp;
-   int i;
-
-   DBG("%s\n", __FUNCTION__);
-
-   for (i = 0; i < bm->nr_pools; i++) {
-      if (!(bm->pool[i].flags & BM_NO_EVICT)) {
-        foreach_s_rev(block, tmp, &bm->pool[i].lru) {
-
-           if (block->buf &&
-               (block->buf->flags & BM_NO_FENCE_SUBDATA))
-              continue;
-
-           set_dirty(intel, block->buf);
-           block->buf->block = NULL;
-
-           free_block(intel, block);
-           *pool = i;
-           return 1;
-        }
-      }
-   }
-
-
-   return 0;
-}
-
-
-static int check_fenced( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-   struct block *block, *tmp;
-   int ret = 0;
-
-   foreach_s(block, tmp, &bm->fenced ) {
-      assert(block->fenced);
-
-      if (bmTestFence(intel, block->fence)) {
-
-        block->fenced = 0;
-
-        if (!block->buf) {
-           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(&block->pool->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, &bm->referenced ) {
-      if (block->fenced &&
-         bmTestFence(intel, block->fence)) {
-        block->fenced = 0;
-      }
-   }
-
-   
-   DBG("%s: %d\n", __FUNCTION__, ret);
-   return ret;
-}
-
-
-
-static void fence_blocks( struct intel_context *intel,
-                         unsigned fence )
-{
-   struct bufmgr *bm = intel->bm;
-   struct block *block, *tmp;
-
-   foreach_s (block, tmp, &bm->on_hardware) {
-      DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, 
-         block->mem->size, block->buf, fence);
-      block->fence = fence;
-
-      block->on_hardware = 0;
-      block->fenced = 1;
-
-      /* Move to tail of pending list here
-       */
-      move_to_tail(&bm->fenced, block);
-   }
-
-   /* Also check the referenced list:
-    */  
-   foreach_s (block, tmp, &bm->referenced) {
-      if (block->on_hardware) {
-        DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, 
-            block->mem->size, block->buf, fence);
-        
-        block->fence = fence;
-        block->on_hardware = 0;
-        block->fenced = 1;
-      }
-   }
-
-
-   bm->last_fence = fence;
-   assert(is_empty_list(&bm->on_hardware));
-}
-
-
-
-
-static GLboolean alloc_block( struct intel_context *intel,
-                             struct buffer *buf )
-{
-   struct bufmgr *bm = intel->bm;
-   int i;
-
-   assert(intel->locked);
-
-   DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name);
-
-   for (i = 0; i < bm->nr_pools; i++) {
-      if (!(bm->pool[i].flags & BM_NO_ALLOC) &&
-         alloc_from_pool(intel, i, buf)) {
-
-        DBG("%s --> 0x%x (sz %x)\n", __FUNCTION__, 
-            buf->block->mem->ofs, buf->block->mem->size);
-        
-        return GL_TRUE;
-      }
-   }
-
-   DBG("%s --> fail\n", __FUNCTION__);
-   return GL_FALSE;   
-}
-
-
-static GLboolean evict_and_alloc_block( struct intel_context *intel,
-                                       struct buffer *buf )
-{
-   GLuint pool;
-   struct bufmgr *bm = intel->bm;
-
-   assert(buf->block == NULL);
-
-   /* Put a cap on the amount of free memory we'll allow to accumulate
-    * before emitting a fence.
-    */
-   if (bm->free_on_hardware > 1 * 1024 * 1024) {
-      DBG("fence for free space: %x\n", bm->free_on_hardware);
-      bmSetFence(intel);
-   }
-
-   /* Search for already free memory:
-    */
-   if (alloc_block(intel, buf))
-      return GL_TRUE;
-
-   /* Look for memory that may have become free: 
-    */
-   if (check_fenced(intel) &&
-       alloc_block(intel, buf))
-      return GL_TRUE;
-
-   /* Look for memory blocks not used for >1 frame:
-    */
-   while (evict_lru(intel, intel->second_last_swap_fence, &pool))
-      if (alloc_from_pool(intel, pool, buf))
-        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 (!intel->thrashing) {
-      while (evict_lru(intel, 0, &pool))
-        if (alloc_from_pool(intel, pool, buf))
-           return GL_TRUE;
-   }
-
-   /* Keep thrashing counter alive?
-    */
-   if (intel->thrashing)
-      intel->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(&bm->fenced)) {
-      GLuint fence = bm->fenced.next->fence;
-      bmFinishFence(intel, fence);
-
-      if (alloc_block(intel, buf))
-        return GL_TRUE;
-   }
-
-
-   /* 
-    */
-   if (!is_empty_list(&bm->on_hardware)) {
-      bmSetFence(intel);
-
-      while (!is_empty_list(&bm->fenced)) {
-        GLuint fence = bm->fenced.next->fence;
-        bmFinishFence(intel, fence);
-      }
-
-      if (!intel->thrashing) {  
-        DBG("thrashing\n");
-      }
-      intel->thrashing = 20; 
-
-      if (alloc_block(intel, buf))
-        return GL_TRUE;
-   }
-
-   while (evict_mru(intel, &pool))
-      if (alloc_from_pool(intel, pool, buf))
-        return GL_TRUE;
-
-   DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size);
-
-   assert(is_empty_list(&bm->on_hardware));
-   assert(is_empty_list(&bm->fenced));
-
-   return GL_FALSE;
-}
-
-
-
-
-
-
-
-
-
-
-/***********************************************************************
- * Public functions
- */
-
-
-/* The initialization functions are skewed in the fake implementation.
- * This call would be to attach to an existing manager, rather than to
- * create a local one.
- */
-struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel )
-{
-   _glthread_DECLARE_STATIC_MUTEX(initMutex);   
-   static struct bufmgr bm;
-   
-   /* This function needs a mutex of its own...
-    */
-   _glthread_LOCK_MUTEX(initMutex);
-
-   if (nr_attach == 0) {
-      _glthread_INIT_MUTEX(bm.mutex);
-
-      make_empty_list(&bm.referenced);
-      make_empty_list(&bm.fenced);
-      make_empty_list(&bm.on_hardware);
-      
-      /* The context id of any of the share group.  This won't be used
-       * in communication with the kernel, so it doesn't matter if
-       * this context is eventually deleted.
-       */
-      bm.ctxId = intel->hHWContext;
-   }
-
-   nr_attach++;
-
-   _glthread_UNLOCK_MUTEX(initMutex);
-
-   return &bm;
-}
-
-
-
-/* The virtual pointer would go away in a true implementation.
- */
-int bmInitPool( struct intel_context *intel, 
-               unsigned long low_offset,
-               void *low_virtual,
-               unsigned long size,
-               unsigned flags)
-{
-   struct bufmgr *bm = intel->bm;
-   int retval = 0;
-
-   LOCK(bm);
-   {
-      GLuint i;
-
-      for (i = 0; i < bm->nr_pools; i++) {
-        if (bm->pool[i].low_offset == low_offset &&
-            bm->pool[i].size == size) {
-           retval = i;
-           goto out;
-        }
-      }
-
-
-      if (bm->nr_pools >= BM_POOL_MAX)
-        retval = -1;
-      else {
-        i = bm->nr_pools++;
-   
-        DBG("bmInitPool %d low_offset %x sz %x\n",
-            i, low_offset, size);
-   
-        bm->pool[i].low_offset = low_offset;
-        bm->pool[i].size = size;
-        bm->pool[i].heap = mmInit( low_offset, size );
-        bm->pool[i].virtual = low_virtual - low_offset;
-        bm->pool[i].flags = flags;
-   
-        make_empty_list(&bm->pool[i].lru);
-        
-        retval = i;
-      }
-   }
- out:
-   UNLOCK(bm);
-   return retval;
-}
-
-static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align)
-{
-   struct bufmgr *bm = intel->bm;
-   struct buffer *buf = calloc(sizeof(*buf), 1);
-
-   buf->id = ++bm->buf_nr;
-   buf->name = name;
-   buf->alignment = align;     
-   buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL;
-
-   return buf;
-}
-
-
-void *bmFindVirtual( struct intel_context *intel,
-                    unsigned int offset,
-                    size_t sz )
-{
-   struct bufmgr *bm = intel->bm;
-   int i;
-
-   for (i = 0; i < bm->nr_pools; i++)
-      if (offset >= bm->pool[i].low_offset &&
-         offset + sz <= bm->pool[i].low_offset + bm->pool[i].size)
-        return bm->pool[i].virtual + offset;
-
-   return NULL;
-}
-
-void bmGenBuffers(struct intel_context *intel, 
-                 const char *name, unsigned n, 
-                 struct buffer **buffers,
-                 int align )
-{
-   struct bufmgr *bm = intel->bm;
-   LOCK(bm);
-   {
-      int i;
-
-      for (i = 0; i < n; i++)
-        buffers[i] = do_GenBuffer(intel, name, align);
-   }
-   UNLOCK(bm);
-}
-
-
-void bmDeleteBuffers(struct intel_context *intel, unsigned n, struct buffer **buffers)
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      unsigned i;
-   
-      for (i = 0; i < n; i++) {
-        struct buffer *buf = buffers[i];
-
-        if (buf && buf->block)
-           free_block(intel, buf->block);
-
-        if (buf) 
-           free(buf);   
-      }
-   }
-   UNLOCK(bm);
-}
-
-
-
-
-/* Hook to inform faked buffer manager about fixed-position
- * front,depth,back buffers.  These may move to a fully memory-managed
- * scheme, or they may continue to be managed as is.  It will probably
- * be useful to pass a fixed offset here one day.
- */
-struct buffer *bmGenBufferStatic(struct intel_context *intel,
-                                unsigned pool )
-{
-   struct bufmgr *bm = intel->bm;
-   struct buffer *buf;
-   LOCK(bm);
-   {
-      assert(bm->pool[pool].flags & BM_NO_EVICT);
-      assert(bm->pool[pool].flags & BM_NO_MOVE);
-
-      if (bm->pool[pool].static_buffer)
-        buf = bm->pool[pool].static_buffer;
-      else {
-        buf = do_GenBuffer(intel, "static", 12);
-   
-        bm->pool[pool].static_buffer = buf;
-        assert(!buf->block);
-
-        buf->size = bm->pool[pool].size;
-        buf->flags = bm->pool[pool].flags;
-        buf->alignment = 12;
-        
-        if (!alloc_from_pool(intel, pool, buf))
-           assert(0);
-      }
-   }
-   UNLOCK(bm);
-   return buf;
-}
-
-
-static void wait_quiescent(struct intel_context *intel,
-                          struct block *block)
-{
-   if (block->on_hardware) {
-      assert(intel->bm->need_fence);
-      bmSetFence(intel);
-      assert(!block->on_hardware);
-   }
-
-
-   if (block->fenced) {
-      bmFinishFence(intel, block->fence);
-   }
-
-   assert(!block->on_hardware);
-   assert(!block->fenced);
-}
-
-
-
-/* If buffer size changes, free and reallocate.  Otherwise update in
- * place.
- */
-int bmBufferData(struct intel_context *intel, 
-                struct buffer *buf, 
-                unsigned size, 
-                const void *data, 
-                unsigned flags )
-{
-   struct bufmgr *bm = intel->bm;
-   int retval = 0;
-
-   LOCK(bm);
-   {
-      DBG("bmBufferData %d sz 0x%x data: %p\n", buf->id, size, data);
-
-      assert(!buf->mapped);
-
-      if (buf->block) {
-        struct block *block = buf->block;
-
-        /* Optimistic check to see if we can reuse the block -- not
-         * required for correctness:
-         */
-        if (block->fenced)
-           check_fenced(intel);
-
-        if (block->on_hardware ||
-            block->fenced ||
-            (buf->size && buf->size != size) || 
-            (data == NULL)) {
-
-           assert(!block->referenced);
-
-           free_block(intel, block);
-           buf->block = NULL;
-           buf->dirty = 1;
-        }
-      }
-
-      buf->size = size;
-      if (buf->block) {
-        assert (buf->block->mem->size >= size);
-      }
-
-      if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) {
-
-        assert(intel->locked || data == NULL);
-
-        if (data != NULL) {
-           if (!buf->block && !evict_and_alloc_block(intel, buf)) {
-              bm->fail = 1;
-              retval = -1;
-              goto out;
-           }
-
-           wait_quiescent(intel, buf->block);
-
-           DBG("bmBufferData %d offset 0x%x sz 0x%x\n", 
-               buf->id, buf->block->mem->ofs, size);
-
-           assert(buf->block->virtual == buf->block->pool->virtual + buf->block->mem->ofs);
-
-           do_memcpy(buf->block->virtual, data, size);
-        }
-        buf->dirty = 0;
-      }
-      else {
-              DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id);
-        set_dirty(intel, buf);
-        free_backing_store(intel, buf);
-   
-        if (data != NULL) {      
-           alloc_backing_store(intel, buf);
-           do_memcpy(buf->backing_store, data, size);
-        }
-      }
-   }
- out:
-   UNLOCK(bm);
-   return retval;
-}
-
-
-/* Update the buffer in place, in whatever space it is currently resident:
- */
-int bmBufferSubData(struct intel_context *intel, 
-                    struct buffer *buf, 
-                    unsigned offset, 
-                    unsigned size, 
-                    const void *data )
-{
-   struct bufmgr *bm = intel->bm;
-   int retval = 0;
-
-   if (size == 0) 
-      return 0;
-
-   LOCK(bm); 
-   {
-      DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size);
-      
-      assert(offset+size <= buf->size);
-
-      if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) {
-
-        assert(intel->locked);
-
-        if (!buf->block && !evict_and_alloc_block(intel, buf)) {
-           bm->fail = 1;
-           retval = -1;
-           goto out;
-        }
-        
-        if (!(buf->flags & BM_NO_FENCE_SUBDATA))
-           wait_quiescent(intel, buf->block);
-
-        buf->dirty = 0;
-
-        do_memcpy(buf->block->virtual + offset, data, size);
-      }
-      else {
-        DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id);
-        set_dirty(intel, buf);
-
-        if (buf->backing_store == NULL)
-           alloc_backing_store(intel, buf);
-
-        do_memcpy(buf->backing_store + offset, data, size); 
-      }
-   }
- out:
-   UNLOCK(bm);
-   return retval;
-}
-
-unsigned bmBufferOffset(struct intel_context *intel, 
-                       struct buffer *buf)
-{
-   struct bufmgr *bm = intel->bm;
-   unsigned retval = 0;
-
-   LOCK(bm);
-   {
-      assert(intel->locked);
-
-      if (!buf->block &&
-         !evict_and_alloc_block(intel, buf)) {
-        bm->fail = 1;
-        retval = ~0;
-      }
-      else {
-        assert(buf->block);
-        assert(buf->block->buf == buf);
-
-        DBG("Add buf %d (block %p, dirty %d) to referenced list\n", buf->id, buf->block,
-            buf->dirty);
-
-        move_to_tail(&bm->referenced, buf->block);
-        buf->block->referenced = 1;
-
-        retval = buf->block->mem->ofs;
-      }
-   }
-   UNLOCK(bm);
-
-   return retval;
-}
-
-
-
-/* Extract data from the buffer:
- */
-void bmBufferGetSubData(struct intel_context *intel, 
-                       struct buffer *buf, 
-                       unsigned offset, 
-                       unsigned size, 
-                       void *data )
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size);
-
-      if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) {
-        if (buf->block && size) {
-           wait_quiescent(intel, buf->block);
-           do_memcpy(data, buf->block->virtual + offset, size); 
-        }
-      }
-      else {
-        if (buf->backing_store && size) {
-           do_memcpy(data, buf->backing_store + offset, size); 
-        }
-      }
-   }
-   UNLOCK(bm);
-}
-
-
-/* Return a pointer to whatever space the buffer is currently resident in:
- */
-void *bmMapBuffer( struct intel_context *intel,
-                  struct buffer *buf, 
-                  unsigned flags )
-{
-   struct bufmgr *bm = intel->bm;
-   void *retval = NULL;
-
-   LOCK(bm);
-   {
-      DBG("bmMapBuffer %d\n", buf->id);
-
-      if (buf->mapped) {
-        _mesa_printf("%s: already mapped\n", __FUNCTION__);
-        retval = NULL;
-      }
-      else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) {
-
-        assert(intel->locked);
-
-        if (!buf->block && !evict_and_alloc_block(intel, buf)) {
-           DBG("%s: alloc failed\n", __FUNCTION__);
-           bm->fail = 1;
-           retval = NULL;
-        }
-        else {
-           assert(buf->block);
-           buf->dirty = 0;
-
-           if (!(buf->flags & BM_NO_FENCE_SUBDATA)) 
-              wait_quiescent(intel, buf->block);
-
-           buf->mapped = 1;
-           retval = buf->block->virtual;
-        }
-      }
-      else {
-        DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id);
-        set_dirty(intel, buf);
-
-        if (buf->backing_store == 0)
-           alloc_backing_store(intel, buf);
-
-        buf->mapped = 1;
-        retval = buf->backing_store;
-      }
-   }
-   UNLOCK(bm);
-   return retval;
-}
-
-void bmUnmapBuffer( struct intel_context *intel, struct buffer *buf )
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      DBG("bmUnmapBuffer %d\n", buf->id);
-      buf->mapped = 0;
-   }
-   UNLOCK(bm);
-}
-
-
-
-
-/* This is the big hack that turns on BM_NO_BACKING_STORE.  Basically
- * says that an external party will maintain the backing store, eg
- * Mesa's local copy of texture data.
- */
-void bmBufferSetInvalidateCB(struct intel_context *intel,
-                            struct buffer *buf,
-                            void (*invalidate_cb)( struct intel_context *, void *ptr ),
-                            void *ptr,
-                            GLboolean dont_fence_subdata)
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      if (buf->backing_store)
-        free_backing_store(intel, buf);
-
-      buf->flags |= BM_NO_BACKING_STORE;
-      
-      if (dont_fence_subdata)
-        buf->flags |= BM_NO_FENCE_SUBDATA;
-
-      DBG("bmBufferSetInvalidateCB set buf %d dirty\n", buf->id);
-      buf->dirty = 1;
-      buf->invalidate_cb = invalidate_cb;
-      buf->invalidate_ptr = ptr;
-
-      /* Note that it is invalid right from the start.  Also note
-       * invalidate_cb is called with the bufmgr locked, so cannot
-       * itself make bufmgr calls.
-       */
-      invalidate_cb( intel, ptr );
-   }
-   UNLOCK(bm);
-}
-
-
-
-
-
-
-
-/* This is only protected against thread interactions by the DRI lock
- * and the policy of ensuring that all dma is flushed prior to
- * releasing that lock.  Otherwise you might have two threads building
- * up a list of buffers to validate at once.
- */
-int bmValidateBuffers( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-   int retval = 0;
-
-   LOCK(bm);
-   {
-      DBG("%s fail %d\n", __FUNCTION__, bm->fail);
-      assert(intel->locked);
-
-      if (!bm->fail) {
-        struct block *block, *tmp;
-
-        foreach_s(block, tmp, &bm->referenced) {
-           struct buffer *buf = block->buf;
-
-           DBG("Validate buf %d / block %p / dirty %d\n", buf->id, block, buf->dirty);
-
-           /* Upload the buffer contents if necessary:
-            */
-           if (buf->dirty) {
-              DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", buf->id, 
-                  buf->name, buf->size, block->mem->ofs);
-
-              assert(!(buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)));
-
-              wait_quiescent(intel, buf->block);
-
-              do_memcpy(buf->block->virtual,
-                        buf->backing_store, 
-                        buf->size);
-
-              buf->dirty = 0;
-           }
-
-           block->referenced = 0;
-           block->on_hardware = 1;
-           move_to_tail(&bm->on_hardware, block);
-        }
-
-        bm->need_fence = 1;
-      }
-
-      retval = bm->fail ? -1 : 0;
-   }
-   UNLOCK(bm);
-
-
-   if (retval != 0)
-      DBG("%s failed\n", __FUNCTION__);
-
-   return retval;
-}
-
-
-
-
-void bmReleaseBuffers( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      struct block *block, *tmp;
-
-      foreach_s (block, tmp, &bm->referenced) {
-
-        DBG("remove block %p from referenced list\n", block);
-
-        if (block->on_hardware) {
-           /* Return to the on-hardware list.
-            */
-           move_to_tail(&bm->on_hardware, block);          
-        }
-        else if (block->fenced) {
-           struct block *s;
-
-           /* Hmm - have to scan the fenced list to insert the
-            * buffers in order.  This is O(nm), but rare and the
-            * numbers are low.
-            */
-           foreach (s, &bm->fenced) {
-              if (FENCE_LTE(block->fence, s->fence))
-                 break;
-           }
-           
-           move_to_tail(s, block);
-        }
-        else {                 
-           /* Return to the lru list:
-            */
-           move_to_tail(&block->pool->lru, block);
-        }
-
-        block->referenced = 0;
-      }
-   }
-   UNLOCK(bm);
-}
-
-
-/* This functionality is used by the buffer manager, not really sure
- * if we need to be exposing it in this way, probably libdrm will
- * offer equivalent calls.
- *
- * For now they can stay, but will likely change/move before final:
- */
-unsigned bmSetFence( struct intel_context *intel )
-{
-   assert(intel->locked);
-
-   /* Emit MI_FLUSH here:
-    */
-   if (intel->bm->need_fence) {
-
-      /* Emit a flush without using a batchbuffer.  Can't rely on the
-       * batchbuffer at this level really.  Would really prefer that
-       * the IRQ ioctly emitted the flush at the same time.
-       */
-      GLuint dword[2];
-      dword[0] = intel->vtbl.flush_cmd();
-      dword[1] = 0;
-      intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword));
-      
-      intel->bm->last_fence = intelEmitIrqLocked( intel );
-      
-      fence_blocks(intel, intel->bm->last_fence);
-
-      intel->vtbl.note_fence(intel, intel->bm->last_fence);
-      intel->bm->need_fence = 0;
-
-      if (intel->thrashing) {
-        intel->thrashing--;
-        if (!intel->thrashing)
-           DBG("not thrashing\n");
-      }
-      
-      intel->bm->free_on_hardware = 0;
-   }
-   
-   return intel->bm->last_fence;
-}
-
-unsigned bmSetFenceLock( struct intel_context *intel )
-{
-  unsigned last;
-  LOCK(intel->bm);
-  last = bmSetFence(intel);
-  UNLOCK(intel->bm);
-  return last;
-}
-unsigned bmLockAndFence( struct intel_context *intel )
-{
-   if (intel->bm->need_fence) {
-      LOCK_HARDWARE(intel);
-      LOCK(intel->bm);
-      bmSetFence(intel);
-      UNLOCK(intel->bm);
-      UNLOCK_HARDWARE(intel);
-   }
-
-   return intel->bm->last_fence;
-}
-
-
-void bmFinishFence( struct intel_context *intel, unsigned fence )
-{
-   if (!bmTestFence(intel, fence)) {
-      DBG("...wait on fence %d\n", fence);
-      intelWaitIrq( intel, fence );
-   }
-   assert(bmTestFence(intel, fence));
-   check_fenced(intel);
-}
-
-void bmFinishFenceLock( struct intel_context *intel, unsigned fence )
-{
-   LOCK(intel->bm);
-   bmFinishFence(intel, fence);
-   UNLOCK(intel->bm);
-}
-
-
-/* Specifically ignore texture memory sharing.
- *  -- just evict everything
- *  -- and wait for idle
- */
-void bm_fake_NotifyContendedLockTake( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      struct block *block, *tmp;
-      GLuint i;
-
-      assert(is_empty_list(&bm->referenced));
-
-      bm->need_fence = 1;
-      bm->fail = 0;
-      bmFinishFence(intel, bmSetFence(intel));
-
-      assert(is_empty_list(&bm->fenced));
-      assert(is_empty_list(&bm->on_hardware));
-
-      for (i = 0; i < bm->nr_pools; i++) {
-        if (!(bm->pool[i].flags & BM_NO_EVICT)) {
-           foreach_s(block, tmp, &bm->pool[i].lru) {
-              assert(bmTestFence(intel, block->fence));
-              set_dirty(intel, block->buf);
-           }
-        }
-      }
-   }
-   UNLOCK(bm);
-}
-
-
-
-void bmEvictAll( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-
-   LOCK(bm);
-   {
-      struct block *block, *tmp;
-      GLuint i;
-
-      DBG("%s\n", __FUNCTION__);
-
-      assert(is_empty_list(&bm->referenced));
-
-      bm->need_fence = 1;
-      bm->fail = 0;
-      bmFinishFence(intel, bmSetFence(intel));
-
-      assert(is_empty_list(&bm->fenced));
-      assert(is_empty_list(&bm->on_hardware));
-
-      for (i = 0; i < bm->nr_pools; i++) {
-        if (!(bm->pool[i].flags & BM_NO_EVICT)) {
-           foreach_s(block, tmp, &bm->pool[i].lru) {
-              assert(bmTestFence(intel, block->fence));
-              set_dirty(intel, block->buf);
-              block->buf->block = NULL;
-
-              free_block(intel, block);
-           }
-        }
-      }
-   }
-   UNLOCK(bm);
-}
-
-
-GLboolean bmError( struct intel_context *intel )
-{
-   struct bufmgr *bm = intel->bm;
-   GLboolean retval;
-
-   LOCK(bm);
-   {
-      retval = bm->fail;
-   }
-   UNLOCK(bm);
-
-   return retval;
-}
-
-
-GLuint bmCtxId( struct intel_context *intel )
-{
-   return intel->bm->ctxId;
-}
index 2aaa10e1c21bfe59ac343d7370ac69d3999e5c1a..e4557a38471573e97ffa06a9c1738f4017f6c8c0 100644 (file)
 #include "imports.h"
 #include "intel_batchbuffer.h"
 #include "intel_ioctl.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 
 static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
 {
    assert(batch->map == NULL);
 
+   if (batch->buf != NULL) {
+      dri_bo_unreference(batch->buf);
+      batch->buf = NULL;
+   }
+
+   batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer",
+                            intel->intelScreen->maxBatchSize, 4096,
+                            DRM_BO_FLAG_MEM_TT);
+   dri_bo_map(batch->buf, GL_TRUE);
+   batch->map = batch->buf->virtual;
+
    batch->offset = (unsigned long)batch->ptr;
    batch->offset = (batch->offset + 63) & ~63;
    batch->ptr = (unsigned char *) batch->offset;
index 25e0a65e99fdcdc578fbeb5e2f9460a8f9d74859..a824966d2e23500e7f96a6ee054d3ba7fdf7ab48 100644 (file)
@@ -29,7 +29,7 @@
 #define INTEL_BATCHBUFFER_H
 
 #include "mtypes.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 struct intel_context;
 
@@ -43,7 +43,7 @@ struct intel_context;
 struct intel_batchbuffer {
    struct intel_context *intel;
 
-   struct buffer *buffer;
+   dri_bo *buffer;
 
    GLuint flags;
    unsigned long offset;
index f88cbb2328dfc3e2a35bff2d6da2ee97ba966000..4502c551a73580815e51be8d3ac6a7af110a76b4 100644 (file)
@@ -41,7 +41,7 @@
 #include "intel_regions.h"
 #include "intel_structs.h"
 
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 
 
@@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
    intelFlush( &intel->ctx );
 
 
-   bmFinishFenceLock(intel, intel->last_swap_fence);
+   dri_fence_wait(intel, intel->last_swap_fence);
 
    /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
     * should work regardless.
@@ -154,8 +154,10 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
    }
 
    intel_batchbuffer_flush( intel->batch );
+
+   dri_fence_unreference(intel->second_last_swap_fence);
    intel->second_last_swap_fence = intel->last_swap_fence;
-   intel->last_swap_fence = bmSetFenceLock( intel );
+   intel->last_swap_fence = dri_fence_reference(intel->bmbmSetFenceLock( intel );
    UNLOCK_HARDWARE( intel );
 
    if (!rect)
@@ -178,7 +180,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
 void intelEmitFillBlit( struct intel_context *intel,
                        GLuint cpp,
                        GLshort dst_pitch,
-                       struct buffer *dst_buffer,
+                       dri_bo *dst_buffer,
                        GLuint dst_offset,
                        GLboolean dst_tiled,
                        GLshort x, GLshort y, 
@@ -250,11 +252,11 @@ static GLuint translate_raster_op(GLenum logicop)
 void intelEmitCopyBlit( struct intel_context *intel,
                        GLuint cpp,
                        GLshort src_pitch,
-                       struct buffer *src_buffer,
+                       dri_bo *src_buffer,
                        GLuint  src_offset,
                        GLboolean src_tiled,
                        GLshort dst_pitch,
-                       struct buffer *dst_buffer,
+                       dri_bo *dst_buffer,
                        GLuint  dst_offset,
                        GLboolean dst_tiled,
                        GLshort src_x, GLshort src_y,
@@ -528,7 +530,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
                                  GLubyte *src_bits, GLuint src_size,
                                  GLuint fg_color,
                                  GLshort dst_pitch,
-                                 struct buffer *dst_buffer,
+                                 dri_bo *dst_buffer,
                                  GLuint dst_offset,
                                  GLboolean dst_tiled,
                                  GLshort x, GLshort y, 
index e361545c8fab316c2e4315734fd69a1ec7a82642..45dd33db664df510f4abb94b2c00fe4043a91de0 100644 (file)
@@ -31,7 +31,7 @@
 #include "intel_context.h"
 #include "intel_ioctl.h"
 
-struct buffer;
+dri_bo;
 
 extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv,
                             const drm_clip_rect_t *rect );
@@ -40,11 +40,11 @@ extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask);
 extern void intelEmitCopyBlit( struct intel_context *intel,
                               GLuint cpp,
                               GLshort src_pitch,
-                              struct buffer *src_buffer,
+                              dri_bo *src_buffer,
                               GLuint  src_offset,
                               GLboolean src_tiled,
                               GLshort dst_pitch,
-                              struct buffer *dst_buffer,
+                              dri_bo *dst_buffer,
                               GLuint  dst_offset,
                               GLboolean dst_tiled,
                               GLshort srcx, GLshort srcy,
@@ -55,7 +55,7 @@ extern void intelEmitCopyBlit( struct intel_context *intel,
 extern void intelEmitFillBlit( struct intel_context *intel,
                               GLuint cpp,
                               GLshort dst_pitch,
-                              struct buffer *dst_buffer,
+                              dri_bo *dst_buffer,
                               GLuint dst_offset,
                               GLboolean dst_tiled,
                               GLshort x, GLshort y, 
@@ -68,7 +68,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
                                  GLubyte *src_bits, GLuint src_size,
                                  GLuint fg_color,
                                  GLshort dst_pitch,
-                                 struct buffer *dst_buffer,
+                                 dri_bo *dst_buffer,
                                  GLuint dst_offset,
                                  GLboolean dst_tiled,
                                  GLshort dst_x, GLshort dst_y, 
index 3349284f5db25a9e644832c050cc8570c1b0eb98..32c458987d7796e51a998453ebb7daf59024cc91 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "intel_context.h"
 #include "intel_buffer_objects.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 
 /**
@@ -185,7 +185,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx,
    return GL_TRUE;
 }
 
-struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj )
+dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj )
 {
    assert(intel_obj->Base.Name);
    assert(intel_obj->buffer);
index 4b38803e5760b1dc25448af97b932e99b50d252e..a80f448716ddaaa4f1f14687b8e91c543e65c26c 100644 (file)
@@ -39,13 +39,13 @@ struct gl_buffer_object;
  */
 struct intel_buffer_object {
    struct gl_buffer_object Base;
-   struct buffer *buffer;   /* the low-level buffer manager's buffer handle */
+   dri_bo *buffer;   /* the low-level buffer manager's buffer handle */
 };
 
 
 /* Get the bm buffer associated with a GL bufferobject:
  */
-struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *obj );
+dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *obj );
 
 /* Hook the bufferobject implementation into mesa: 
  */
index 022819d58217ad514881b4144f98dd51f613e386..37c9fa3ec311cf598bdaf06f8ac032aab921e81f 100644 (file)
@@ -58,7 +58,7 @@
 #include "intel_regions.h"
 #include "intel_buffer_objects.h"
 
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 #include "utils.h"
 #include "vblank.h"
@@ -635,10 +635,10 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags )
    /* As above, but don't evict the texture data on transitions
     * between contexts which all share a local buffer manager.
     */
-   if (sarea->texAge != my_bufmgr) {
+   if (sarea->texAge != intel->hHWContext) {
       DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr);
-      sarea->texAge = my_bufmgr;
-      bm_fake_NotifyContendedLockTake( intel ); 
+      sarea->texAge = intel->hHWContext;
+      dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr);
    }
 
    /* Drawable changed?
@@ -668,11 +668,6 @@ void LOCK_HARDWARE( struct intel_context *intel )
 
    intel->locked = 1;
 
-   if (bmError(intel)) {
-      bmEvictAll(intel);
-      intel->vtbl.lost_hardware( intel );
-   }
-
    /* Make sure nothing has been emitted prior to getting the lock:
     */
    assert(intel->batch->map == 0);
@@ -680,16 +675,8 @@ void LOCK_HARDWARE( struct intel_context *intel )
    /* XXX: postpone, may not be needed:
     */
    if (!intel_batchbuffer_map(intel->batch)) {
-      bmEvictAll(intel);
-      intel->vtbl.lost_hardware( intel );
-
-      /* This could only fail if the batchbuffer was greater in size
-       * than the available texture memory:
-       */
-      if (!intel_batchbuffer_map(intel->batch)) {
-        _mesa_printf("double failure to map batchbuffer\n");
-        assert(0);
-      }
+      _mesa_printf("failure to map batchbuffer\n");
+      assert(0);
    }
 }
  
index e7e736079f4b49c60493eb9136b25cc5a0cdfb7a..88d5983027278f244b6ba9a904bdb9f3e3609b26 100644 (file)
@@ -41,7 +41,7 @@
 #include "intel_blit.h"
 #include "intel_regions.h"
 #include "drm.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 static int intelWaitIdleLocked( struct intel_context *intel )
 {
index 0fb33e27f476ebab4451c9a9a266c85991529a88..8db61267b5582cb95e72713a492ac962b1e50b33 100644 (file)
@@ -28,7 +28,7 @@
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 #include "enums.h"
 #include "imports.h"
 
index b78eba898ffa8fb20690a83250220def035e2ce2..9bf858cacb421d1bcd4f13036f6d8df7525028d3 100644 (file)
@@ -42,7 +42,7 @@
 #include "intel_context.h"
 #include "intel_regions.h"
 #include "intel_blit.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 #include "imports.h"
 
 /* XXX: Thread safety?
@@ -51,7 +51,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi
 {
    DBG("%s\n", __FUNCTION__);
    if (!region->map_refcount++) {
-      region->map = bmMapBuffer(intel, region->buffer, 0);
+      region->map = dri_bo_map(region->buffer, GL_TRUE);
       if (!region->map)
         region->map_refcount--;
    }
@@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel,
 {
    DBG("%s\n", __FUNCTION__);
    if (!--region->map_refcount) {
-      bmUnmapBuffer(intel, region->buffer);
+      dri_bo_unmap(region->buffer);
       region->map = NULL;
    }
 }
@@ -84,8 +84,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel,
    region->height = height;    /* needed? */
    region->refcount = 1;
 
-   bmGenBuffers(intel, "tex", 1, &region->buffer, 6);
-   bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0);
+   region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region",
+                                pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT);
 
    return region;
 }
@@ -108,7 +108,7 @@ void intel_region_release( struct intel_context *intel,
    
    if (--(*region)->refcount == 0) {
       assert((*region)->map_refcount == 0);
-      bmDeleteBuffers(intel, 1, &(*region)->buffer);
+      dri_bo_unreference((*region)->buffer);
       free(*region);
    }
    *region = NULL;
index d2235f1275bd19ba6f0b18146d2a9a3866aa1f4d..8505d7eedc2e3ccacc140c9c16e1ae49cfa9765d 100644 (file)
@@ -29,7 +29,7 @@
 #define INTEL_REGIONS_H
 
 #include "mtypes.h"
-#include "bufmgr.h"            /* for DBG! */
+#include "dri_bufmgr.h"                /* for DBG! */
 struct intel_context;
 
 /* A layer on top of the bufmgr buffers that adds a few useful things:
@@ -40,7 +40,7 @@ struct intel_context;
  * - Blitter commands for copying 2D regions between buffers.
  */
 struct intel_region {
-   struct buffer *buffer;
+   dri_bo *buffer;
    GLuint refcount;
    GLuint cpp;
    GLuint pitch;
index 5dac50df32c324c1986d0d5dba7b84d319b2d8f3..06bf9214f054be7fdaeb3bce7c746b960e66df78 100644 (file)
@@ -109,12 +109,18 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv)
       return GL_FALSE;
    }
 
-   if (drmMap(sPriv->fd,
-              intelScreen->tex.handle,
-              intelScreen->tex.size,
-              (drmAddress *)&intelScreen->tex.map) != 0) {
-      intelUnmapScreenRegions(intelScreen);
-      return GL_FALSE;
+   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;
    }
 
    if (0)
@@ -163,6 +169,32 @@ intelUnmapScreenRegions(intelScreenPrivate *intelScreen)
    }
 }
 
+/** 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 void
 intelPrintDRIInfo(intelScreenPrivate *intelScreen,
@@ -359,7 +391,19 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
       (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
       (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
    }
-   
+
+   assert(!intelScreen->ttm);
+   intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset,
+                                             intelScreen->tex.map,
+                                             intelScreen->tex.size,
+                                             intel_fence_emit,
+                                             intel_fence_wait,
+                                             intelScreen);
+   if (intelScreen->bufmgr == FALSE) {
+      fprintf(stderr, "Couldn't initialize buffer manager\n");
+      return GL_FALSE;
+   }
+
    return GL_TRUE;
 }
 
@@ -369,6 +413,7 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv)
    intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
 
    intelUnmapScreenRegions(intelScreen);
+   dri_bufmgr_destroy(intelScreen->bufmgr);
    FREE(intelScreen);
    sPriv->private = NULL;
 }
index bf9a716082d5888e1180362bbe57ada7c513c54e..bb004822c436242fc32aff38af87aa46806797f5 100644 (file)
@@ -80,6 +80,13 @@ typedef struct
     * Configuration cache with default values for all contexts 
     */
    driOptionCache optionCache;
+
+   /**
+    * This value indicates that the kernel memory manager is being used
+    * instead of the fake client-side memory manager.
+    */
+   GLboolean ttm;
+   dri_bufmgr *bufmgr;
 } intelScreenPrivate;
 
 
deleted file mode 120000 (symlink)
index fe61b441945e5da392ab2885bc12cca826004a55..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_layout.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..fcb5cc390682587c36db93ff630d339b71269e30
--- /dev/null
@@ -0,0 +1,102 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Michel Dänzer <michel@tungstengraphics.com>
+  */
+
+#include "intel_mipmap_tree.h"
+#include "intel_tex_layout.h"
+#include "macros.h"
+
+
+static int align(int value, int alignment)
+{
+   return (value + alignment - 1) & ~(alignment - 1);
+}
+
+void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
+{
+   GLint align_h = 2, align_w = 4;
+   GLuint level;
+   GLuint x = 0;
+   GLuint y = 0;
+   GLuint width = mt->width0;
+   GLuint height = mt->height0;
+
+   mt->pitch = mt->width0;
+
+   /* May need to adjust pitch to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (mt->first_level != mt->last_level) {
+      GLuint mip1_width = align(minify(mt->width0), align_w)
+                       + minify(minify(mt->width0));
+
+      if (mip1_width > mt->width0)
+        mt->pitch = mip1_width;
+   }
+
+   /* Pitch must be a whole number of dwords, even though we
+    * express it in texels.
+    */
+   mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
+   mt->total_height = 0;
+
+   for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+      GLuint img_height;
+
+      intel_miptree_set_level_info(mt, level, 1, x, y, width, 
+                                  height, 1);
+
+      if (mt->compressed)
+        img_height = MAX2(1, height/4);
+      else
+        img_height = align(height, align_h);
+
+
+      /* Because the images are packed better, the final offset
+       * might not be the maximal one:
+       */
+      mt->total_height = MAX2(mt->total_height, y + img_height);
+
+      /* Layout_below: step right after second mipmap.
+       */
+      if (level == mt->first_level + 1) {
+        x += align(width, align_w);
+      }
+      else {
+        y += img_height;
+      }
+
+      width  = minify(width);
+      height = minify(height);
+   }
+}
index 8c05e7cdabccf7177ef5461c0feefaab5878c506..0cfb32f76d19f895490bdc050bb5c68644572ba0 100644 (file)
@@ -31,7 +31,7 @@
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
-#include "bufmgr.h"
+#include "dri_bufmgr.h"
 
 /**
  * Compute which mipmap levels that really need to be sent to the hardware.
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
new file mode 100644 (file)
index 0000000..8ee48b5
--- /dev/null
@@ -0,0 +1,331 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "intel_batchbuffer.h"
+#include "intel_ioctl.h"
+#include "intel_decode.h"
+#include "i915_debug.h"
+
+/* Relocations in kernel space:
+ *    - pass dma buffer seperately
+ *    - memory manager knows how to patch
+ *    - pass list of dependent buffers
+ *    - pass relocation list
+ *
+ * Either:
+ *    - get back an offset for buffer to fire
+ *    - memory manager knows how to fire buffer
+ *
+ * Really want the buffer to be AGP and pinned.
+ *
+ */
+
+/* Cliprect fence: The highest fence protecting a dma buffer
+ * containing explicit cliprect information.  Like the old drawable
+ * lock but irq-driven.  X server must wait for this fence to expire
+ * before changing cliprects [and then doing sw rendering?].  For
+ * other dma buffers, the scheduler will grab current cliprect info
+ * and mix into buffer.  X server must hold the lock while changing
+ * cliprects???  Make per-drawable.  Need cliprects in shared memory
+ * -- beats storing them with every cmd buffer in the queue.
+ *
+ * ==> X server must wait for this fence to expire before touching the
+ * framebuffer with new cliprects.
+ *
+ * ==> Cliprect-dependent buffers associated with a
+ * cliprect-timestamp.  All of the buffers associated with a timestamp
+ * must go to hardware before any buffer with a newer timestamp.
+ *
+ * ==> Dma should be queued per-drawable for correct X/GL
+ * synchronization.  Or can fences be used for this?
+ *
+ * Applies to: Blit operations, metaops, X server operations -- X
+ * server automatically waits on its own dma to complete before
+ * modifying cliprects ???
+ */
+
+void
+intel_batchbuffer_reset(struct intel_batchbuffer *batch)
+{
+   struct intel_context *intel = batch->intel;
+
+   if (batch->buf != NULL) {
+      dri_bo_unreference(batch->buf);
+      batch->buf = NULL;
+   }
+
+   batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer",
+                            intel->intelScreen->maxBatchSize, 4096,
+                            DRM_BO_FLAG_MEM_TT);
+   dri_bo_map(batch->buf, GL_TRUE);
+   batch->map = batch->buf->virtual;
+   batch->size = intel->intelScreen->maxBatchSize;
+   batch->ptr = batch->map;
+}
+
+struct intel_batchbuffer *
+intel_batchbuffer_alloc(struct intel_context *intel)
+{
+   struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
+
+   batch->intel = intel;
+   batch->last_fence = NULL;
+   intel_batchbuffer_reset(batch);
+
+   return batch;
+}
+
+void
+intel_batchbuffer_free(struct intel_batchbuffer *batch)
+{
+   if (batch->last_fence) {
+      dri_fence_wait(batch->last_fence);
+      dri_fence_unreference(batch->last_fence);
+      batch->last_fence = NULL;
+   }
+   if (batch->map) {
+      dri_bo_unmap(batch->buf);
+      batch->map = NULL;
+   }
+   dri_bo_unreference(batch->buf);
+   batch->buf = NULL;
+   free(batch);
+}
+
+static int
+relocation_sort(const void *a_in, const void *b_in) {
+   const struct buffer_reloc *a = a_in, *b = b_in;
+
+   return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
+}
+
+
+/* TODO: Push this whole function into bufmgr.
+ */
+static void
+do_flush_locked(struct intel_batchbuffer *batch,
+                GLuint used,
+                GLboolean ignore_cliprects, GLboolean allow_unlock)
+{
+   GLuint *ptr;
+   GLuint i;
+   struct intel_context *intel = batch->intel;
+   dri_fence *fo;
+   GLboolean performed_rendering = GL_FALSE;
+
+   assert(batch->buf->virtual != NULL);
+   ptr = batch->buf->virtual;
+
+   /* Sort our relocation list in terms of referenced buffer pointer.
+    * This lets us uniquely validate the buffers with the sum of all the flags,
+    * while avoiding O(n^2) on number of relocations.
+    */
+   qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]),
+        relocation_sort);
+
+   /* Perform the necessary validations of buffers, and enter the relocations
+    * in the batchbuffer.
+    */
+   for (i = 0; i < batch->nr_relocs; i++) {
+      struct buffer_reloc *r = &batch->reloc[i];
+
+      if (r->validate_flags & DRM_BO_FLAG_WRITE)
+        performed_rendering = GL_TRUE;
+
+      /* If this is the first time we've seen this buffer in the relocation
+       * list, figure out our flags and validate it.
+       */
+      if (i == 0 || batch->reloc[i - 1].buf != r->buf) {
+        uint32_t validate_flags;
+        int j, ret;
+
+        /* Accumulate the flags we need for validating this buffer. */
+        validate_flags = r->validate_flags;
+        for (j = i + 1; j < batch->nr_relocs; j++) {
+           if (batch->reloc[j].buf != r->buf)
+              break;
+           validate_flags |= batch->reloc[j].validate_flags;
+        }
+
+        /* Validate.  If we fail, fence to clear the unfenced list and bail
+         * out.
+         */
+        ret = dri_bo_validate(r->buf, validate_flags);
+        if (ret != 0) {
+           dri_bo_unmap(batch->buf);
+           fo = dri_fence_validated(intel->intelScreen->bufmgr,
+                                    "batchbuffer failure fence", GL_TRUE);
+           dri_fence_unreference(fo);
+           goto done;
+        }
+      }
+      ptr[r->offset / 4] = r->buf->offset + r->delta;
+      dri_bo_unreference(r->buf);
+   }
+
+   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
+    * single buffer.
+    */
+
+   if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
+      intel_batch_ioctl(batch->intel,
+                        batch->buf->offset,
+                        used, ignore_cliprects, allow_unlock);
+   }
+
+   /* 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);
+
+   if (performed_rendering) {
+      dri_fence_unreference(batch->last_fence);
+      batch->last_fence = 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);
+      }
+      intel->vtbl.lost_hardware(intel);
+   }
+
+done:
+   if (INTEL_DEBUG & DEBUG_BATCH) {
+      dri_bo_map(batch->buf, GL_FALSE);
+      intel_decode(ptr, used / 4, batch->buf->offset);
+      dri_bo_unmap(batch->buf);
+   }
+}
+
+
+void
+intel_batchbuffer_flush(struct intel_batchbuffer *batch)
+{
+   struct intel_context *intel = batch->intel;
+   GLuint used = batch->ptr - batch->map;
+   GLboolean was_locked = intel->locked;
+
+   if (used == 0)
+      return;
+
+   /* Add the MI_BATCH_BUFFER_END.  Always add an MI_FLUSH - this is a
+    * performance drain that we would like to avoid.
+    */
+   if (used & 4) {
+      ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
+      ((int *) batch->ptr)[1] = 0;
+      ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END;
+      used += 12;
+   }
+   else {
+      ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
+      ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END;
+      used += 8;
+   }
+
+   /* TODO: Just pass the relocation list and dma buffer up to the
+    * kernel.
+    */
+   if (!was_locked)
+      LOCK_HARDWARE(intel);
+
+   do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
+                  GL_FALSE);
+
+   if (!was_locked)
+      UNLOCK_HARDWARE(intel);
+
+   /* Reset the buffer:
+    */
+   intel_batchbuffer_reset(batch);
+}
+
+void
+intel_batchbuffer_finish(struct intel_batchbuffer *batch)
+{
+   intel_batchbuffer_flush(batch);
+   if (batch->last_fence != NULL)
+      dri_fence_wait(batch->last_fence);
+}
+
+
+/*  This is the only way buffers get added to the validate list.
+ */
+GLboolean
+intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+                             dri_bo *buffer,
+                             GLuint flags, GLuint delta)
+{
+   struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
+
+   assert(batch->nr_relocs <= MAX_RELOCS);
+
+   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;
+}
+
+
+
+void
+intel_batchbuffer_data(struct intel_batchbuffer *batch,
+                       const void *data, GLuint bytes, GLuint flags)
+{
+   assert((bytes & 3) == 0);
+   intel_batchbuffer_require_space(batch, bytes, flags);
+   __memcpy(batch->ptr, data, bytes);
+   batch->ptr += bytes;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
new file mode 100644 (file)
index 0000000..850a91e
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef INTEL_BATCHBUFFER_H
+#define INTEL_BATCHBUFFER_H
+
+#include "mtypes.h"
+#include "dri_bufmgr.h"
+
+struct intel_context;
+
+#define BATCH_SZ 16384
+#define BATCH_RESERVED 16
+
+#define MAX_RELOCS 4096
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS    0x2
+
+struct buffer_reloc
+{
+   dri_bo *buf;
+   GLuint offset;
+   GLuint delta;                /* not needed? */
+   GLuint validate_flags;
+};
+
+struct intel_batchbuffer
+{
+   struct intel_context *intel;
+
+   dri_bo *buf;
+   dri_fence *last_fence;
+   GLuint flags;
+
+   drmBOList list;
+   GLuint list_count;
+   GLubyte *map;
+   GLubyte *ptr;
+
+   struct buffer_reloc reloc[MAX_RELOCS];
+   GLuint nr_relocs;
+   GLuint size;
+};
+
+struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
+                                                  *intel);
+
+void intel_batchbuffer_free(struct intel_batchbuffer *batch);
+
+
+void intel_batchbuffer_finish(struct intel_batchbuffer *batch);
+
+void intel_batchbuffer_flush(struct intel_batchbuffer *batch);
+
+void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
+
+
+/* Unlike bmBufferData, this currently requires the buffer be mapped.
+ * Consider it a convenience function wrapping multple
+ * intel_buffer_dword() calls.
+ */
+void intel_batchbuffer_data(struct intel_batchbuffer *batch,
+                            const void *data, GLuint bytes, GLuint flags);
+
+void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
+                                     GLuint bytes);
+
+GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
+                                       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
+ * be passed as structs rather than dwords, but that's a little bit of
+ * work...
+ */
+static INLINE GLuint
+intel_batchbuffer_space(struct intel_batchbuffer *batch)
+{
+   return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+}
+
+
+static INLINE void
+intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
+{
+   assert(batch->map);
+   assert(intel_batchbuffer_space(batch) >= 4);
+   *(GLuint *) (batch->ptr) = dword;
+   batch->ptr += 4;
+}
+
+static INLINE void
+intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
+                                GLuint sz, GLuint flags)
+{
+   assert(sz < batch->size - 8);
+   if (intel_batchbuffer_space(batch) < sz ||
+       (batch->flags != 0 && flags != 0 && batch->flags != flags))
+      intel_batchbuffer_flush(batch);
+
+   batch->flags |= flags;
+}
+
+/* Here are the crusty old macros, to be removed:
+ */
+#define BATCH_LOCALS
+
+#define BEGIN_BATCH(n, flags) do {                             \
+   assert(!intel->prim.flush);                                 \
+   intel_batchbuffer_require_space(intel->batch, (n)*4, flags);        \
+} while (0)
+
+#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d)
+
+#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)
+
+
+#endif