Esempio n. 1
0
/* Called via glXGetMemoryOffsetMESA() */
GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer)
{
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa;
    GLuint card_offset;

    if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) {
        fprintf(stderr, "%s: no context\n", __FUNCTION__);
        return ~0;
    }

    if (!r200IsGartMemory( rmesa, pointer, 0 ))
        return ~0;

    card_offset = r200GartOffsetFromVirtual( rmesa, pointer );

    return card_offset - rmesa->radeon.radeonScreen->gart_base;
}
Esempio n. 2
0
/* Called via glXGetMemoryOffsetMESA() */
GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer)
{
   GET_CURRENT_CONTEXT(ctx);
   r200ContextPtr rmesa;
   GLuint card_offset;

   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) {
      fprintf(stderr, "%s: no context\n", __FUNCTION__);
      return ~0;
   }

   if (!r200IsGartMemory( rmesa, pointer, 0 ))
      return ~0;

   if (rmesa->dri.drmMinor < 6) 
      return ~0;

   card_offset = r200GartOffsetFromVirtual( rmesa, pointer );

   return card_offset - rmesa->r200Screen->gart_base;
}
Esempio n. 3
0
static void do_draw_pix( GLcontext *ctx,
                         GLint x, GLint y, GLsizei width, GLsizei height,
                         GLint pitch,
                         const void *pixels,
                         GLuint planemask)
{
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
    drm_clip_rect_t *box = dPriv->pClipRects;
    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0][0];
    driRenderbuffer *drb = (driRenderbuffer *) rb;
    int nbox = dPriv->numClipRects;
    int i;
    int blit_format;
    int size;
    int src_offset = r200GartOffsetFromVirtual( rmesa, pixels );
    int src_pitch = pitch * rmesa->r200Screen->cpp;

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

    switch ( rmesa->r200Screen->cpp ) {
    case 2:
        blit_format = R200_CP_COLOR_FORMAT_RGB565;
        break;
    case 4:
        blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
        break;
    default:
        return;
    }


    LOCK_HARDWARE( rmesa );

    if (rmesa->store.cmd_used)
        r200FlushCmdBufLocked( rmesa, __FUNCTION__ );

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

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

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


    r200EmitWait( rmesa, RADEON_WAIT_3D );

    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;

        r200EmitBlit( rmesa,
                      blit_format,
                      src_pitch, src_offset,
                      drb->pitch * drb->cpp,
                      drb->offset + rmesa->r200Screen->fbLocation,
                      bx - x, by - y,
                      bx, by,
                      bw, bh );
    }

    r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
    r200WaitForIdleLocked( rmesa ); /* required by GL */
    UNLOCK_HARDWARE( rmesa );
}
Esempio n. 4
0
static GLboolean
r200TryReadPixels( GLcontext *ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *pack,
                   GLvoid *pixels )
{
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLint pitch = pack->RowLength ? pack->RowLength : width;
    GLint blit_format;
    GLuint cpp = rmesa->r200Screen->cpp;
    GLint size = width * height * cpp;

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

    /* Only accelerate reading to GART buffers.
     */
    if ( !r200IsGartMemory(rmesa, pixels,
                           pitch * height * rmesa->r200Screen->cpp ) ) {
        if (R200_DEBUG & DEBUG_PIXEL)
            fprintf(stderr, "%s: dest not GART\n", __FUNCTION__);
        return GL_FALSE;
    }

    /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
     * blitter:
     */
    if (!pack->Invert) {
        if (R200_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 ( rmesa->r200Screen->cpp ) {
    case 4:
        blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
        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.
     */
    LOCK_HARDWARE( rmesa );

    if (rmesa->store.cmd_used)
        r200FlushCmdBufLocked( rmesa, __FUNCTION__ );

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

    {
        __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
        driRenderbuffer *drb = (driRenderbuffer *) ctx->ReadBuffer->_ColorReadBuffer;
        int nbox = dPriv->numClipRects;
        int src_offset = drb->offset
                         + rmesa->r200Screen->fbLocation;
        int src_pitch = drb->pitch * drb->cpp;
        int dst_offset = r200GartOffsetFromVirtual( rmesa, pixels );
        int dst_pitch = pitch * rmesa->r200Screen->cpp;
        drm_clip_rect_t *box = dPriv->pClipRects;
        int i;

        r200EmitWait( rmesa, RADEON_WAIT_3D );

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


        if (R200_DEBUG & DEBUG_PIXEL)
            fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
                    src_pitch, dst_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;

            r200EmitBlit( rmesa,
                          blit_format,
                          src_pitch, src_offset,
                          dst_pitch, dst_offset,
                          bx, by,
                          bx - x, by - y,
                          bw, bh );
        }

        r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
    }
    UNLOCK_HARDWARE( rmesa );

    r200Finish( ctx ); /* required by GL */

    return GL_TRUE;
}
Esempio n. 5
0
static void r200UploadGARTClientSubImage( r200ContextPtr rmesa,
					  r200TexObjPtr t, 
					  struct gl_texture_image *texImage,
					  GLint hwlevel,
					  GLint x, GLint y, 
					  GLint width, GLint height )
{
   const struct gl_texture_format *texFormat = texImage->TexFormat;
   GLuint srcPitch, dstPitch;
   int blit_format;
   int srcOffset;

   /*
    * XXX it appears that we always upload the full image, not a subimage.
    * I.e. x==0, y==0, width=texWidth, height=texWidth.  If this is ever
    * changed, the src pitch will have to change.
    */
   switch ( texFormat->TexelBytes ) {
   case 1:
      blit_format = R200_CP_COLOR_FORMAT_CI8;
      srcPitch = t->image[0][0].width * texFormat->TexelBytes;
      dstPitch = t->image[0][0].width * texFormat->TexelBytes;
      break;
   case 2:
      blit_format = R200_CP_COLOR_FORMAT_RGB565;
      srcPitch = t->image[0][0].width * texFormat->TexelBytes;
      dstPitch = t->image[0][0].width * texFormat->TexelBytes;
      break;
   case 4:
      blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
      srcPitch = t->image[0][0].width * texFormat->TexelBytes;
      dstPitch = t->image[0][0].width * texFormat->TexelBytes;
      break;
   default:
      return;
   }

   t->image[0][hwlevel].data = texImage->Data;
   srcOffset = r200GartOffsetFromVirtual( rmesa, texImage->Data );

   assert( srcOffset != ~0 );

   /* Don't currently need to cope with small pitches?
    */
   width = texImage->Width;
   height = texImage->Height;

   r200EmitWait( rmesa, RADEON_WAIT_3D );

   r200EmitBlit( rmesa, blit_format, 
		 srcPitch,  
		 srcOffset,   
		 dstPitch,
		 t->bufAddr,
		 x, 
		 y, 
		 t->image[0][hwlevel].x + x,
		 t->image[0][hwlevel].y + y, 
		 width,
		 height );

   r200EmitWait( rmesa, RADEON_WAIT_2D );
}
Esempio n. 6
0
static void r200UploadRectSubImage( r200ContextPtr rmesa,
				    r200TexObjPtr t, 
				    struct gl_texture_image *texImage,
				    GLint x, GLint y, 
				    GLint width, GLint height )
{
   const struct gl_texture_format *texFormat = texImage->TexFormat;
   int blit_format, dstPitch, done;

   switch ( texFormat->TexelBytes ) {
   case 1:
      blit_format = R200_CP_COLOR_FORMAT_CI8;
      break;
   case 2:
      blit_format = R200_CP_COLOR_FORMAT_RGB565;
      break;
   case 4:
      blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
      break;
   default:
      return;
   }

   t->image[0][0].data = texImage->Data;

   /* Currently don't need to cope with small pitches.
    */
   width = texImage->Width;
   height = texImage->Height;
   dstPitch = t->pp_txpitch + 32;

   if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
      /* In this case, could also use GART texturing.  This is
       * currently disabled, but has been tested & works.
       */
      if ( !t->image_override )
         t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data );
      t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32;

      if (R200_DEBUG & DEBUG_TEXTURE)
	 fprintf(stderr, 
		 "Using GART texturing for rectangular client texture\n");

      /* Release FB memory allocated for this image:
       */
      /* FIXME This may not be correct as driSwapOutTextureObject sets
       * FIXME dirty_images.  It may be fine, though.
       */
      if ( t->base.memBlock ) {
	 driSwapOutTextureObject( (driTextureObject *) t );
      }
   }
   else if (texImage->IsClientData) {
      /* Data already in GART memory, with usable pitch.
       */
      GLuint srcPitch;
      srcPitch = texImage->RowStride * texFormat->TexelBytes;
      r200EmitBlit( rmesa, 
		    blit_format, 
		    srcPitch,
		    r200GartOffsetFromVirtual( rmesa, texImage->Data ),   
		    dstPitch, t->bufAddr,
		    0, 0, 
		    0, 0, 
		    width, height );
   }
   else {
      /* Data not in GART memory, or bad pitch.
       */
      for (done = 0; done < height ; ) {
	 struct r200_dma_region region;
	 int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch );
	 int src_pitch;
	 char *tex;

         src_pitch = texImage->RowStride * texFormat->TexelBytes;

	 tex = (char *)texImage->Data + done * src_pitch;

	 memset(&region, 0, sizeof(region));
	 r200AllocDmaRegion( rmesa, &region, lines * dstPitch, 1024 );

	 /* Copy texdata to dma:
	  */
	 if (0)
	    fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n",
		    __FUNCTION__, src_pitch, dstPitch);

	 if (src_pitch == dstPitch) {
	    memcpy( region.address + region.start, tex, lines * src_pitch );
	 } 
	 else {
	    char *buf = region.address + region.start;
	    int i;
	    for (i = 0 ; i < lines ; i++) {
	       memcpy( buf, tex, src_pitch );
	       buf += dstPitch;
	       tex += src_pitch;
	    }
	 }

	 r200EmitWait( rmesa, RADEON_WAIT_3D );

	 /* Blit to framebuffer
	  */
	 r200EmitBlit( rmesa,
		       blit_format,
		       dstPitch, GET_START( &region ),
		       dstPitch | (t->tile_bits >> 16),
		       t->bufAddr,
		       0, 0,
		       0, done,
		       width, lines );
	 
	 r200EmitWait( rmesa, RADEON_WAIT_2D );

	 r200ReleaseDmaRegion( rmesa, &region, __FUNCTION__ );
	 done += lines;
      }
   }
}