Merge branch 'mesa_7_5_branch'
[mesa.git] / src / mesa / drivers / dri / intel / intel_batchbuffer.h
index 80b87b40f797078702949ffa05d616f6907867b4..51579df09e771a9750cedaa0520378577ee78101 100644 (file)
@@ -1,13 +1,12 @@
 #ifndef INTEL_BATCHBUFFER_H
 #define INTEL_BATCHBUFFER_H
 
-#include "mtypes.h"
+#include "main/mtypes.h"
 
-#include "dri_bufmgr.h"
+#include "intel_context.h"
+#include "intel_bufmgr.h"
 #include "intel_reg.h"
 
-struct intel_context;
-
 #define BATCH_SZ 16384
 #define BATCH_RESERVED 16
 
@@ -20,6 +19,9 @@ enum cliprect_mode {
    /**
     * Batchbuffer contents require looping over per cliprect at batch submit
     * time.
+    *
+    * This will be upgraded to NO_LOOP_CLIPRECTS when there's a single
+    * constant cliprect, as in DRI2 or FBO rendering.
     */
    LOOP_CLIPRECTS,
    /**
@@ -30,8 +32,10 @@ enum cliprect_mode {
    /**
     * Batchbuffer contents contain drawing that already handles cliprects, such
     * as 2D drawing to front/back/depth that doesn't respect DRAWING_RECTANGLE.
+    *
     * Equivalent behavior to NO_LOOP_CLIPRECTS, but may not persist in batch
-    * outside of LOCK/UNLOCK.
+    * outside of LOCK/UNLOCK.  This is upgraded to just NO_LOOP_CLIPRECTS when
+    * there's a constant cliprect, as in DRI2 or FBO rendering.
     */
    REFERENCES_CLIPRECTS
 };
@@ -51,6 +55,12 @@ struct intel_batchbuffer
 
    GLuint size;
 
+   /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
+   struct {
+      GLuint total;
+      GLubyte *start_ptr;
+   } emit;
+
    GLuint dirty_state;
 };
 
@@ -116,12 +126,19 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
    if (intel_batchbuffer_space(batch) < sz)
       intel_batchbuffer_flush(batch);
 
+   if ((cliprect_mode == LOOP_CLIPRECTS ||
+       cliprect_mode == REFERENCES_CLIPRECTS) &&
+       batch->intel->constant_cliprect)
+      cliprect_mode = NO_LOOP_CLIPRECTS;
+
    if (cliprect_mode != IGNORE_CLIPRECTS) {
       if (batch->cliprect_mode == IGNORE_CLIPRECTS) {
         batch->cliprect_mode = cliprect_mode;
       } else {
-        if (batch->cliprect_mode != cliprect_mode)
+        if (batch->cliprect_mode != cliprect_mode) {
            intel_batchbuffer_flush(batch);
+           batch->cliprect_mode = cliprect_mode;
+        }
       }
    }
 }
@@ -132,9 +149,12 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
 
 #define BEGIN_BATCH(n, cliprect_mode) do {                             \
    intel_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \
+   assert(intel->batch->emit.start_ptr == NULL);                       \
+   intel->batch->emit.total = (n) * 4;                                 \
+   intel->batch->emit.start_ptr = intel->batch->ptr;                   \
 } while (0)
 
-#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d)
+#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
 
 #define OUT_RELOC(buf, read_domains, write_domain, delta) do {         \
    assert((delta) >= 0);                                               \
@@ -142,7 +162,16 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
                                read_domains, write_domain, delta);     \
 } while (0)
 
-#define ADVANCE_BATCH() do { } while(0)
+#define ADVANCE_BATCH() do {                                           \
+   unsigned int _n = intel->batch->ptr - intel->batch->emit.start_ptr; \
+   assert(intel->batch->emit.start_ptr != NULL);                       \
+   if (_n != intel->batch->emit.total) {                               \
+      fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",      \
+             _n, intel->batch->emit.total);                            \
+      abort();                                                         \
+   }                                                                   \
+   intel->batch->emit.start_ptr = NULL;                                        \
+} while(0)
 
 
 static INLINE void