Mesa (master): i965: Add support for accelerated CopyTexSubImage.

Eric Anholt anholt at kemper.freedesktop.org
Fri Nov 21 09:36:10 UTC 2008


Module: Mesa
Branch: master
Commit: 3e0164aabb48a99fce58964cad99fd3978ee84f6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3e0164aabb48a99fce58964cad99fd3978ee84f6

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Nov 21 17:09:47 2008 +0800

i965: Add support for accelerated CopyTexSubImage.

There were hacks in EmitCopyBlit before to adjust offsets so that y=0 after
the offsets had been adjusted for a negative pitch.  It appears that those
hacks were due to an unclear and surprising aspect of the hardware: inverting
the pitch results in the blit into the specified rectangle being inverted,
without the user needing to adjust y and base offset.

Tested with piglit copytexsubimage test on 915GM and GM965.  Should fix
serious performance issues with ETQW and other applications.

---

 src/mesa/drivers/dri/intel/intel_blit.c     |   64 ++++++++-------------------
 src/mesa/drivers/dri/intel/intel_tex.c      |    7 ---
 src/mesa/drivers/dri/intel/intel_tex_copy.c |   38 +++++++++-------
 3 files changed, 41 insertions(+), 68 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index e1046f4..ab12aae 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -40,6 +40,7 @@
 #include "intel_reg.h"
 #include "intel_regions.h"
 #include "intel_batchbuffer.h"
+#include "intel_chipset.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
@@ -359,51 +360,24 @@ intelEmitCopyBlit(struct intel_context *intel,
       return;
    }
 
-   /* Initial y values don't seem to work with negative pitches.  If
-    * we adjust the offsets manually (below), it seems to work fine.
-    *
-    * On the other hand, if we always adjust, the hardware doesn't
-    * know which blit directions to use, so overlapping copypixels get
-    * the wrong result.
-    */
-   if (dst_pitch > 0 && src_pitch > 0) {
-      assert(dst_x < dst_x2);
-      assert(dst_y < dst_y2);
-
-      BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
-      OUT_BATCH(CMD);
-      OUT_BATCH(BR13 | dst_pitch);
-      OUT_BATCH((dst_y << 16) | dst_x);
-      OUT_BATCH((dst_y2 << 16) | dst_x2);
-      OUT_RELOC(dst_buffer,
-		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-		dst_offset);
-      OUT_BATCH((src_y << 16) | src_x);
-      OUT_BATCH(src_pitch);
-      OUT_RELOC(src_buffer,
-		I915_GEM_DOMAIN_RENDER, 0,
-		src_offset);
-      ADVANCE_BATCH();
-   }
-   else {
-      assert(dst_x < dst_x2);
-      assert(h > 0);
-
-      BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
-      OUT_BATCH(CMD);
-      OUT_BATCH(BR13 | ((uint16_t)dst_pitch));
-      OUT_BATCH((0 << 16) | dst_x);
-      OUT_BATCH((h << 16) | dst_x2);
-      OUT_RELOC(dst_buffer,
-		I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-		dst_offset + dst_y * dst_pitch);
-      OUT_BATCH((0 << 16) | src_x);
-      OUT_BATCH(src_pitch);
-      OUT_RELOC(src_buffer,
-		I915_GEM_DOMAIN_RENDER, 0,
-		src_offset + src_y * src_pitch);
-      ADVANCE_BATCH();
-   }
+   assert(dst_x < dst_x2);
+   assert(dst_y < dst_y2);
+
+   BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
+   OUT_BATCH(CMD);
+   OUT_BATCH(BR13 | (uint16_t)dst_pitch);
+   OUT_BATCH((dst_y << 16) | dst_x);
+   OUT_BATCH((dst_y2 << 16) | dst_x2);
+   OUT_RELOC(dst_buffer,
+	     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+	     dst_offset);
+   OUT_BATCH((src_y << 16) | src_x);
+   OUT_BATCH((uint16_t)src_pitch);
+   OUT_RELOC(src_buffer,
+	     I915_GEM_DOMAIN_RENDER, 0,
+	     src_offset);
+   ADVANCE_BATCH();
+
    intel_batchbuffer_emit_mi_flush(intel->batch);
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
index 23455a4..82f8b87 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -222,17 +222,10 @@ intelInitTextureFuncs(struct dd_function_table *functions)
    functions->TexSubImage1D = intelTexSubImage1D;
    functions->TexSubImage2D = intelTexSubImage2D;
    functions->TexSubImage3D = intelTexSubImage3D;
-#ifdef I915
    functions->CopyTexImage1D = intelCopyTexImage1D;
    functions->CopyTexImage2D = intelCopyTexImage2D;
    functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
    functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
-#else
-   functions->CopyTexImage1D = _swrast_copy_teximage1d;
-   functions->CopyTexImage2D = _swrast_copy_teximage2d;
-   functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
-   functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
-#endif
    functions->GetTexImage = intelGetTexImage;
    functions->GenerateMipmap = intelGenerateMipmap;
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index f4cb4a7..36446ef 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -114,43 +114,49 @@ do_copy_texsubimage(struct intel_context *intel,
 
       if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax,
                                &x, &y, &width, &height)) {
+	 GLshort src_pitch;
+
          /* Update dst for clipped src.  Need to also clip the source rect.
           */
          dstx += x - orig_x;
          dsty += y - orig_y;
 
+	 /* image_offset may be non-page-aligned, but that's illegal for tiling.
+	  */
+	 assert(intelImage->mt->region->tiling == I915_TILING_NONE);
+
          if (ctx->ReadBuffer->Name == 0) {
             /* reading from a window, adjust x, y */
             __DRIdrawablePrivate *dPriv = intel->driDrawable;
-            GLuint window_y;
-            /* window_y = position of window on screen if y=0=bottom */
-            window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
-            y = window_y + y;
+	    y = dPriv->y + (dPriv->h - (y + height));
             x += dPriv->x;
+
+	    /* Invert the data coming from the source rectangle due to GL
+	     * and hardware disagreeing on where y=0 is.
+	     *
+	     * It appears that our offsets and pitches get mangled
+	     * appropriately by the hardware, and we don't need to adjust them
+	     * on our own.
+	     */
+	    src_pitch = -src->pitch;
          }
          else {
-            /* reading from a FBO */
-            /* invert Y */
-            y = ctx->ReadBuffer->Height - y - 1;
+            /* reading from a FBO, y is already oriented the way we like */
+	    src_pitch = src->pitch;
          }
 
-
-         /* A bit of fiddling to get the blitter to work with -ve
-          * pitches.  But we get a nice inverted blit this way, so it's
-          * worth it:
-          */
          intelEmitCopyBlit(intel,
                            intelImage->mt->cpp,
-                           -src->pitch,
+                           src_pitch,
                            src->buffer,
-                           src->height * src->pitch * src->cpp,
+                           0,
 			   src->tiling,
                            intelImage->mt->pitch,
                            intelImage->mt->region->buffer,
                            image_offset,
 			   intelImage->mt->region->tiling,
-                           x, y + height, dstx, dsty, width, height,
-			   GL_COPY); /* ? */
+                           x, y, dstx, dsty, width, height,
+			   GL_COPY);
       }
    }
 




More information about the mesa-commit mailing list