I've been toiling with mesa a bit and have what I believe to be the 
beginning of support for large resolution 3D. At this point it is very 
hacked together just so I can prove that it's possible. The theory of 
operation is to create an extra framebuffer and batchbuffer when a 
context is initialized. Everything that is sent to the first batchbuffer 
is also sent to the second batchbuffer, excepting that color and depth 
buffer addrs and scissor boxes are modified for the extra batchbuffer. 
At this point, I haven't looked too deep into when I need to call 
Viewport to change between the two framebuffer renders, but I will get 
to that later. In the copybuffers routine, I blit both buffers to the 
screen.

First, I want to know what others think of the theory. I have attached 
my patch to the i915tex_privbuffers branch driver below. If there are 
any architectural issues with my approach I would surely be interested 
to here them and how they might be addressed.

Secondly, in the current state I am having difficulties with an assert 
being tripped:

glxgears: i915_vtbl.c:439: i915_emit_state: Assertion 
`(state->Program[0] & 0x1ff) + 2 == state->ProgramSize' failed.

I noticed that if I comment out I915_UPLOAD_PROGRAM from the end of 
i915_init_packets():

    i915->state.active = (//I915_UPLOAD_PROGRAM |
                          I915_UPLOAD_STIPPLE |
                          I915_UPLOAD_CTX |
                          I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT);

the program does not hit the assert, but fails later with a segfault. I 
haven't tracked down that segfault yet, but I assume that I don't want 
to be changing the code in such a way. Can someone illuminate me as to 
what i915->state.active is used for? I have noticed that 
I915_STATECHANGE is used to set dirty bits and then emit the dirty state 
to the hardware. However, I915_STATECHANGE modifies state.emitted, not 
state.active. What is the difference between the two?

Thanks for any help,
Chase Douglas

diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h 
b/src/mesa/drivers/dri/i915tex/i915_context.h
index 3a41d66..5b3dbd8 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.h
+++ b/src/mesa/drivers/dri/i915tex/i915_context.h
@@ -203,6 +203,7 @@ struct i915_hw_state
  {
     GLuint Ctx[I915_CTX_SETUP_SIZE];
     GLuint Buffer[I915_DEST_SETUP_SIZE];
+   GLuint ExtraBuffer[I915_DEST_SETUP_SIZE];
     GLuint Stipple[I915_STP_SETUP_SIZE];
     GLuint Fog[I915_FOG_SETUP_SIZE];
     GLuint Defaults[I915_DEF_SETUP_SIZE];
@@ -216,6 +217,8 @@ struct i915_hw_state
      */
     struct intel_region *draw_region;
     struct intel_region *depth_region;
+   struct intel_region *extra_draw_region;
+   struct intel_region *extra_depth_region;
  /*    struct intel_region *tex_region[I915_TEX_UNITS]; */

     /* Regions aren't actually that appropriate here as the memory may
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c 
b/src/mesa/drivers/dri/i915tex/i915_state.c
index 1fede6a..150e157 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -368,6 +368,7 @@ i915Scissor(GLcontext * ctx, GLint x, GLint y, 
GLsizei w, GLsizei h)
  {
     struct i915_context *i915 = I915_CONTEXT(ctx);
     int x1, y1, x2, y2;
+   int ex1, ey1, ex2, ey2;

     if (!ctx->DrawBuffer)
        return;
@@ -390,17 +391,56 @@ i915Scissor(GLcontext * ctx, GLint x, GLint y, 
GLsizei w, GLsizei h)
        y2 = y + h - 1;
        DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, 
y1, y2);
     }
-
+
     x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);
     y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);
     x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);
     y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);
-
-   DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2);
+
+   if (x1 >= 2048) {
+      ex1 = x1;
+      ex2 = x2;
+      ey1 = y1;
+      ey2 = y2;
+      x1 = 0;
+      x2 = 0;
+   }
+   else if (x2 >= 2048) {
+      ex1 = 2048;
+      ex2 = x2;
+      ey1 = y1;
+      ey2 = y2;
+      x2 = 2047;
+   }
+   else if (y1 >= 2048) {
+      ex1 = x1;
+      ex2 = x2;
+      ey1 = y1;
+      ey2 = y2;
+      y1 = 0;
+      y2 = 0;
+   }
+   else if (y2 >= 2048) {
+      ex1 = x1;
+      ex2 = x2;
+      ey1 = 2048;
+      ey2 = y2;
+      y2 = 2047;
+   }
+   else {
+      ex1 = 0;
+      ex2 = 0;
+      ey1 = 0;
+      ey2 = 0;
+   }
+
+   DBG("%s %d..%d,%d..%d and %d..%d,%d..%d (clamped)\n", __FUNCTION__, 
x1, x2, y1, y2, ex1, ex2, ey1, ey2);

     I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
     i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
     i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
+   i915->state.ExtraBuffer[I915_DESTREG_SR1] = (ey1 << 16) | (ex1 & 
0xffff);
+   i915->state.ExtraBuffer[I915_DESTREG_SR1] = (ey2 << 16) | (ex2 & 
0xffff);
  }

  static void
@@ -913,7 +953,9 @@ i915_init_packets(struct i915_context *i915)
           (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
        i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
        i915->state.Buffer[I915_DESTREG_SR1] = 0;
+      i915->state.ExtraBuffer[I915_DESTREG_SR1] = 0;
        i915->state.Buffer[I915_DESTREG_SR2] = 0;
+      i915->state.ExtraBuffer[I915_DESTREG_SR2] = 0;
     }


diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c 
b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 13ca9ae..7dd4927 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -39,6 +39,7 @@
  #include "intel_batchbuffer.h"
  #include "intel_tex.h"
  #include "intel_regions.h"
+#include "intel_fbo.h"

  #include "i915_reg.h"
  #include "i915_context.h"
@@ -226,7 +227,8 @@ i915_emit_invarient_state(struct intel_context *intel)


  #define emit(intel, state, size )                  \
-   intel_batchbuffer_data(intel->batch, state, size, 0 )
+   intel_batchbuffer_data(intel->batch, state, size, 0 ); \
+   intel_batchbuffer_data(intel->extraBatch, state, size, 0)

  static GLuint
  get_dirty(struct i915_hw_state *state)
@@ -301,6 +303,7 @@ i915_emit_state(struct intel_context *intel)
      * batchbuffer fills up.
      */
     intel_batchbuffer_require_space(intel->batch, 
get_state_size(state), 0);
+   intel_batchbuffer_require_space(intel->extraBatch, 
get_state_size(state), 0);

     /* Do this here as we may have flushed the batchbuffer above,
      * causing more state to be dirty!
@@ -328,27 +331,39 @@ i915_emit_state(struct intel_context *intel)
           fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
        BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0);
        OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
-      OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
-      OUT_RELOC(state->draw_region->buffer,
-                DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
-                DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
-                state->draw_region->draw_offset);
+      OUT_BATCH_SINGLE(state->Buffer[I915_DESTREG_CBUFADDR1], GL_FALSE);
+      OUT_BATCH_SINGLE(state->ExtraBuffer[I915_DESTREG_CBUFADDR1], 
GL_TRUE);
+      OUT_RELOC_SINGLE(state->draw_region->buffer, //IMPORTANT: Draw 
Buffer Addr Here
+                       DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+                       DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+                       state->draw_region->draw_offset, GL_FALSE);
+      OUT_RELOC_SINGLE(state->extra_draw_region->buffer,
+                       DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+                       DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+                       state->extra_draw_region->draw_offset, GL_TRUE);

        if (state->depth_region) {
           OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
-         OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
-         OUT_RELOC(state->depth_region->buffer,
-                   DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
-                   DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
-                   state->depth_region->draw_offset);
+         OUT_BATCH_SINGLE(state->Buffer[I915_DESTREG_DBUFADDR1], GL_FALSE);
+         OUT_BATCH_SINGLE(state->ExtraBuffer[I915_DESTREG_DBUFADDR1], 
GL_TRUE);
+         OUT_RELOC_SINGLE(state->depth_region->buffer, //IMPORTANT: 
Depth Buffer Addr Here
+                          DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+                          DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+                          state->depth_region->draw_offset, GL_FALSE);
+         OUT_RELOC_SINGLE(state->extra_depth_region->buffer,
+                          DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+                          DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+                          state->extra_depth_region->draw_offset, GL_TRUE);
        }

        OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
        OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
        OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]);
        OUT_BATCH(state->Buffer[I915_DESTREG_SR0]);
-      OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
-      OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);
+      OUT_BATCH_SINGLE(state->Buffer[I915_DESTREG_SR1], GL_FALSE);
+      OUT_BATCH_SINGLE(state->ExtraBuffer[I915_DESTREG_SR1], GL_TRUE);
+      OUT_BATCH_SINGLE(state->Buffer[I915_DESTREG_SR2], GL_FALSE);
+      OUT_BATCH_SINGLE(state->ExtraBuffer[I915_DESTREG_SR2], GL_TRUE);
        ADVANCE_BATCH();
     }

@@ -419,7 +434,7 @@ i915_emit_state(struct intel_context *intel)

     if (dirty & I915_UPLOAD_PROGRAM) {
        if (INTEL_DEBUG & DEBUG_STATE)
-         fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
+         fprintf(stderr, "I915_UPLOAD_PROGRAM: state->Program[0] = %d, 
state->ProgramSize = %d\n", state->Program[0], state->ProgramSize);

        assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize);

@@ -451,17 +466,51 @@ i915_state_draw_region(struct intel_context *intel,
                         struct intel_region *depth_region)
  {
     struct i915_context *i915 = i915_context(&intel->ctx);
+   struct intel_framebuffer *ifb = intel->driDrawable->driverPrivate;
+   struct intel_region *extra_color_region;
+   struct intel_region *extra_depth_region;
+   GLuint color_index;
+   GLuint depth_index;
     GLuint value;

     ASSERT(state == &i915->state || state == &i915->meta);

+   /*
+    * Find which regions color_region and depth_region are
+    */
+   if (color_region) {
+      for (color_index = 0; color_index < BUFFER_COUNT; color_index++)
+         if ((struct intel_renderbuffer 
*)ifb->Base.Attachment[color_index].Renderbuffer &&
+             color_region == ((struct intel_renderbuffer 
*)ifb->Base.Attachment[color_index].Renderbuffer)->region)
+            break;
+
+      extra_color_region = ((struct intel_renderbuffer 
*)ifb->Base.Attachment[color_index].Renderbuffer)->region;
+   }
+   else
+      extra_color_region = NULL;
+
+   if (depth_region) {
+      for (depth_index = 0; depth_index < BUFFER_COUNT; depth_index++)
+         if ((struct intel_renderbuffer 
*)ifb->Base.Attachment[depth_index].Renderbuffer &&
+             depth_region == ((struct intel_renderbuffer 
*)ifb->Base.Attachment[depth_index].Renderbuffer)->region)
+            break;
+
+      extra_depth_region = ((struct intel_renderbuffer 
*)ifb->Base.Attachment[depth_index].Renderbuffer)->region;
+   }
+   else
+      extra_depth_region = NULL;
+
     if (state->draw_region != color_region) {
        intel_region_release(&state->draw_region);
        intel_region_reference(&state->draw_region, color_region);
+      intel_region_release(&state->extra_draw_region);
+      intel_region_reference(&state->extra_draw_region, 
extra_color_region);
     }
     if (state->depth_region != depth_region) {
        intel_region_release(&state->depth_region);
        intel_region_reference(&state->depth_region, depth_region);
+      intel_region_release(&state->extra_depth_region);
+      intel_region_reference(&state->extra_depth_region, 
extra_depth_region);
     }

     /*
@@ -474,6 +523,10 @@ i915_state_draw_region(struct intel_context *intel,
           (BUF_3D_ID_COLOR_BACK |
            BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
            BUF_3D_USE_FENCE);
+      state->ExtraBuffer[I915_DESTREG_CBUFADDR1] =
+         (BUF_3D_ID_COLOR_BACK |
+          BUF_3D_PITCH(extra_color_region->pitch * 
extra_color_region->cpp) |
+          BUF_3D_USE_FENCE);
     }

     if (depth_region) {
@@ -483,6 +536,10 @@ i915_state_draw_region(struct intel_context *intel,
           (BUF_3D_ID_DEPTH |
            BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
            BUF_3D_USE_FENCE);
+      state->ExtraBuffer[I915_DESTREG_DBUFADDR1] =
+         (BUF_3D_ID_DEPTH |
+          BUF_3D_PITCH(extra_depth_region->pitch * 
extra_depth_region->cpp) |
+          BUF_3D_USE_FENCE);
     }

     /*
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c 
b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index c92b83b..0c36124 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
@@ -27,6 +27,8 @@

  #include "intel_batchbuffer.h"
  #include "intel_ioctl.h"
+#include "i915_context.h"
+#include "i830_context.h"

  /* Relocations in kernel space:
   *    - pass dma buffer seperately
@@ -118,6 +120,12 @@ intel_batchbuffer_reset(struct intel_batchbuffer 
*batch)

     batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
     batch->ptr = batch->map;
+
+   // FIXME: Need to determine i915 or i830 routines
+   if (i915_context(&batch->intel->ctx)->current) {
+      I915_STATECHANGE(I915_CONTEXT(&batch->intel->ctx), 
I915_UPLOAD_BUFFERS);
+      batch->intel->vtbl.emit_state(batch->intel);
+   }
  }

  /*======================================================================
@@ -127,15 +135,23 @@ struct intel_batchbuffer *
  intel_batchbuffer_alloc(struct intel_context *intel)
  {
     struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
+   struct intel_batchbuffer *extraBatch = calloc(sizeof(*extraBatch), 1);

     batch->intel = intel;
+   extraBatch->intel = intel;

     driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1,
                   &batch->buffer, 4096,
                   DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0);
+   driGenBuffers(intel->intelScreen->batchPool, "extrabatchbuffer", 1,
+                 &extraBatch->buffer, 4096,
+                 DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0);
     batch->last_fence = NULL;
+   extraBatch->last_fence = NULL;
     driBOCreateList(20, &batch->list);
+   driBOCreateList(20, &extraBatch->list);
     intel_batchbuffer_reset(batch);
+   intel_batchbuffer_reset(extraBatch);
     return batch;
  }

@@ -200,7 +216,8 @@ do_flush_locked(struct intel_batchbuffer *batch,
     if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
        intel_batch_ioctl(batch->intel,
                          driBOOffset(batch->buffer),
-                        used, ignore_cliprects, allow_unlock);
+                        used, ignore_cliprects, allow_unlock,
+                        batch == intel->extraBatch);
     }


@@ -257,6 +274,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer 
*batch)
     if (used == 0)
        return batch->last_fence;

+   if (intel->extraBatch == batch && !intel->doExtraBuffer) {
+     driBOUnmap(batch->buffer);
+     batch->ptr = NULL;
+     batch->map = NULL;
+     intel_batchbuffer_reset(batch);
+     return batch->last_fence;
+   }
+
     /* Add the MI_BATCH_BUFFER_END.  Always add an MI_FLUSH - this is a
      * performance drain that we would like to avoid.
      */
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h 
b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
index 212f130..0517f60 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
@@ -111,11 +111,26 @@ intel_batchbuffer_require_space(struct 
intel_batchbuffer *batch,
     intel_batchbuffer_require_space(intel->batch, (n)*4, flags);       \
  } while (0)

-#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d)
+#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d); \
+                      intel_batchbuffer_emit_dword(intel->extraBatch, d)
+#define OUT_BATCH_SINGLE(d, extra)  \
+   if (!extra) \
+      intel_batchbuffer_emit_dword(intel->batch, d); \
+   else \
+      intel_batchbuffer_emit_dword(intel->extraBatch, d)

  #define OUT_RELOC(buf,flags,mask,delta) do {                          \
     assert((delta) >= 0);                                                      
\
     intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta);       
\
+   intel_batchbuffer_emit_reloc(intel->extraBatch, buf, flags, mask, 
delta); \
+} while (0)
+
+#define OUT_RELOC_SINGLE(buf,flags,mask,delta,extra) do { \
+   assert((delta) >= 0); \
+   if (!extra) \
+      intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, 
delta); \
+   else \
+      intel_batchbuffer_emit_reloc(intel->extraBatch, buf, flags, mask, 
delta); \
  } while (0)

  #define ADVANCE_BATCH() do { } while(0)
diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c 
b/src/mesa/drivers/dri/i915tex/intel_blit.c
index 28441f4..76604b6 100644
--- a/src/mesa/drivers/dri/i915tex/intel_blit.c
+++ b/src/mesa/drivers/dri/i915tex/intel_blit.c
@@ -44,6 +44,7 @@

  #define FILE_DEBUG_FLAG DEBUG_BLIT

+//IMPORTANT: Shift region to draw to here
  /**
   * Copy the back color buffer to the front color buffer.
   * Used for SwapBuffers().
@@ -185,6 +186,145 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
         driFenceUnReference(intel->first_swap_fence);
        intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
        driFenceReference(intel->first_swap_fence);
+
+      UNLOCK_HARDWARE(intel);
+
+      if (intel->last_swap_fence) {
+         driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, 
GL_TRUE);
+         driFenceUnReference(intel->last_swap_fence);
+         intel->last_swap_fence = NULL;
+      }
+
+      LOCK_HARDWARE(intel);
+
+      intel->last_swap_fence = intel->first_swap_fence;
+      intel->first_swap_fence = intel_batchbuffer_flush(intel->extraBatch);
+      driFenceReference(intel->first_swap_fence);
+   }
+
+   if (intel->doExtraBuffer && intel->numExtraClipRects) {
+      struct intel_framebuffer *intel_fb = intel->extraBuffer;
+      const struct intel_region *frontRegion
+            = intelScreen->front_region;
+      const struct intel_region *backRegion
+            = intel_fb->Base._ColorDrawBufferMask[0] == 
BUFFER_BIT_FRONT_LEFT ?
+          intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT) :
+            intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
+      const int backWidth = intel_fb->Base.Width;
+      const int backHeight = intel_fb->Base.Height;
+      const int nbox = intel->numExtraClipRects;
+      const drm_clip_rect_t *pbox = intel->pExtraClipRects;
+      const int pitch = frontRegion->pitch;
+      const int srcpitch = backRegion->pitch;
+      const int cpp = frontRegion->cpp;
+      int BR13, CMD;
+      int i;
+
+      ASSERT(intel_fb);
+      ASSERT(intel_fb->Base.Name == 0);    /* Not a user-created FBO */
+      ASSERT(frontRegion);
+      ASSERT(backRegion);
+      ASSERT(frontRegion->cpp == backRegion->cpp);
+
+      DBG("front pitch %d back pitch %d\n",
+          frontRegion->pitch, backRegion->pitch);
+
+      if (cpp == 2) {
+         BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+         CMD = XY_SRC_COPY_BLT_CMD;
+      }
+      else {
+         BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+         CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+               XY_SRC_COPY_BLT_WRITE_RGB);
+      }
+
+      for (i = 0; i < nbox; i++, pbox++) {
+         drm_clip_rect_t box;
+         drm_clip_rect_t sbox;
+
+         if (pbox->x1 > pbox->x2 ||
+             pbox->y1 > pbox->y2 ||
+             pbox->x2 > intelScreen->width || pbox->y2 > 
intelScreen->height)
+            continue;
+
+         box = *pbox;
+
+         if (rect) {
+            drm_clip_rect_t rrect;
+
+            rrect.x1 = dPriv->x + rect->x1;
+            rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
+            rrect.x2 = rect->x2 + rrect.x1;
+            rrect.y2 = rect->y2 + rrect.y1;
+            if (rrect.x1 > box.x1)
+               box.x1 = rrect.x1;
+            if (rrect.y1 > box.y1)
+               box.y1 = rrect.y1;
+            if (rrect.x2 < box.x2)
+               box.x2 = rrect.x2;
+            if (rrect.y2 < box.y2)
+               box.y2 = rrect.y2;
+
+            if (box.x1 > box.x2 || box.y1 > box.y2)
+               continue;
+         }
+
+         /* restrict blit to size of actually rendered area */
+         if (box.x2 - box.x1 > backWidth)
+            box.x2 = backWidth + box.x1;
+         if (box.y2 - box.y1 > backHeight)
+            box.y2 = backHeight + box.y1;
+
+         DBG("box x1 x2 y1 y2 %d %d %d %d\n",
+             box.x1, box.x2, box.y1, box.y2);
+
+         sbox.x1 = box.x1 - dPriv->x;
+         sbox.y1 = box.y1 - dPriv->y;
+
+         BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+         OUT_BATCH(CMD);
+         OUT_BATCH(BR13);
+         OUT_BATCH((box.y1 << 16) | (box.x1 + 2048)); // FIX: Need to 
fix in case of vertical orientation
+         OUT_BATCH((box.y2 << 16) | (box.x2 + 2048));
+
+         OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | 
DRM_BO_FLAG_WRITE,
+                   DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+         OUT_BATCH((sbox.y1 << 16) | sbox.x1);
+         OUT_BATCH((srcpitch * cpp) & 0xffff);
+         OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | 
DRM_BO_FLAG_READ,
+                   DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
+
+         ADVANCE_BATCH();
+      }
+
+      UNLOCK_HARDWARE(intel);
+
+      if (intel->last_swap_fence) {
+         driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, 
GL_TRUE);
+         driFenceUnReference(intel->last_swap_fence);
+         intel->last_swap_fence = NULL;
+      }
+
+      LOCK_HARDWARE(intel);
+
+      intel->last_swap_fence = intel->first_swap_fence;
+      intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
+      driFenceReference(intel->first_swap_fence);
+
+      UNLOCK_HARDWARE(intel);
+
+      if (intel->last_swap_fence) {
+         driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, 
GL_TRUE);
+         driFenceUnReference(intel->last_swap_fence);
+         intel->last_swap_fence = NULL;
+      }
+
+      LOCK_HARDWARE(intel);
+
+      intel->last_swap_fence = intel->first_swap_fence;
+      intel->first_swap_fence = intel_batchbuffer_flush(intel->extraBatch);
+      driFenceReference(intel->first_swap_fence);
     }

     UNLOCK_HARDWARE(intel);
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c 
b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index 4b2a4ac..324afcc 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -139,11 +139,31 @@ intelSetRenderbufferClipRects(struct intel_context 
*intel)
     intel->fboRect.y1 = 0;
     intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
     intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
+   if (intel->doExtraBuffer) {
+      if (intel->ctx.DrawBuffer->Width > 2048) {
+         intel->fboRect.x2 = 2048;
+         intel->extraFboRect.x1 = 2048;
+         intel->extraFboRect.x2 = intel->ctx.DrawBuffer->Width;
+         intel->extraFboRect.y1 = intel->fboRect.y1;
+         intel->extraFboRect.y2 = intel->fboRect.y2;
+      }
+      else {
+         intel->fboRect.y2 = 2048;
+         intel->extraFboRect.x1 = intel->fboRect.x1;
+         intel->extraFboRect.x2 = intel->fboRect.x2;
+         intel->extraFboRect.y1 = 2048;
+         intel->extraFboRect.y2 = intel->ctx.DrawBuffer->Height;
+      }
+   }
     intel->numClipRects = 1;
     intel->pClipRects = &intel->fboRect;
+   if (intel->doExtraBuffer) {
+      intel->numExtraClipRects = 1;
+      intel->pExtraClipRects = &intel->extraFboRect;
+   }
  }

-
+//IMPORTANT: When window size increases beyond 2048x2048, detect here
  /**
   * This will be called whenever the currently bound window is 
moved/resized.
   * XXX: actually, it seems to NOT be called when the window is only 
moved (BP).
@@ -161,6 +181,14 @@ intelWindowMoved(struct intel_context *intel)
        intel->numClipRects = 0;
     }

+   if (dPriv->w > 2048 || dPriv->h > 2048) {
+      intel->doExtraBuffer = GL_TRUE;
+   }
+
+   if (intel->doExtraBuffer && dPriv->w < 2048 && dPriv->h < 2048) {
+      intel->doExtraBuffer = GL_FALSE;
+   }
+
     /* Update Mesa's notion of window size */
     driUpdateFramebufferSize(ctx, dPriv);
     intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c 
b/src/mesa/drivers/dri/i915tex/intel_context.c
index f032c97..2022d46 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -357,6 +357,7 @@ intelInitContext(struct intel_context *intel,
     GLcontext *ctx = &intel->ctx;
     GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
     __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate fake;
     intelScreenPrivate *intelScreen = (intelScreenPrivate *) 
sPriv->private;
     drmI830Sarea *saPriv = (drmI830Sarea *)
        (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset);
@@ -481,6 +482,14 @@ intelInitContext(struct intel_context *intel,
     intel->last_swap_fence = NULL;
     intel->first_swap_fence = NULL;

+   intel->extraBatch = intel_batchbuffer_alloc(intel);
+   if (!intel->driScreen->DriverAPI.CreateBuffer(intel->driScreen, 
&fake, mesaVis, GL_FALSE))
+      fprintf(stderr, "Could not allocate extra frame buffer. Will not 
display beyond 2048x2048\n");
+   else {
+      intel->extraBuffer = fake.driverPrivate;
+      fprintf(stderr, "Successfully created extra buffer\n");
+   }
+
     intel_bufferobj_init(intel);
     intel_fbo_init(intel);

@@ -512,6 +521,7 @@ intelDestroyContext(__DRIcontextPrivate * 
driContextPriv)
  {
     struct intel_context *intel =
        (struct intel_context *) driContextPriv->driverPrivate;
+   __DRIdrawablePrivate fake;

     assert(intel);               /* should never be null */
     if (intel) {
@@ -530,6 +540,11 @@ intelDestroyContext(__DRIcontextPrivate * 
driContextPriv)
        intel->Fallback = 0;      /* don't call _swrast_Flush later */

        intel_batchbuffer_free(intel->batch);
+      intel_batchbuffer_free(intel->extraBatch);
+
+      fake.driverPrivate = intel->extraBuffer;
+      intel->driScreen->DriverAPI.DestroyBuffer(&fake);
+      fprintf(stderr, "Freed extra buffer\n");

        if (intel->last_swap_fence) {
         driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h 
b/src/mesa/drivers/dri/i915tex/intel_context.h
index ee5be45..de6aace 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -190,6 +190,7 @@ struct intel_context
     struct _DriFenceObject *first_swap_fence;

     struct intel_batchbuffer *batch;
+   struct intel_batchbuffer *extraBatch;

     struct
     {
@@ -245,8 +246,11 @@ struct intel_context
     /* These refer to the current drawing buffer:
      */
     GLuint numClipRects;         /**< cliprects for drawing */
+   GLuint numExtraClipRects;
     drm_clip_rect_t *pClipRects;
+   drm_clip_rect_t *pExtraClipRects;
     drm_clip_rect_t fboRect;     /**< cliprect for rendering */
+   drm_clip_rect_t extraFboRect;

     GLuint do_usleeps;
     int do_irqs;
@@ -262,6 +266,9 @@ struct intel_context
     intelScreenPrivate *intelScreen;
     drmI830Sarea *sarea;

+   struct intel_framebuffer *extraBuffer;
+   GLboolean doExtraBuffer;
+
     GLuint lastStamp;

     /**
@@ -340,7 +347,7 @@ __memcpy(void *to, const void *from, size_t n)
  #if DO_DEBUG
  extern int INTEL_DEBUG;
  #else
-#define INTEL_DEBUG            0
+#define INTEL_DEBUG            DEBUG_STATE
  #endif

  #define DEBUG_TEXTURE 0x1
diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c 
b/src/mesa/drivers/dri/i915tex/intel_ioctl.c
index 54721c7..350de7b 100644
--- a/src/mesa/drivers/dri/i915tex/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c
@@ -93,7 +93,8 @@ void
  intel_batch_ioctl(struct intel_context *intel,
                    GLuint start_offset,
                    GLuint used,
-                  GLboolean ignore_cliprects, GLboolean allow_unlock)
+                  GLboolean ignore_cliprects, GLboolean allow_unlock,
+                  GLboolean extraBatch)
  {
     drmI830BatchBuffer batch;

@@ -113,8 +114,14 @@ intel_batch_ioctl(struct intel_context *intel,

     batch.start = start_offset;
     batch.used = used;
-   batch.cliprects = intel->pClipRects;
-   batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+   if (extraBatch) {
+      batch.cliprects = intel->pClipRects;
+      batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+   }
+   else {
+      batch.cliprects = intel->pExtraClipRects;
+      batch.num_cliprects = ignore_cliprects ? 0 : 
intel->numExtraClipRects;
+   }
     batch.DR1 = 0;
     batch.DR4 = 0; /* still need this ? */

diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h 
b/src/mesa/drivers/dri/i915tex/intel_ioctl.h
index e8d07de..0b28c65 100644
--- a/src/mesa/drivers/dri/i915tex/intel_ioctl.h
+++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.h
@@ -36,5 +36,6 @@ int intelEmitIrqLocked(struct intel_context *intel);
  void intel_batch_ioctl(struct intel_context *intel,
                         GLuint start_offset,
                         GLuint used,
-                       GLboolean ignore_cliprects, GLboolean allow_unlock);
+                       GLboolean ignore_cliprects, GLboolean allow_unlock,
+                       GLboolean extraBatch);
  #endif
diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c 
b/src/mesa/drivers/dri/i915tex/intel_state.c
index 5c5f2c6..2bca065 100644
--- a/src/mesa/drivers/dri/i915tex/intel_state.c
+++ b/src/mesa/drivers/dri/i915tex/intel_state.c
@@ -189,7 +189,7 @@ intelClearColor(GLcontext * ctx, const GLfloat color[4])
     intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], 
clear[2]);
  }

-
+//IMPORTANT: Shift image in viewport here
  /**
   * Update the viewport transformation matrix.  Depends on:
   *  - viewport pos/size
@@ -218,6 +218,13 @@ intelCalcViewport(GLcontext * ctx)
        yBias = 0.0;
     }

+   /*if (intel->extraBufferNow) {
+      if (ctx->DrawBuffer->Width > 2048)
+         v[MAT_TX] -= 2048;
+      else
+         v[MAT_TY] -= 2048;
+   }*/
+
     m[MAT_SX] = v[MAT_SX];
     m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to