diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 6d6051a427b..47786a48f9b 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -219,16 +219,36 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, return; } - BEGIN_BATCH( 12); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (dst_y << 16) | dst_x ); - OUT_BATCH( (dst_y2 << 16) | dst_x2 ); - OUT_BATCH( dst_offset ); - OUT_BATCH( (src_y << 16) | src_x ); - OUT_BATCH( src_pitch ); - OUT_BATCH( src_offset ); - ADVANCE_BATCH(); + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. + */ + if (0) { + BEGIN_BATCH(8); + OUT_BATCH( CMD ); + OUT_BATCH( BR13 ); + OUT_BATCH( (dst_y << 16) | dst_x ); + OUT_BATCH( (dst_y2 << 16) | dst_x2 ); + OUT_BATCH( dst_offset ); + OUT_BATCH( (src_y << 16) | src_x ); + OUT_BATCH( ((GLint)src_pitch&0xffff) ); + OUT_BATCH( src_offset ); + ADVANCE_BATCH(); + } + else { + src_offset += src_y * src_pitch; + dst_offset += dst_y * dst_pitch; + + BEGIN_BATCH(8); + OUT_BATCH( CMD ); + OUT_BATCH( BR13 ); + OUT_BATCH( (0 << 16) | dst_x ); + OUT_BATCH( (h << 16) | dst_x2 ); + OUT_BATCH( dst_offset ); + OUT_BATCH( (0 << 16) | src_x ); + OUT_BATCH( ((GLint)src_pitch&0xffff) ); + OUT_BATCH( src_offset ); + ADVANCE_BATCH(); + } } diff --git a/src/mesa/drivers/dri/i915/intel_blit.h b/src/mesa/drivers/dri/i915/intel_blit.h new file mode 100644 index 00000000000..dd75844730d --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_blit.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BLIT_H +#define INTEL_BLIT_H + +#include "intel_context.h" +#include "intel_ioctl.h" + +extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv ); +extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx1, GLint cy1, GLint cw, GLint ch); + +extern void intelEmitCopyBlitLocked( intelContextPtr intel, + GLuint cpp, + GLshort src_pitch, + GLuint src_offset, + GLshort dst_pitch, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h ); + +extern void intelEmitFillBlitLocked( intelContextPtr intel, + GLuint cpp, + GLshort dst_pitch, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, + GLuint color ); + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_tex_copy.c b/src/mesa/drivers/dri/i915/intel_tex_copy.c index 68833e83161..50ba017d8bc 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_copy.c +++ b/src/mesa/drivers/dri/i915/intel_tex_copy.c @@ -119,6 +119,7 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, GLuint src_offset = 0; GLint orig_x = x; GLint orig_y = y; + GLuint window_y; if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { ret = GL_TRUE; @@ -127,12 +128,14 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, /* Update dst for clipped src. Need to also clip the source rect. */ - dstx = x - orig_x; - dsty = y - orig_y; + dstx += x - orig_x; + dsty += y - orig_y; - y = dPriv->h - y - height; /* convert from gl to hardware coords */ x += dPriv->x; - y += dPriv->y; + + window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); + + y = window_y + y; bmAddBuffer(intel->buffer_list, @@ -147,15 +150,21 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, ret = GL_FALSE; goto out; } - + + /* A bit of fiddling to get the blitter to work with -ve + * pitches. But we get a nice inverted blit this way, so it's + * worth it: + */ intelEmitCopyBlitLocked( intel, intelImage->mt->cpp, - src->pitch, src_offset, + -src->pitch, + src_offset + intel->intelScreen->height * src->pitch * src->cpp, intelImage->mt->pitch, dst_offset + image_offset, - x, y, + x, y + height, dstx, dsty, width, height ); + out: intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE); }