예제 #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;
}
예제 #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;
}
예제 #3
0
static GLboolean
r200TryDrawPixels( GLcontext *ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
{
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLint pitch = unpack->RowLength ? unpack->RowLength : width;
    GLuint planemask;
    GLuint cpp = rmesa->r200Screen->cpp;
    GLint size = width * pitch * cpp;

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

    /* check that we're drawing to exactly one color buffer */
    if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1)
        return GL_FALSE;

    switch (format) {
    case GL_RGB:
    case GL_RGBA:
    case GL_BGRA:
        planemask = r200PackColor(cpp,
                                  ctx->Color.ColorMask[RCOMP],
                                  ctx->Color.ColorMask[GCOMP],
                                  ctx->Color.ColorMask[BCOMP],
                                  ctx->Color.ColorMask[ACOMP]);

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

        if (planemask != ~0)
            return GL_FALSE;	/* fix me -- should be possible */

        /* Can't do conversions on GART reads/draws.
         */
        if ( !r200IsGartMemory( rmesa, pixels, size ) ) {
            if (R200_DEBUG & DEBUG_PIXEL)
                fprintf(stderr, "%s: not GART 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 ( r200IsGartMemory(rmesa, pixels, size) )
    {
        do_draw_pix( ctx, x, y, width, height, pitch, pixels, planemask );
        return GL_TRUE;
    }
    else if (0)
    {
        /* Pixels is in regular memory -- get dma buffers and perform
         * upload through them.
         */
    }
    else
        return GL_FALSE;
}
예제 #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;
}