get rid of more cliprects (readpixel)...
authorRoland Scheidegger <sroland@tungstengraphics.com>
Mon, 16 Jul 2007 11:57:49 +0000 (13:57 +0200)
committerRoland Scheidegger <sroland@tungstengraphics.com>
Mon, 16 Jul 2007 11:57:49 +0000 (13:57 +0200)
src/mesa/drivers/dri/i915tex/intel_pixel_read.c

index c41ca33f8f56d26018a021994d4a21328fae04a9..76a6959625e56bdd29e95378fef85057c38d1aa6 100644 (file)
@@ -42,6 +42,8 @@
 #include "intel_regions.h"
 #include "intel_pixel.h"
 #include "intel_buffer_objects.h"
+#include "intel_fbo.h"
+#include "intel_tris.h"
 
 /* For many applications, the new ability to pull the source buffers
  * back out of the GTT and then do the packing/conversion operations
@@ -54,6 +56,8 @@
  * an argument for blit/texture readpixels, or for blitting to a
  * temporary and then pulling that back.
  *
+ * XXX this is not true for fake frontbuffers...
+
  * When the destination is a pbo, however, it's not clear if it is
  * ever going to be pulled to main memory (though the access param
  * will be a good hint).  So it sounds like we do want to be able to
 
 static GLboolean
 do_texture_readpixels(GLcontext * ctx,
-                      GLint x, GLint y, GLsizei width, GLsizei height,
+                      GLint srcx, GLint srcy, GLsizei width, GLsizei height,
                       GLenum format, GLenum type,
                       const struct gl_pixelstore_attrib *pack,
                       struct intel_region *dest_region)
 {
 #if 0
    struct intel_context *intel = intel_context(ctx);
-   intelScreenPrivate *screen = intel->intelScreen;
-   GLint pitch = pack->RowLength ? pack->RowLength : width;
-   int textureFormat;
-   GLenum glTextureFormat;
-   int destFormat, depthFormat, destPitch;
-   drm_clip_rect_t tmp;
+   struct intel_region *depthreg = NULL;
+   struct intel_region *src = intel_readbuf_region(intel);
+// struct intel_region *src = copypix_src_region(intel, type);
+   GLenum src_format;
+   GLenum src_type;
 
    if (INTEL_DEBUG & DEBUG_PIXEL)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
-
-   if (ctx->_ImageTransferState ||
-       pack->SwapBytes || pack->LsbFirst || !pack->Invert) {
-      if (INTEL_DEBUG & DEBUG_PIXEL)
-         fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
-      return GL_FALSE;
-   }
-
-   intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel));
-
-   if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) {
-      if (INTEL_DEBUG & DEBUG_PIXEL)
-         fprintf(stderr, "%s: couldn't set dest %s/%s\n",
-                 __FUNCTION__,
-                 _mesa_lookup_enum_by_nr(type),
-                 _mesa_lookup_enum_by_nr(format));
+   if (!src || type != GL_COLOR)
       return GL_FALSE;
-   }
 
-   LOCK_HARDWARE(intel);
+   intelFlush(&intel->ctx);
 
-   if (intel->numClipRects) {
-      intel->vtbl.install_meta_state(intel);
-      intel->vtbl.meta_no_depth_write(intel);
-      intel->vtbl.meta_no_stencil_write(intel);
+   intel->vtbl.install_meta_state(intel);
 
-      if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
-         UNLOCK_HARDWARE(intel);
-         SET_STATE(i830, state);
-         if (INTEL_DEBUG & DEBUG_PIXEL)
-            fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
-         return GL_TRUE;
-      }
+   /* Is this true?  Also will need to turn depth testing on according
+    * to state:
+    */
+   intel->vtbl.meta_no_stencil_write(intel);
+   intel->vtbl.meta_no_depth_write(intel);
 
-      y = intel->pClipRects->y2 - y - height;
+   /* Set the 3d engine to draw into the destination region:
+    */
+   if (ctx->DrawBuffer->_DepthBuffer &&
+       ctx->DrawBuffer->_DepthBuffer->Wrapped)
+      depthreg = (intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped))->region;
 
+   intel->vtbl.meta_draw_region(intel, dest_region, depthreg);
 
-      /* Set the frontbuffer up as a large rectangular texture.
-       */
-      intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat);
+   intel->vtbl.meta_import_pixel_state(intel);
 
+   if (src->cpp == 2) {
+      src_format = GL_RGB;
+      src_type = GL_UNSIGNED_SHORT_5_6_5;
+   }
+   else {
+      src_format = GL_BGRA;
+      src_type = GL_UNSIGNED_BYTE;
+   }
 
-      intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat);
+   /* Set the frontbuffer up as a large rectangular texture.
+    */
+   if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0,
+                                         src->pitch,
+                                         src->height, src_format, src_type)) {
+      intel->vtbl.leave_meta_state(intel);
+      return GL_FALSE;
+   }
 
 
-      /* Set the 3d engine to draw into the destination region:
-       */
+   intel->vtbl.meta_texture_blend_replace(intel);
 
-      intel->vtbl.meta_draw_region(intel, dest_region);
-      intel->vtbl.meta_draw_format(intel, destFormat, depthFormat);     /* ?? */
+   LOCK_HARDWARE(intel);
 
+   {
+      int dstbufHeight = height * ctx->Pixel.ZoomY; /* ? */
+      /* convert from gl to hardware coords */
+      srcy = ctx->ReadBuffer->Height - srcy - height;
 
-      /* Draw a single quad, no cliprects:
+      /* Clip against the source region.  This is the only source
+       * clipping we do.  XXX: Just set the texcord wrap mode to clamp
+       * or similar.
+       *
        */
-      intel->vtbl.meta_disable_cliprects(intel);
+      if (0) {
+         if (!_mesa_clip_to_region(0, 0, ctx->ReadBuffer->Width - 1,
+                                  ctx->ReadBuffer->Height - 1,
+                                   &srcx, &srcy, &width, &height))
+            goto out;
 
-      intel->vtbl.draw_quad(intel,
-                            0, width, 0, height,
-                            0x00ff00ff, x, x + width, y, y + height);
+      }
 
+      /* Just use the regular cliprect mechanism...  Does this need to
+       * even hold the lock???
+       */
+      intel_meta_draw_quad(intel,
+                          0,
+                          width * ctx->Pixel.ZoomX,
+                          dstbufHeight - (height * ctx->Pixel.ZoomY),
+                          dstbufHeight, 0,   /* XXX: what z value? */
+                           0x00ff00ff,
+                           srcx, srcx + width, srcy, srcy + height);
+
+    out:
       intel->vtbl.leave_meta_state(intel);
+      intel_batchbuffer_flush(intel->batch);
    }
    UNLOCK_HARDWARE(intel);
 
-   intel_region_wait_fence(ctx, dest_region);   /* required by GL */
+   if (INTEL_DEBUG & DEBUG_PIXEL)
+      _mesa_printf("%s: success\n", __FUNCTION__);
    return GL_TRUE;
 #endif
 
@@ -166,7 +187,8 @@ do_blit_readpixels(GLcontext * ctx,
                    const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
 {
    struct intel_context *intel = intel_context(ctx);
-   struct intel_region *src = intel_readbuf_region(intel);
+   struct intel_renderbuffer *irbread;
+   struct intel_region *src;
    struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
    GLuint dst_offset;
    GLuint rowLength;
@@ -175,8 +197,10 @@ do_blit_readpixels(GLcontext * ctx,
    if (INTEL_DEBUG & DEBUG_PIXEL)
       _mesa_printf("%s\n", __FUNCTION__);
 
-   if (!src)
+   irbread = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+   if (!irbread || !irbread->region)
       return GL_FALSE;
+   src = irbread->region;
 
    if (dst) {
       /* XXX This validation should be done by core mesa:
@@ -228,44 +252,35 @@ do_blit_readpixels(GLcontext * ctx,
    dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height,
                                              format, type, 0, 0, 0);
 
-   /* reading from priv buffer, cliprects should not change */
    intelFlush(&intel->ctx);
 
-   if (intel->numClipRects) {
-      assert (intel->numClipRects == 1);
+   {
+      GLint srcx = x;
+      GLint srcy = irbread->Base.Height - (y + height);
+      GLint srcwidth = width;
+      GLint srcheight = height;
+
       GLboolean all = (width * height * src->cpp == dst->Base.Size &&
                        x == 0 && dst_offset == 0);
 
       struct _DriBufferObject *dst_buffer =
          intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL :
                                 INTEL_WRITE_PART);
-      int nbox = intel->numClipRects;
-      drm_clip_rect_t *box = intel->pClipRects;
-      drm_clip_rect_t rect;
-      drm_clip_rect_t src_rect;
-      int i;
-
-      src_rect.x1 = x;
-      src_rect.y1 = box->y2 - (y + height);
-      src_rect.x2 = src_rect.x1 + width;
-      src_rect.y2 = src_rect.y1 + height;
-
-
 
-      for (i = 0; i < nbox; i++) {
-         if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
-            continue;
+      /* clip to src region */
+      if (_mesa_clip_to_region(0, 0, irbread->Base.Width - 1,
+                                  irbread->Base.Height - 1,
+                                  &srcx, &srcy, &srcwidth, &srcheight));
 
+      {
          intelEmitCopyBlit(intel,
                            src->cpp,
                            src->pitch, src->buffer, 0,
                            rowLength,
                            dst_buffer, dst_offset,
-                           rect.x1,
-                           rect.y1,
-                           rect.x1 - src_rect.x1,
-                           rect.y2 - src_rect.y2,
-                           rect.x2 - rect.x1, rect.y2 - rect.y1,
+                           srcx, srcy,
+                           0, 0,
+                           width, height,
                           GL_COPY);
       }