add accelerated glCopyPixels path
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 20 Sep 2006 14:36:49 +0000 (14:36 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 20 Sep 2006 14:36:49 +0000 (14:36 +0000)
src/mesa/drivers/dri/i965/Makefile
src/mesa/drivers/dri/i965/intel_context.c
src/mesa/drivers/dri/i965/intel_context.h
src/mesa/drivers/dri/i965/intel_pixel_copy.c [new file with mode: 0644]

index e4fb451cc091a01978c3696feef8f491854eddfa..dfa9318a687fa7b2e7b8c18bbd962b5cc141af74 100644 (file)
@@ -16,6 +16,7 @@ DRIVER_SOURCES = \
        intel_regions.c \
        intel_screen.c \
        intel_span.c \
+       intel_pixel_copy.c \
        intel_state.c \
        intel_tex.c \
        intel_tex_validate.c \
index 59fc8073eee44bf3e36f905bc9596793df625eea..eabb98ca231e6a8e33616a7b3f83b42be5d4e71e 100644 (file)
@@ -255,10 +255,14 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
     */
    functions->Accum = _swrast_Accum;
    functions->Bitmap = _swrast_Bitmap;
-   functions->CopyPixels = _swrast_CopyPixels;
    functions->ReadPixels = _swrast_ReadPixels;
    functions->DrawPixels = _swrast_DrawPixels;
 
+   /* CopyPixels can be accelerated even with the current memory
+    * manager:
+    */
+   functions->CopyPixels = intelCopyPixels;
+
    intelInitTextureFuncs( functions );
    intelInitStateFuncs( functions );
    intelInitBufferFuncs( functions );
@@ -446,8 +450,6 @@ GLboolean intelInitContext( struct intel_context *intel,
 /*                       DRI_TEXMGR_DO_TEXTURE_RECT ); */
 
 
-   intel->prim.primitive = ~0;
-
    if (getenv("INTEL_NO_RAST")) {
       fprintf(stderr, "disabling 3D rasterization\n");
       intel->no_rast = 1;
index 0328cb900a8c6e09a2194d6e12c05bbb074b3bbf..f7fe8c1b22f70c6a6700dae67df7e8640c7ebf90 100644 (file)
@@ -176,16 +176,6 @@ struct intel_context
 
    struct intel_batchbuffer *batch;
 
-   struct {
-      GLuint id;
-      GLuint primitive;
-      GLubyte *start_ptr;      
-      void (*flush)( struct intel_context * );
-   } prim;
-
-   GLboolean locked;
-   GLboolean strict_conformance;
-
    GLubyte clear_chan[4];
    GLuint ClearColor;
    GLuint ClearDepth;
@@ -201,6 +191,10 @@ struct intel_context
    GLboolean no_hw;
    GLboolean no_rast;
    GLboolean thrashing;
+   GLboolean locked;
+   GLboolean strict_conformance;
+   GLboolean need_flush;
+
 
    
    /* AGP memory buffer manager:
@@ -214,22 +208,12 @@ struct intel_context
    GLmatrix ViewportMatrix;
    GLenum render_primitive;
    GLenum reduced_primitive;
-   GLuint vertex_size;
-   GLubyte *verts;                     /* points to tnl->clipspace.vertex_buf */
-
 
    struct intel_region *front_region;
    struct intel_region *back_region;
    struct intel_region *draw_region;
    struct intel_region *depth_region;
 
-
-   /* Fallback rasterization functions 
-    */
-   intel_point_func draw_point;
-   intel_line_func draw_line;
-   intel_tri_func draw_tri;
-
    /* These refer to the current draw (front vs. back) buffer:
     */
    int drawX;                  /* origin of drawable in draw buffer */
@@ -496,6 +480,13 @@ extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest,
                                            const drm_clip_rect_t *b );
 
 
+/* ================================================================
+ * intel_pixel_copy.c:
+ */
+void intelCopyPixels(GLcontext * ctx,
+                     GLint srcx, GLint srcy,
+                     GLsizei width, GLsizei height,
+                     GLint destx, GLint desty, GLenum type);
 
 #define _NEW_WINDOW_POS 0x40000000
 
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
new file mode 100644 (file)
index 0000000..ad27867
--- /dev/null
@@ -0,0 +1,239 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 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 "glheader.h"
+#include "enums.h"
+#include "image.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "state.h"
+#include "swrast/swrast.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_ioctl.h"
+#include "intel_batchbuffer.h"
+#include "intel_blit.h"
+#include "intel_regions.h"
+
+
+static struct intel_region *
+copypix_src_region(struct intel_context *intel, GLenum type)
+{
+   switch (type) {
+   case GL_COLOR:
+      return intel_readbuf_region(intel);
+   case GL_DEPTH:
+      /* Don't think this is really possible execpt at 16bpp, when we have no stencil.
+       */
+      if (intel->depth_region && intel->depth_region->cpp == 2)
+         return intel->depth_region;
+   case GL_STENCIL:
+      /* Don't think this is really possible. 
+       */
+      break;
+   case GL_DEPTH_STENCIL_EXT:
+      /* Does it matter whether it is stencil/depth or depth/stencil?
+       */
+      return intel->depth_region;
+   default:
+      break;
+   }
+
+   return NULL;
+}
+
+
+
+
+/**
+ * Check if any fragment operations are in effect which might effect
+ * glDraw/CopyPixels.
+ */
+static GLboolean
+intel_check_blit_fragment_ops(GLcontext * ctx)
+{
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   /* Could do logicop with the blitter: 
+    */
+   return !(ctx->_ImageTransferState ||
+            ctx->Color.AlphaEnabled ||
+            ctx->Depth.Test ||
+            ctx->Fog.Enabled ||
+            ctx->Stencil.Enabled ||
+            !ctx->Color.ColorMask[0] ||
+            !ctx->Color.ColorMask[1] ||
+            !ctx->Color.ColorMask[2] ||
+            !ctx->Color.ColorMask[3] ||
+            ctx->Color.ColorLogicOpEnabled ||
+            ctx->Texture._EnabledUnits ||
+           ctx->FragmentProgram._Enabled);
+}
+
+
+
+/**
+ * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
+ */
+static GLboolean
+do_blit_copypixels(GLcontext * ctx,
+                   GLint srcx, GLint srcy,
+                   GLsizei width, GLsizei height,
+                   GLint dstx, GLint dsty, GLenum type)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_region *dst = intel_drawbuf_region(intel);
+   struct intel_region *src = copypix_src_region(intel, type);
+
+   /* Copypixels can be more than a straight copy.  Ensure all the
+    * extra operations are disabled:
+    */
+   if (!intel_check_blit_fragment_ops(ctx) ||
+       ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F)
+      return GL_FALSE;
+
+   if (!src || !dst)
+      return GL_FALSE;
+
+
+
+   intelFlush(&intel->ctx);
+
+/*    intel->vtbl.render_start(intel); */
+/*    intel->vtbl.emit_state(intel); */
+
+   LOCK_HARDWARE(intel);
+
+   if (intel->driDrawable->numClipRects) {
+      __DRIdrawablePrivate *dPriv = intel->driDrawable;
+      drm_clip_rect_t *box = dPriv->pClipRects;
+      drm_clip_rect_t dest_rect;
+      GLint nbox = dPriv->numClipRects;
+      GLint delta_x = 0;
+      GLint delta_y = 0;
+      GLuint i;
+
+      /* Do scissoring in GL coordinates:
+       */
+      if (ctx->Scissor.Enabled)
+      {
+        GLint x = ctx->Scissor.X;
+        GLint y = ctx->Scissor.Y;
+        GLuint w = ctx->Scissor.Width;
+        GLuint h = ctx->Scissor.Height;
+        GLint dx = dstx - srcx;
+         GLint dy = dsty - srcy;
+
+         if (!_mesa_clip_to_region(x, y, x+w, y+h, &dstx, &dsty, &width, &height))
+            goto out;
+        
+         srcx = dstx - dx;
+         srcy = dsty - dy;
+      }
+
+      /* Convert from GL to hardware coordinates:
+       */
+      dsty = dPriv->h - dsty - height;  
+      srcy = dPriv->h - srcy - height;  
+      dstx += dPriv->x;
+      dsty += dPriv->y;
+      srcx += dPriv->x;
+      srcy += dPriv->y;
+
+      /* Clip against the source region.  This is the only source
+       * clipping we do.  Dst is clipped with cliprects below.
+       */
+      {
+         delta_x = srcx - dstx;
+         delta_y = srcy - dsty;
+
+         if (!_mesa_clip_to_region(0, 0, src->pitch, src->height,
+                                   &srcx, &srcy, &width, &height))
+            goto out;
+
+         dstx = srcx - delta_x;
+         dsty = srcy - delta_y;
+      }
+
+      dest_rect.x1 = dstx;
+      dest_rect.y1 = dsty;
+      dest_rect.x2 = dstx + width;
+      dest_rect.y2 = dsty + height;
+
+/*       intel->vtbl.emit_flush(intel, 0); */
+
+      /* Could do slightly more clipping: Eg, take the intersection of
+       * the existing set of cliprects and those cliprects translated
+       * by delta_x, delta_y:
+       * 
+       * This code will not overwrite other windows, but will
+       * introduce garbage when copying from obscured window regions.
+       */
+      for (i = 0; i < nbox; i++) {
+         drm_clip_rect_t rect;
+
+         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i]))
+            continue;
+
+
+         intelEmitCopyBlit(intel, 
+                          dst->cpp, 
+                          src->pitch, src->buffer, 0, src->tiled,
+                          dst->pitch, dst->buffer, 0, dst->tiled,
+                          rect.x1 + delta_x, 
+                          rect.y1 + delta_y,       /* srcx, srcy */
+                           rect.x1, rect.y1,    /* dstx, dsty */
+                           rect.x2 - rect.x1, rect.y2 - rect.y1);
+      }
+
+      intel->need_flush = GL_TRUE;
+   out:
+      intel_batchbuffer_flush(intel->batch);
+   }
+   UNLOCK_HARDWARE(intel);
+   return GL_TRUE;
+}
+
+void
+intelCopyPixels(GLcontext * ctx,
+                GLint srcx, GLint srcy,
+                GLsizei width, GLsizei height,
+                GLint destx, GLint desty, GLenum type)
+{
+   if (INTEL_DEBUG & DEBUG_PIXEL)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
+      return;
+
+   if (INTEL_DEBUG & DEBUG_PIXEL)
+      _mesa_printf("fallback to _swrast_CopyPixels\n");
+
+   _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
+}