Merge remote branch 'origin/master' into pipe-video
[mesa.git] / src / mesa / drivers / dri / intel / intel_pixel_copy.c
index f058b3c8e4dfa21f748297d8f1f016d9f219dedf..a7ca780e944021899142479a5d466662a3efb07d 100644 (file)
 #include "intel_buffers.h"
 #include "intel_regions.h"
 #include "intel_pixel.h"
+#include "intel_fbo.h"
 
 #define FILE_DEBUG_FLAG DEBUG_PIXEL
 
 static struct intel_region *
 copypix_src_region(struct intel_context *intel, GLenum type)
 {
+   struct intel_renderbuffer *depth;
+
+   depth = (struct intel_renderbuffer *)
+      &intel->ctx.DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+
    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;
+      /* Don't think this is really possible execpt at 16bpp, when we
+       * have no stencil. */
+      if (depth && depth->region->cpp == 2)
+         return depth->region;
    case GL_STENCIL:
-      /* Don't think this is really possible. 
-       */
+      /* 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;
+      return depth->region;
    default:
       break;
    }
@@ -71,7 +76,7 @@ copypix_src_region(struct intel_context *intel, GLenum type)
  * we allow Scissor.
  */
 static GLboolean
-intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
+intel_check_copypixel_blit_fragment_ops(struct gl_context * ctx)
 {
    if (ctx->NewState)
       _mesa_update_state(ctx);
@@ -83,10 +88,10 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
             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.ColorMask[0][0] ||
+            !ctx->Color.ColorMask[0][1] ||
+            !ctx->Color.ColorMask[0][2] ||
+            !ctx->Color.ColorMask[0][3] ||
             ctx->Texture._EnabledUnits ||
            ctx->FragmentProgram._Enabled ||
            ctx->Color.BlendEnabled);
@@ -97,23 +102,24 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
  * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
  */
 static GLboolean
-do_blit_copypixels(GLcontext * ctx,
+do_blit_copypixels(struct gl_context * 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);
+   struct intel_region *dst;
+   struct intel_region *src;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct gl_framebuffer *read_fb = ctx->ReadBuffer;
-   unsigned int num_cliprects;
-   drm_clip_rect_t *cliprects;
-   int x_off, y_off;
+   GLint orig_dstx;
+   GLint orig_dsty;
+   GLint orig_srcx;
+   GLint orig_srcy;
+   GLboolean flip = GL_FALSE;
 
    if (type == GL_DEPTH || type == GL_STENCIL) {
-      if (INTEL_DEBUG & DEBUG_FALLBACKS)
-        fprintf(stderr, "glCopyPixels() fallback: GL_DEPTH || GL_STENCIL\n");
+      fallback_debug("glCopyPixels() fallback: GL_DEPTH || GL_STENCIL\n");
       return GL_FALSE;
    }
 
@@ -127,100 +133,63 @@ do_blit_copypixels(GLcontext * ctx,
        ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F)
       return GL_FALSE;
 
+   intel_prepare_render(intel);
+
+   dst = intel_drawbuf_region(intel);
+   src = copypix_src_region(intel, type);
+
    if (!src || !dst)
       return GL_FALSE;
 
+   intel_flush(&intel->ctx);
+
+   /* Clip to destination buffer. */
+   orig_dstx = dstx;
+   orig_dsty = dsty;
+   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
+                            fb->_Xmax, fb->_Ymax,
+                            &dstx, &dsty, &width, &height))
+      goto out;
+   /* Adjust src coords for our post-clipped destination origin */
+   srcx += dstx - orig_dstx;
+   srcy += dsty - orig_dsty;
+
+   /* Clip to source buffer. */
+   orig_srcx = srcx;
+   orig_srcy = srcy;
+   if (!_mesa_clip_to_region(0, 0,
+                            read_fb->Width, read_fb->Height,
+                            &srcx, &srcy, &width, &height))
+      goto out;
+   /* Adjust dst coords for our post-clipped source origin */
+   dstx += srcx - orig_srcx;
+   dsty += srcy - orig_srcy;
+
+   /* Flip dest Y if it's a window system framebuffer. */
+   if (fb->Name == 0) {
+      /* copypixels to a window system framebuffer */
+      dsty = fb->Height - dsty - height;
+      flip = !flip;
+   }
 
+   /* Flip source Y if it's a window system framebuffer. */
+   if (read_fb->Name == 0) {
+      srcy = read_fb->Height - srcy - height;
+      flip = !flip;
+   }
 
-   intelFlush(&intel->ctx);
-
-   LOCK_HARDWARE(intel);
-
-   intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
-   if (num_cliprects != 0) {
-      GLint delta_x;
-      GLint delta_y;
-      GLint orig_dstx;
-      GLint orig_dsty;
-      GLint orig_srcx;
-      GLint orig_srcy;
-      GLuint i;
-
-      /* XXX: We fail to handle different inversion between read and draw framebuffer. */
-
-      /* Clip to destination buffer. */
-      orig_dstx = dstx;
-      orig_dsty = dsty;
-      if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
-                               fb->_Xmax, fb->_Ymax,
-                               &dstx, &dsty, &width, &height))
-        goto out;
-      /* Adjust src coords for our post-clipped destination origin */
-      srcx += dstx - orig_dstx;
-      srcy += dsty - orig_dsty;
-
-      /* Clip to source buffer. */
-      orig_srcx = srcx;
-      orig_srcy = srcy;
-      if (!_mesa_clip_to_region(0, 0,
-                               read_fb->Width, read_fb->Height,
-                               &srcx, &srcy, &width, &height))
-        goto out;
-      /* Adjust dst coords for our post-clipped source origin */
-      dstx += srcx - orig_srcx;
-      dsty += srcy - orig_srcy;
-
-      /* Convert from GL to hardware coordinates:
-       */
-      if (fb->Name == 0) {
-        /* copypixels to a system framebuffer */
-        dstx = x_off + dstx;
-        dsty = y_off + (fb->Height - dsty - height);
-      } else {
-        /* copypixels to a user framebuffer object */
-        dstx = x_off + dstx;
-        dsty = y_off + dsty;
-      }
-
-      /* Flip source Y if it's a system framebuffer. */
-      if (read_fb->Name == 0) {
-        srcx = intel->driReadDrawable->x + srcx;
-        srcy = intel->driReadDrawable->y + (fb->Height - srcy - height);
-      }
-
-      delta_x = srcx - dstx;
-      delta_y = srcy - dsty;
-      /* Could do slightly more clipping: Eg, take the intersection of
-       * the destination cliprects and the read drawable cliprects
-       *
-       * This code will not overwrite other windows, but will
-       * introduce garbage when copying from obscured window regions.
-       */
-      for (i = 0; i < num_cliprects; i++) {
-        GLint clip_x = dstx;
-        GLint clip_y = dsty;
-        GLint clip_w = width;
-        GLint clip_h = height;
-
-         if (!_mesa_clip_to_region(cliprects[i].x1, cliprects[i].y1,
-                                  cliprects[i].x2, cliprects[i].y2,
-                                  &clip_x, &clip_y, &clip_w, &clip_h))
-            continue;
-
-        if (!intel_region_copy(intel,
-                               dst, 0, clip_x, clip_y,
-                               src, 0, clip_x + delta_x, clip_y + delta_y,
-                               clip_w, clip_h,
-                               ctx->Color.ColorLogicOpEnabled ?
-                               ctx->Color.LogicOp : GL_COPY)) {
-           DBG("%s: blit failure\n", __FUNCTION__);
-           UNLOCK_HARDWARE(intel);
-           return GL_FALSE;
-        }
-      }
+   if (!intel_region_copy(intel,
+                         dst, 0, dstx, dsty,
+                         src, 0, srcx, srcy,
+                         width, height, flip,
+                         ctx->Color.ColorLogicOpEnabled ?
+                         ctx->Color.LogicOp : GL_COPY)) {
+      DBG("%s: blit failure\n", __FUNCTION__);
+      return GL_FALSE;
    }
+
 out:
-   UNLOCK_HARDWARE(intel);
+   intel_check_front_buffer_rendering(intel);
 
    DBG("%s: success\n", __FUNCTION__);
    return GL_TRUE;
@@ -228,13 +197,12 @@ out:
 
 
 void
-intelCopyPixels(GLcontext * ctx,
+intelCopyPixels(struct gl_context * 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__);
+   DBG("%s\n", __FUNCTION__);
 
    if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
       return;