Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / drivers / dri / intel / intel_batchbuffer.c
index 803ff5e90ee382c96e9d477ecd99c90cde2b81c0..6aa36d10b1203c34c74fce7d439de8ec2ed07cfb 100644 (file)
  * 
  **************************************************************************/
 
+#include "intel_context.h"
 #include "intel_batchbuffer.h"
-#include "intel_ioctl.h"
 #include "intel_decode.h"
 #include "intel_reg.h"
+#include "intel_bufmgr.h"
+#include "intel_buffers.h"
 
 /* Relocations in kernel space:
  *    - pass dma buffer seperately
@@ -82,8 +84,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
       batch->buffer = malloc (intel->maxBatchSize);
 
    batch->buf = dri_bo_alloc(intel->bufmgr, "batchbuffer",
-                            intel->maxBatchSize, 4096,
-                            DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | DRM_BO_FLAG_CACHED_MAPPED);
+                            intel->maxBatchSize, 4096);
    if (batch->buffer)
       batch->map = batch->buffer;
    else {
@@ -94,10 +95,6 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
    batch->ptr = batch->map;
    batch->dirty_state = ~0;
    batch->cliprect_mode = IGNORE_CLIPRECTS;
-
-   /* account batchbuffer in aperture */
-   dri_bufmgr_check_aperture_space(batch->buf);
-
 }
 
 struct intel_batchbuffer *
@@ -137,6 +134,9 @@ do_flush_locked(struct intel_batchbuffer *batch,
 {
    struct intel_context *intel = batch->intel;
    int ret = 0;
+   unsigned int num_cliprects = 0;
+   struct drm_clip_rect *cliprects = NULL;
+   int x_off = 0, y_off = 0;
 
    if (batch->buffer)
       dri_bo_subdata (batch->buf, 0, used, batch->buffer);
@@ -146,36 +146,21 @@ do_flush_locked(struct intel_batchbuffer *batch,
    batch->map = NULL;
    batch->ptr = NULL;
 
-   /* 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 &&
-        batch->cliprect_mode == LOOP_CLIPRECTS)) {
-      if (intel->ttm == GL_TRUE) {
-        struct drm_i915_gem_execbuffer *execbuf;
-
-        execbuf = dri_process_relocs(batch->buf);
-        ret = intel_exec_ioctl(batch->intel,
-                               used,
-                               batch->cliprect_mode != LOOP_CLIPRECTS,
-                               allow_unlock,
-                               execbuf);
-      } else {
-        dri_process_relocs(batch->buf);
-        ret = intel_batch_ioctl(batch->intel,
-                                batch->buf->offset,
-                                used,
-                                batch->cliprect_mode != LOOP_CLIPRECTS,
-                                allow_unlock);
-      }
+   if (batch->cliprect_mode == LOOP_CLIPRECTS) {
+      intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
+   }
+   /* Dispatch the batchbuffer, if it has some effect (nonzero cliprects).
+    * Can't short-circuit like this once we have hardware contexts, but we
+    * should always be in DRI2 mode by then anyway.
+    */
+   if ((batch->cliprect_mode != LOOP_CLIPRECTS ||
+       num_cliprects != 0) && !intel->no_hw) {
+      dri_bo_exec(batch->buf, used, cliprects, num_cliprects,
+                 (x_off & 0xffff) | (y_off << 16));
    }
 
-   dri_post_submit(batch->buf);
-
-   if (intel->numClipRects == 0 &&
-       batch->cliprect_mode == LOOP_CLIPRECTS) {
+   if (batch->cliprect_mode == LOOP_CLIPRECTS && num_cliprects == 0) {
       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
@@ -210,17 +195,28 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
 {
    struct intel_context *intel = batch->intel;
    GLuint used = batch->ptr - batch->map;
-   GLboolean was_locked = intel->locked;
 
-   if (used == 0)
+   if (intel->first_post_swapbuffers_batch == NULL) {
+      intel->first_post_swapbuffers_batch = intel->batch->buf;
+      drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+   }
+
+   if (intel->first_post_swapbuffers_batch == NULL) {
+      intel->first_post_swapbuffers_batch = intel->batch->buf;
+      drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+   }
+
+   if (used == 0) {
+      batch->cliprect_mode = IGNORE_CLIPRECTS;
       return;
+   }
 
    if (INTEL_DEBUG & DEBUG_BATCH)
       fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
              used);
 
    /* Emit a flush if the bufmgr doesn't do it for us. */
-   if (!intel->ttm) {
+   if (intel->always_flush_cache || !intel->ttm) {
       *(GLuint *) (batch->ptr) = intel->vtbl.flush_cmd();
       batch->ptr += 4;
       used = batch->ptr - batch->map;
@@ -250,25 +246,20 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
     * avoid that in the first place. */
    batch->ptr = batch->map;
 
+   if (intel->vtbl.finish_batch)
+      intel->vtbl.finish_batch(intel);
+
    /* TODO: Just pass the relocation list and dma buffer up to the
     * kernel.
     */
-   if (!was_locked)
-      LOCK_HARDWARE(intel);
-
+   LOCK_HARDWARE(intel);
    do_flush_locked(batch, used, GL_FALSE);
-
-   if (!was_locked)
-      UNLOCK_HARDWARE(intel);
+   UNLOCK_HARDWARE(intel);
 
    if (INTEL_DEBUG & DEBUG_SYNC) {
-      int irq;
-
       fprintf(stderr, "waiting for idle\n");
-      LOCK_HARDWARE(intel);
-      irq = intelEmitIrqLocked(intel);
-      UNLOCK_HARDWARE(intel);
-      intelWaitIrq(intel, irq);
+      dri_bo_map(batch->buf, GL_TRUE);
+      dri_bo_unmap(batch->buf);
    }
 
    /* Reset the buffer:
@@ -290,8 +281,8 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
    if (batch->ptr - batch->map > batch->buf->size)
     _mesa_printf ("bad relocation ptr %p map %p offset %d size %d\n",
                  batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
-   ret = dri_emit_reloc(batch->buf, read_domains, write_domain,
-                       delta, batch->ptr - batch->map, buffer);
+   ret = dri_bo_emit_reloc(batch->buf, read_domains, write_domain,
+                          delta, batch->ptr - batch->map, buffer);
 
    /*
     * Using the old buffer offset, write in what the right data would be, in case