Example #1
0
/**
 * Prepare for softare rendering.  Map current read/draw framebuffers'
 * renderbuffes and all currently bound texture objects.
 *
 * Old note: Moved locking out to get reasonable span performance.
 */
void
intelSpanRenderStart(GLcontext * ctx)
{
   struct intel_context *intel = intel_context(ctx);
   GLuint i;

   intelFinish(&intel->ctx);
   LOCK_HARDWARE(intel);

#if 0
   /* Just map the framebuffer and all textures.  Bufmgr code will
    * take care of waiting on the necessary fences:
    */
   intel_region_map(intel->intelScreen, intel->front_region);
   intel_region_map(intel->intelScreen, intel->back_region);
   intel_region_map(intel->intelScreen, intel->intelScreen->depth_region);
#endif

   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
      if (ctx->Texture.Unit[i]._ReallyEnabled) {
         struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
         intel_tex_map_images(intel, intel_texture_object(texObj));
      }
   }

   intel_map_unmap_buffers(intel, GL_TRUE);
}
Example #2
0
void brw_draw_prims( GLcontext *ctx,
		     const struct gl_client_array *arrays[],
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLuint min_index,
		     GLuint max_index )
{
   struct intel_context *intel = intel_context(ctx);
   GLboolean retval;

   /* Decide if we want to rebase.  If so we end up recursing once
    * only into this function.
    */
   if (brw_need_rebase( ctx, arrays, ib, min_index )) {
      vbo_rebase_prims( ctx, arrays, 
			prim, nr_prims, 
			ib, min_index, max_index, 
			brw_draw_prims );
      
      return;
   }


   /* Make a first attempt at drawing:
    */
   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

   
   /* This looks like out-of-memory but potentially we have
    * situation where there is enough memory but it has become
    * fragmented.  Clear out all heaps and start from scratch by
    * faking a contended lock event:  (done elsewhere)
    */
   if (!retval && !intel->Fallback && bmError(intel)) {
      DBG("retrying\n");
      /* Then try a second time only to upload textures and draw the
       * primitives:
       */
      retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

   /* Otherwise, we really are out of memory.  Pass the drawing
    * command to the software tnl module and which will in turn call
    * swrast to do the drawing.
    */
   if (!retval) {
       _swsetup_Wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

   if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) {
      intelFinish( &intel->ctx );
      intel->aub_wrap = 1;
   }
}
Example #3
0
static void do_draw_pix( GLcontext *ctx,
			 GLint x, GLint y, GLsizei width, GLsizei height,
			 GLint pitch,
			 const void *pixels,
			 GLuint dest )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   drm_clip_rect_t *box = dPriv->pClipRects;
   int nbox = dPriv->numClipRects;
   int i;
   int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
   int src_pitch = pitch;

   assert(src_offset != ~0);  /* should be caught earlier */

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );
   if (ctx->DrawBuffer)
   {
      y -= height;			/* cope with pixel zoom */
   
      if (!clip_pixelrect(ctx, ctx->DrawBuffer,
			  &x, &y, &width, &height)) {
	 UNLOCK_HARDWARE( intel );
	 return;
      }

      y = dPriv->h - y - height; 	/* convert from gl to hardware coords */
      x += dPriv->x;
      y += dPriv->y;

      for (i = 0 ; i < nbox ; i++ )
      {
	 GLint bx, by, bw, bh;
	 if (intersect_region(box + i, x, y, width, height,
			      &bx, &by, &bw, &bh)) {
            intelEmitCopyBlitLocked( intel,
                                     intel->intelScreen->cpp,
                                     src_pitch, src_offset,
                                     intel->intelScreen->front.pitch,
                                     intel->drawRegion->offset,
                                     bx - x, by - y,
                                     bx, by,
                                     bw, bh );
         }
      }
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( &intel->ctx );
}
Example #4
0
GLboolean
i830TryTextureDrawPixels( GLcontext *ctx,
			  GLint x, GLint y, GLsizei width, GLsizei height,
			  GLenum format, GLenum type,
			  const struct gl_pixelstore_attrib *unpack,
			  const GLvoid *pixels )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   i830ContextPtr i830 = I830_CONTEXT(ctx);
   GLint pitch = unpack->RowLength ? unpack->RowLength : width;
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   int textureFormat;
   GLenum glTextureFormat;
   int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
   int src_offset = intelAgpOffsetFromVirtual( intel, pixels );

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* Todo -- upload images that aren't in agp space, then texture
    * from them.  
    */

   if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) {
      fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__);
      return GL_FALSE;
   }

   /* Todo -- don't want to clobber all the drawing state like we do
    * for readpixels -- most of this state can be handled just fine.
    */
   if (	ctx->_ImageTransferState ||
	unpack->SwapBytes ||
	unpack->LsbFirst ||
	ctx->Color.AlphaEnabled || 
	ctx->Depth.Test ||
	ctx->Fog.Enabled ||
	ctx->Scissor.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->Depth.OcclusionTest) {
      fprintf(stderr, "%s: other tests failed\n", __FUNCTION__);
      return GL_FALSE;
   }

   /* Todo -- remove these restrictions:
    */
   if (ctx->Pixel.ZoomX != 1.0F ||
       ctx->Pixel.ZoomY != -1.0F)
      return GL_FALSE;



   switch (type) {
   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
      if (format != GL_BGRA) return GL_FALSE;
      textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
      glTextureFormat = GL_RGBA;
      break;
   case GL_UNSIGNED_SHORT_5_6_5: 
      if (format != GL_RGB) return GL_FALSE;
      textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
      glTextureFormat = GL_RGB;
      break;
   case GL_UNSIGNED_SHORT_8_8_MESA: 
      if (format != GL_YCBCR_MESA) return GL_FALSE;
      textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY 
/*  		       | TM0S1_COLORSPACE_CONVERSION */
	 );
      glTextureFormat = GL_YCBCR_MESA;
      break;
   case GL_UNSIGNED_SHORT_8_8_REV_MESA: 
      if (format != GL_YCBCR_MESA) return GL_FALSE;
      textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL 
/* 		       | TM0S1_COLORSPACE_CONVERSION */
	 );
      glTextureFormat = GL_YCBCR_MESA;
      break;
   case GL_UNSIGNED_INT_8_8_8_8_REV: 
      if (format != GL_BGRA) return GL_FALSE;
      textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
      glTextureFormat = GL_RGBA;
      break;
   default:
      fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__);
      return GL_FALSE;
   }

   intelFlush( ctx );

   SET_STATE( i830, meta );

   LOCK_HARDWARE( intel );
   {
      intelWaitForIdle( intel ); /* required by GL */

      y -= height;			/* cope with pixel zoom */

      if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
	 UNLOCK_HARDWARE( intel );
	 SET_STATE(i830, state);
	 fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
	 return GL_TRUE;
      }


      y = dPriv->h - y - height;

      set_initial_state( i830 );

      /* Set the pixel image up as a rectangular texture.
       */
      set_tex_rect_source( i830, 
			   src_offset, 
			   width, 
			   height, 
			   pitch, /* XXXX!!!! -- /2 sometimes */
			   textureFormat ); 
   
   
      enable_texture_blend_replace( i830 ); 

   
      /* Draw to the current draw buffer:
       */
      set_draw_offset( i830, dst_offset );

      /* Draw a quad, use regular cliprects
       */
/*       fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */

      draw_quad( i830, 
		 x, x+width, y, y+height,
		 0, 255, 0, 0, 
		 0, width, 0, height );

      intelWindowMoved( intel );
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( ctx ); /* required by GL */
   
   SET_STATE(i830, state);

   return GL_TRUE;
}
Example #5
0
GLboolean
i830TryTextureReadPixels( GLcontext *ctx,
			  GLint x, GLint y, GLsizei width, GLsizei height,
			  GLenum format, GLenum type,
			  const struct gl_pixelstore_attrib *pack,
			  GLvoid *pixels )
{
   i830ContextPtr i830 = I830_CONTEXT(ctx);
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   intelScreenPrivate *screen = i830->intel.intelScreen;
   GLint pitch = pack->RowLength ? pack->RowLength : width;
   __DRIdrawablePrivate *dPriv = i830->intel.driDrawable;
   int textureFormat;
   GLenum glTextureFormat;
   int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
   int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels);
   int destFormat, depthFormat, destPitch;
   drm_clip_rect_t tmp;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);


   if (	ctx->_ImageTransferState ||
	pack->SwapBytes ||
	pack->LsbFirst ||
	!pack->Invert) {
      fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
      return GL_FALSE;
   }

   switch (screen->fbFormat) {
   case DV_PF_565:
      textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
      glTextureFormat = GL_RGB;
      break;
   case DV_PF_555:
      textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
      glTextureFormat = GL_RGBA;
      break;
   case DV_PF_8888:
      textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
      glTextureFormat = GL_RGBA;
      break;
   default:
      fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__,
	      screen->fbFormat);
      return GL_FALSE;
   }


   switch (type) {
   case GL_UNSIGNED_SHORT_5_6_5: 
      if (format != GL_RGB) return GL_FALSE;
      destFormat = COLR_BUF_RGB565; 
      depthFormat = DEPTH_FRMT_16_FIXED;
      destPitch = pitch * 2;
      break;
   case GL_UNSIGNED_INT_8_8_8_8_REV: 
      if (format != GL_BGRA) return GL_FALSE;
      destFormat = COLR_BUF_ARGB8888; 
      depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER;
      destPitch = pitch * 4;
      break;
   default:
      fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__,
	      _mesa_lookup_enum_by_nr(type));
      return GL_FALSE;
   }

   destFormat |= (0x02<<24);

/*    fprintf(stderr, "type: %s destFormat: %x\n", */
/* 	   _mesa_lookup_enum_by_nr(type), */
/* 	   destFormat); */

   intelFlush( ctx );

   SET_STATE( i830, meta );
   set_initial_state( i830 );
   set_no_depth_stencil_write( i830 );

   LOCK_HARDWARE( intel );
   {
      intelWaitForIdle( intel ); /* required by GL */

      if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
	 UNLOCK_HARDWARE( intel );
	 SET_STATE(i830, state);
	 fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
	 return GL_TRUE;
      }

#if 0
      /* FIXME -- Just emit the correct state
       */
      if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH, 
		      destPitch) != 0) {
	 UNLOCK_HARDWARE( intel );
	 SET_STATE(i830, state);
	 fprintf(stderr, "%s: setparam failed\n", __FUNCTION__);
	 return GL_FALSE;
      }
#endif


      y = dPriv->h - y - height;
      x += dPriv->x;
      y += dPriv->y;


      /* Set the frontbuffer up as a large rectangular texture.
       */
      set_tex_rect_source( i830, 
			   src_offset, 
			   screen->width, 
			   screen->height, 
			   screen->front.pitch, 
			   textureFormat ); 
   
   
      enable_texture_blend_replace( i830 ); 


      /* Set the 3d engine to draw into the agp memory
       */

      set_draw_region( i830, destOffset ); 
      set_draw_format( i830, destFormat, depthFormat );  


      /* Draw a single quad, no cliprects:
       */
      i830->intel.numClipRects = 1;
      i830->intel.pClipRects = &tmp;
      i830->intel.pClipRects[0].x1 = 0;
      i830->intel.pClipRects[0].y1 = 0;
      i830->intel.pClipRects[0].x2 = width;
      i830->intel.pClipRects[0].y2 = height;

      draw_quad( i830, 
		 0, width, 0, height, 
		 0, 255, 0, 0, 
		 x, x+width, y, y+height );

      intelWindowMoved( intel );
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( ctx ); /* required by GL */

   SET_STATE( i830, state );
   return GL_TRUE;
}
Example #6
0
static GLboolean
intelTryReadPixels( GLcontext *ctx,
		  GLint x, GLint y, GLsizei width, GLsizei height,
		  GLenum format, GLenum type,
		  const struct gl_pixelstore_attrib *pack,
		  GLvoid *pixels )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   GLint size = 0; /* not really used */
   GLint pitch = pack->RowLength ? pack->RowLength : width;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* Only accelerate reading to agp buffers.
    */
   if ( !intelIsAgpMemory(intel, pixels, 
			pitch * height * intel->intelScreen->cpp ) ) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
      return GL_FALSE;
   }

   /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
    * blitter:
    */
   if (!pack->Invert) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
      return GL_FALSE;
   }

   if (!check_color(ctx, type, format, pack, pixels, size, pitch))
      return GL_FALSE;

   switch ( intel->intelScreen->cpp ) {
   case 4:
      break;
   default:
      return GL_FALSE;
   }


   /* Although the blits go on the command buffer, need to do this and
    * fire with lock held to guarentee cliprects and drawing offset are
    * correct.
    *
    * This is an unusual situation however, as the code which flushes
    * a full command buffer expects to be called unlocked.  As a
    * workaround, immediately flush the buffer on aquiring the lock.
    */
   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );
   {
      __DRIdrawablePrivate *dPriv = intel->driDrawable;
      int nbox = dPriv->numClipRects;
      int src_offset = intel->readRegion->offset;
      int src_pitch = intel->intelScreen->front.pitch;
      int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
      drm_clip_rect_t *box = dPriv->pClipRects;
      int i;

      assert(dst_offset != ~0);  /* should have been caught above */

      if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) {
	 UNLOCK_HARDWARE( intel );
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s totally clipped -- nothing to do\n",
		    __FUNCTION__);
	 return GL_TRUE;
      }

      /* convert to screen coords (y=0=top) */
      y = dPriv->h - y - height;
      x += dPriv->x;
      y += dPriv->y;

      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
		 src_pitch, pitch);

      /* We don't really have to do window clipping for readpixels.
       * The OpenGL spec says that pixels read from outside the
       * visible window region (pixel ownership) have undefined value.
       */
      for (i = 0 ; i < nbox ; i++)
      {
         GLint bx, by, bw, bh;
         if (intersect_region(box+i, x, y, width, height,
                              &bx, &by, &bw, &bh)) {
            intelEmitCopyBlitLocked( intel,
                                     intel->intelScreen->cpp,
                                     src_pitch, src_offset,
                                     pitch, dst_offset,
                                     bx, by,
                                     bx - x, by - y,
                                     bw, bh );
         }
      }
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( &intel->ctx );

   return GL_TRUE;
}
Example #7
0
static void do_draw_pix( GLcontext *ctx,
			 GLint x, GLint y, GLsizei width, GLsizei height,
			 GLint pitch,
			 const void *pixels,
			 GLuint dest )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   drm_clip_rect_t *box = dPriv->pClipRects;
   int nbox = dPriv->numClipRects;
   int i;
   int size;
   int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
   int src_pitch = pitch;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );
   if (ctx->DrawBuffer)
   {
      y -= height;			/* cope with pixel zoom */
   
      if (!clip_pixelrect(ctx, ctx->DrawBuffer,
			  &x, &y, &width, &height,
			  &size)) {
	 UNLOCK_HARDWARE( intel );
	 return;
      }

      y = dPriv->h - y - height; 	/* convert from gl to hardware coords */
      x += dPriv->x;
      y += dPriv->y;


      for (i = 0 ; i < nbox ; i++ )
      {
	 GLint bx = box[i].x1;
	 GLint by = box[i].y1;
	 GLint bw = box[i].x2 - bx;
	 GLint bh = box[i].y2 - by;

	 if (bx < x) bw -= x - bx, bx = x;
	 if (by < y) bh -= y - by, by = y;
	 if (bx + bw > x + width) bw = x + width - bx;
	 if (by + bh > y + height) bh = y + height - by;
	 if (bw <= 0) continue;
	 if (bh <= 0) continue;

	 intelEmitCopyBlitLocked( intel,
			    intel->intelScreen->cpp,
			    src_pitch, src_offset,
			    intel->intelScreen->frontPitch,
			      intel->drawOffset,
			    bx - x, by - y,
			    bx, by,
			    bw, bh );
      }
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( &intel->ctx );
}
Example #8
0
static GLboolean
intelTryReadPixels( GLcontext *ctx,
		  GLint x, GLint y, GLsizei width, GLsizei height,
		  GLenum format, GLenum type,
		  const struct gl_pixelstore_attrib *pack,
		  GLvoid *pixels )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   GLint size = 0;
   GLint pitch = pack->RowLength ? pack->RowLength : width;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* Only accelerate reading to agp buffers.
    */
   if ( !intelIsAgpMemory(intel, pixels, 
			pitch * height * intel->intelScreen->cpp ) ) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
      return GL_FALSE;
   }

   /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
    * blitter:
    */
   if (!pack->Invert) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
      return GL_FALSE;
   }

   if (!check_color(ctx, type, format, pack, pixels, size, pitch))
      return GL_FALSE;

   switch ( intel->intelScreen->cpp ) {
   case 4:
      break;
   default:
      return GL_FALSE;
   }


   /* Although the blits go on the command buffer, need to do this and
    * fire with lock held to guarentee cliprects and drawOffset are
    * correct.
    *
    * This is an unusual situation however, as the code which flushes
    * a full command buffer expects to be called unlocked.  As a
    * workaround, immediately flush the buffer on aquiring the lock.
    */
   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );
   {
      __DRIdrawablePrivate *dPriv = intel->driDrawable;
      int nbox = dPriv->numClipRects;
      int src_offset = intel->drawOffset;
      int src_pitch = intel->intelScreen->frontPitch;
      int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
      drm_clip_rect_t *box = dPriv->pClipRects;
      int i;

      if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height,
			  &size)) {
	 UNLOCK_HARDWARE( intel );
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s totally clipped -- nothing to do\n",
		    __FUNCTION__);
	 return GL_TRUE;
      }


      y = dPriv->h - y - height;
      x += dPriv->x;
      y += dPriv->y;


      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
		 src_pitch, pitch);

      for (i = 0 ; i < nbox ; i++)
      {
	 GLint bx = box[i].x1;
	 GLint by = box[i].y1;
	 GLint bw = box[i].x2 - bx;
	 GLint bh = box[i].y2 - by;
	 
	 if (bx < x) bw -= x - bx, bx = x;
	 if (by < y) bh -= y - by, by = y;
	 if (bx + bw > x + width) bw = x + width - bx;
	 if (by + bh > y + height) bh = y + height - by;
	 if (bw <= 0) continue;
	 if (bh <= 0) continue;

	 intelEmitCopyBlitLocked( intel,
			    intel->intelScreen->cpp,
			    src_pitch, src_offset,
			    pitch, dst_offset,
			    bx, by,
			    bx - x, by - y,
			    bw, bh );
      }
   }
   UNLOCK_HARDWARE( intel );
   intelFinish( &intel->ctx );

   return GL_TRUE;
}