get rid of more fake cliprects (drawpixel), and enable blit draw with scissor
authorRoland Scheidegger <sroland@tungstengraphics.com>
Mon, 16 Jul 2007 13:33:09 +0000 (15:33 +0200)
committerRoland Scheidegger <sroland@tungstengraphics.com>
Mon, 16 Jul 2007 13:33:09 +0000 (15:33 +0200)
src/mesa/drivers/dri/i915tex/intel_pixel.c
src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c
src/mesa/drivers/dri/i915tex/intel_pixel_copy.c
src/mesa/drivers/dri/i915tex/intel_pixel_draw.c

index 9018e3daef497714487c1136732cdb477e8c98ec..8e61cc8184898e7c148dce65b0396d442b439ee2 100644 (file)
@@ -44,13 +44,12 @@ intel_check_blit_fragment_ops(GLcontext * ctx)
    if (ctx->NewState)
       _mesa_update_state(ctx);
 
-   /* XXX Note: Scissor could be done with the blitter:
+   /* XXX Note: Scissor done with blitter:
     */
    return !(ctx->_ImageTransferState ||
             ctx->Color.AlphaEnabled ||
             ctx->Depth.Test ||
             ctx->Fog.Enabled ||
-            ctx->Scissor.Enabled ||
             ctx->Stencil.Enabled ||
             !ctx->Color.ColorMask[0] ||
             !ctx->Color.ColorMask[1] ||
index 96d3cbef5f2f317dd58c72ca505ab69a4aa0a62e..c205c6a715f30233201edde8366639d1aa410418 100644 (file)
@@ -195,16 +195,17 @@ do_blit_bitmap( GLcontext *ctx,
 
    LOCK_HARDWARE(intel);
 
-   if (intel->numClipRects) {
-      assert(intel->numClipRects == 1);
-      drm_clip_rect_t *box = intel->pClipRects;
+   {
+      drm_clip_rect_t box;
       drm_clip_rect_t dest_rect;
-      GLint nbox = intel->numClipRects;
       GLint srcx = 0, srcy = 0;
       GLint orig_screen_x1, orig_screen_y2;
       GLuint i;
 
-
+      box.x1 = 0;
+      box.y1 = 0;
+      box.x2 = ctx->DrawBuffer->Width;
+      box.y2 = ctx->DrawBuffer->Height;
       orig_screen_x1 = dstx;
       orig_screen_y2 = box->y2 - dsty;
 
@@ -231,13 +232,13 @@ x      if (ctx->Scissor.Enabled)
       dest_rect.x2 = dstx + width;
       dest_rect.y2 = dsty + height;
 
-      for (i = 0; i < nbox; i++) {
+      for (i = 0; i < 1; i++) {
          drm_clip_rect_t rect;
         int box_w, box_h;
         GLint px, py;
         GLuint stipple[32];
 
-         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i]))
+         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[0]))
             continue;
 
         /* Now go back to GL coordinates to figure out what subset of
index 57e746ae22f06db25602287e3bca615706a56e41..3148a2b0d42f7a70435af0c22e319b6f894b3bab 100644 (file)
@@ -80,33 +80,6 @@ copypix_src_region(struct intel_context *intel, GLenum type)
 }
 
 
-/**
- * Check if any fragment operations are in effect which might effect
- * glCopyPixels.  Differs from intel_check_blit_fragment_ops in that
- * we allow Scissor.
- */
-static GLboolean
-intel_check_copypixel_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->Texture._EnabledUnits ||
-           ctx->FragmentProgram._Enabled ||
-           ctx->Color.BlendEnabled);
-}
-
 /* Doesn't work for overlapping regions.  Could do a double copy or
  * just fallback.
  */
@@ -269,7 +242,7 @@ do_blit_copypixels(GLcontext * ctx,
    /* Copypixels can be more than a straight copy.  Ensure all the
     * extra operations are disabled:
     */
-   if (!intel_check_copypixel_blit_fragment_ops(ctx) ||
+   if (!intel_check_blit_fragment_ops(ctx) ||
        ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F)
       return GL_FALSE;
 
index 2d46c4b8c0e48b1bd5d055c9187646187f650ef3..b1ecf2b0ce37c49496ae2b300287c20c8e7192e1 100644 (file)
@@ -43,7 +43,7 @@
 #include "intel_pixel.h"
 #include "intel_buffer_objects.h"
 #include "intel_tris.h"
-
+#include "intel_fbo.h"
 
 
 static GLboolean
@@ -138,9 +138,8 @@ do_texture_drawpixels(GLcontext * ctx,
 
    LOCK_HARDWARE(intel);
 
-   if (intel->numClipRects) {
-      assert(intel->numClipRects == 1);
-      int bufHeight = intel->pClipRects->y2;
+   {
+      int bufHeight = ctx->DrawBuffer->Height;
 
       GLint srcx, srcy;
       GLint dstx, dsty;
@@ -208,22 +207,50 @@ do_texture_drawpixels(GLcontext * ctx,
  */
 static GLboolean
 do_blit_drawpixels(GLcontext * ctx,
-                   GLint x, GLint y,
+                   GLint dstx, GLint dsty,
                    GLsizei width, GLsizei height,
                    GLenum format, GLenum type,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid * pixels)
 {
    struct intel_context *intel = intel_context(ctx);
-   struct intel_region *dest = intel_drawbuf_region(intel);
+   struct intel_renderbuffer *irbdraw;
+   struct intel_region *dest;
    struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj);
    GLuint src_offset;
    GLuint rowLength;
+   GLuint height_orig = height;
    struct _DriFenceObject *fence = NULL;
 
    if (INTEL_DEBUG & DEBUG_PIXEL)
       _mesa_printf("%s\n", __FUNCTION__);
 
+   if (type == GL_COLOR) {
+      irbdraw = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
+      if (!irbdraw || !irbdraw->region)
+        return GL_FALSE;
+   }
+   else if (type == GL_DEPTH) {
+      /* Don't think this is really possible execpt at 16bpp, when we have no stencil.
+       */
+      irbdraw = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
+      if (!irbdraw || !irbdraw->region || !(irbdraw->region->cpp == 2))
+        return GL_FALSE;
+   }
+   else if (GL_DEPTH_STENCIL_EXT) {
+      /* Does it matter whether it is stencil/depth or depth/stencil?
+       */
+      irbdraw = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
+      if (!irbdraw || !irbdraw->region)
+        return GL_FALSE;
+   }
+   else if (GL_STENCIL) {
+      /* Don't think this is really possible. 
+       */
+      return GL_FALSE;
+   }
+
+   dest = irbdraw->region;
 
    if (!dest) {
       if (INTEL_DEBUG & DEBUG_PIXEL)
@@ -277,7 +304,7 @@ do_blit_drawpixels(GLcontext * ctx,
       if (INTEL_DEBUG & DEBUG_PIXEL)
          _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__);
       return GL_FALSE;          /* later */
-      y -= height;
+      dsty -= height;
    }
    else if (ctx->Pixel.ZoomY == 1.0F) {
       rowLength = -rowLength;
@@ -291,38 +318,59 @@ do_blit_drawpixels(GLcontext * ctx,
    src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height,
                                              format, type, 0, 0, 0);
 
-   /* don't need a lock as cliprects shouldn't change */
+   /* don't need a lock as we have no cliprects ? */
    intelFlush(&intel->ctx);
 
-   if (intel->numClipRects) {
-      assert(intel->numClipRects == 1);
-      int nbox = intel->numClipRects;
-      drm_clip_rect_t *box = intel->pClipRects;
-      drm_clip_rect_t rect;
-      drm_clip_rect_t dest_rect;
+   {
+      GLuint srcx = 0;
+      GLuint srcy = 0;
+      GLint dx = dstx;
+      GLint dy = dsty;
+
+      /* 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;
+        height_orig = height;
+
+
+         if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height))
+            goto out;
+
+      }
+
+      /* no need to clip against pbo src region, but clip against dest */
+      {
+         if (!_mesa_clip_to_region(0, 0, irbdraw->Base.Width - 1,
+                                  irbdraw->Base.Height - 1,
+                                  &dstx, &dsty, &width, &height))
+            goto out;
+
+         srcx = dstx - dx;
+         srcy = dsty - dy;
+      }
+
       struct _DriBufferObject *src_buffer =
          intel_bufferobj_buffer(intel, src, INTEL_READ);
-      int i;
 
-      dest_rect.x1 = x;
-      dest_rect.y1 = box->y2 - (y + height);
-      dest_rect.x2 = dest_rect.x1 + width;
-      dest_rect.y2 = dest_rect.y1 + height;
-
-      for (i = 0; i < nbox; i++) {
-         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i]))
-            continue;
+      /* Convert from GL to hardware coordinates:
+       */
+      dsty = irbdraw->Base.Height - dsty - height;
+      srcy = height_orig - srcy - height;
 
+      {
          intelEmitCopyBlit(intel,
                            dest->cpp,
                            rowLength,
                            src_buffer, src_offset,
                            dest->pitch,
                            dest->buffer, 0,
-                           rect.x1 - dest_rect.x1,
-                           rect.y2 - dest_rect.y2,
-                           rect.x1,
-                           rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1,
+                           srcx, srcy,
+                           dstx, dsty, width, height,
                           ctx->Color.ColorLogicOpEnabled ?
                           ctx->Color.LogicOp : GL_COPY);
       }
@@ -335,6 +383,8 @@ do_blit_drawpixels(GLcontext * ctx,
       driFenceUnReference(fence);
    }
 
+   out:
+
    if (INTEL_DEBUG & DEBUG_PIXEL)
       _mesa_printf("%s - DONE\n", __FUNCTION__);