Exemple #1
0
static GLboolean
intelTryDrawPixels( 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);
   GLint pitch = unpack->RowLength ? unpack->RowLength : width;
   GLuint dest;
   GLuint cpp = intel->intelScreen->cpp;
   GLint size = width * pitch * cpp;

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

   switch (format) {
   case GL_RGB:
   case GL_RGBA:
   case GL_BGRA:
      dest = intel->drawRegion->offset;

      /* Planemask doesn't have full support in blits.
       */
      if (!ctx->Color.ColorMask[RCOMP] ||
	  !ctx->Color.ColorMask[GCOMP] ||
	  !ctx->Color.ColorMask[BCOMP] ||
	  !ctx->Color.ColorMask[ACOMP]) {
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s: planemask\n", __FUNCTION__);
	 return GL_FALSE;	
      }

      /* Can't do conversions on agp reads/draws. 
       */
      if ( !intelIsAgpMemory( intel, pixels, size ) ) {
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
	 return GL_FALSE;
      }

      if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
	 return GL_FALSE;
      }
      if (!check_color_per_fragment_ops(ctx)) {
	 return GL_FALSE;
      }

      if (ctx->Pixel.ZoomX != 1.0F ||
	  ctx->Pixel.ZoomY != -1.0F)
	 return GL_FALSE;
      break;

   default:
      return GL_FALSE;
   }

   if ( intelIsAgpMemory(intel, pixels, size) )
   {
      do_draw_pix( ctx, x, y, width, height, pitch, pixels, dest );
      return GL_TRUE;
   }
   else if (0)
   {
      /* Pixels is in regular memory -- get dma buffers and perform
       * upload through them.  No point doing this for regular uploads
       * but once we remove some of the restrictions above (colormask,
       * pixelformat conversion, zoom?, etc), this could be a win.
       */
   }
   else
      return GL_FALSE;

   return GL_FALSE;
}
static GLboolean
mgaTryDrawPixels( GLcontext *ctx,
		  GLint x, GLint y, GLsizei width, GLsizei height,
		  GLenum format, GLenum type,
		  const struct gl_pixelstore_attrib *unpack,
		  const GLvoid *pixels )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   GLint size, skipPixels, skipRows;
   GLint pitch = unpack->RowLength ? unpack->RowLength : width;
   GLuint dest, planemask;
   GLuint cpp = mmesa->mgaScreen->cpp;

   if (!clip_pixelrect(ctx, ctx->DrawBuffer,
		       &x, &y, &width, &height,
		       &skipPixels, &skipRows, &size)) {
      return GL_TRUE;
   }


   switch (format) {
#if defined(MESA_packed_depth_stencil)
   case GL_DEPTH_STENCIL_MESA:
      dest = mmesa->mgaScreen->depthOffset;
      planemask = ~0;
      if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) ||
	  !check_depth_per_fragment_ops(ctx) ||
	  !check_stencil_per_fragment_ops(ctx))
	 return GL_FALSE;
      break;
#endif

   case GL_DEPTH_COMPONENT:
      dest = mmesa->mgaScreen->depthOffset;

      if (ctx->Visual.depthBits == 24)
	 planemask = ~0xff;
      else
	 planemask = ~0;

      if (!check_depth(ctx, type, unpack, pixels, size, pitch) ||
	  !check_depth_per_fragment_ops(ctx))
	 return GL_FALSE;
      break;

   case GL_RGB:
   case GL_BGRA:
      dest = (mmesa->draw_buffer == MGA_FRONT ?
	      mmesa->mgaScreen->frontOffset :
	      mmesa->mgaScreen->backOffset);

      planemask = mgaPackColor(cpp,
			       ctx->Color.ColorMask[RCOMP],
			       ctx->Color.ColorMask[GCOMP],
			       ctx->Color.ColorMask[BCOMP],
			       ctx->Color.ColorMask[ACOMP]);

      if (cpp == 2)
	 planemask |= planemask << 16;

      if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
	 return GL_FALSE;
      }
      if (!check_color_per_fragment_ops(ctx)) {
	 return GL_FALSE;
      }
      break;

   default:
      return GL_FALSE;
   }

   LOCK_HARDWARE_QUIESCENT( mmesa );

   if (mmesa->dirty_cliprects & MGA_FRONT)
      mgaUpdateRects( mmesa, MGA_FRONT );

   if ( IS_AGP_MEM(mmesa, (char *)pixels) &&
	IS_AGP_MEM(mmesa, (char *)pixels + size) )
   {
      do_draw_pix( ctx, x, y, width, height, pitch, pixels,
		   dest, planemask );
      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
   }
   else
   {
      /* Pixels is in regular memory -- get dma buffers and perform
       * upload through them.
       */
/*        drmBufPtr buf = mgaGetBufferLocked(mmesa); */
      GLuint bufferpitch = (width*cpp+31)&~31;

      char *address = 0; /*  mmesa->mgaScreen->agp.map; */

      do {
/*  	 GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */
	 GLuint rows = height;


	 if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n",
			rows, bufferpitch);

	 /* The texture conversion code is so slow that there is only
	  * negligble speedup when the buffers/images don't exactly
	  * match:
	  */
#if 0
	 if (cpp == 2) {
	    if (!_mesa_convert_texsubimage2d( MESA_FORMAT_RGB565,
					      0, 0, width, rows,
					      bufferpitch, format, type,
					      unpack, pixels, address )) {
/*  	       mgaReleaseBufLocked( mmesa, buf ); */
	       UNLOCK_HARDWARE(mmesa);
	       return GL_FALSE;
	    }
	 } else {
	    if (!_mesa_convert_texsubimage2d( MESA_FORMAT_ARGB8888,
					      0, 0, width, rows,
					      bufferpitch, format, type,
					      unpack, pixels, address )) {
/*  	       mgaReleaseBufLocked( mmesa, buf ); */
	       UNLOCK_HARDWARE(mmesa);
	       return GL_FALSE;
	    }
	 }
#else
	 MEMCPY( address, pixels, rows*bufferpitch );
#endif

	 do_draw_pix( ctx, x, y, width, rows,
		      bufferpitch/cpp, address, dest, planemask );

	 /* Fix me -- use multiple buffers to avoid flush.
	  */
	 UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );

	 pixels = (void *)((char *) pixels + rows * pitch);
	 height -= rows;
	 y += rows;
      } while (height);

/*        mgaReleaseBufLocked( mmesa, buf ); */
   }

   UNLOCK_HARDWARE( mmesa );
   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;

   return GL_TRUE;
}