diff options
Diffstat (limited to 'src/mesa/drivers/dri/i915/i830_metaops.c')
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_metaops.c | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c new file mode 100644 index 0000000000..fb2ee12f41 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -0,0 +1,699 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" + +#include "i830_context.h" +#include "i830_reg.h" + +/* A large amount of state doesn't need to be uploaded. + */ +#define ACTIVE (I830_UPLOAD_TEXBLEND(0) | \ + I830_UPLOAD_STIPPLE | \ + I830_UPLOAD_CTX | \ + I830_UPLOAD_BUFFERS | \ + I830_UPLOAD_TEX(0)) + + +#define SET_STATE( i830, STATE ) \ +do { \ + i830->current->emitted &= ~ACTIVE; \ + i830->current = &i830->STATE; \ + i830->current->emitted &= ~ACTIVE; \ +} while (0) + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void set_initial_state( i830ContextPtr i830 ) +{ + memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); + i830->meta.active = ACTIVE; + i830->meta.emitted = 0; +} + + +static void set_no_depth_stencil_write( i830ContextPtr i830 ) +{ + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; + + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Set stencil unit to replace always with the reference value. + */ +static void set_stencil_replace( i830ContextPtr i830, + GLuint s_mask, + GLuint s_clear) +{ + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK((s_mask&0xff))); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE((s_clear&0xff)) | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); + + + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void set_color_mask( i830ContextPtr i830, GLboolean state ) +{ + const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | + (1 << WRITEMASK_GREEN_SHIFT) | + (1 << WRITEMASK_BLUE_SHIFT) | + (1 << WRITEMASK_ALPHA_SHIFT)); + + if (state) { + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= + (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); + } + else + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= mask; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Installs a one-stage passthrough texture blend pipeline. Is there + * more that can be done to turn off texturing? + */ +static void set_no_texture( i830ContextPtr i830 ) +{ + i830->meta.TexBlendWordsUsed[0] = + i830SetBlend_GL1_2( i830, 0, GL_NONE, 0, + TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], 0 ); + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); +} + +/* Set up a single element blend stage for 'replace' texturing with no + * funny ops. + */ +static void enable_texture_blend_replace( i830ContextPtr i830, + GLenum format ) +{ + i830->meta.TexBlendWordsUsed[0] = + i830SetBlend_GL1_2( i830, 0, GL_REPLACE, format, + TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], 0 ); + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); + +/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ +/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ +} + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static void set_tex_rect_source( i830ContextPtr i830, + GLuint offset, + GLuint width, + GLuint height, + GLuint pitch, + GLuint textureFormat ) +{ + GLint numLevels = 1; + GLuint *setup = i830->meta.Tex[0]; + + pitch *= i830->intel.intelScreen->cpp; + +/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ +/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ + + setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << 0) | 4); + setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset); + setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | + ((width - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); + setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; + setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; + setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; + + setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_IN_TEXELUNITS | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + i830->meta.emitted &= ~I830_UPLOAD_TEX(0); +} + + +/* Select between front and back draw buffers. + */ +static void set_draw_offset( i830ContextPtr i830, + GLuint offset ) +{ + i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + +/* Setup an arbitary draw format, useful for targeting + * texture or agp memory. + */ +static void set_draw_format( i830ContextPtr i830, + GLuint format, + GLuint depth_format) +{ + i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + format | + DEPTH_IS_Z | + depth_format); +} + + +static void set_vertex_format( i830ContextPtr i830 ) +{ + i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | + VFT0_TEX_COUNT(1) | + VFT0_DIFFUSE | + VFT0_SPEC | + VFT0_XYZW); + i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | + VFT1_TEX0_FMT(TEXCOORDFMT_2D) | + VFT1_TEX1_FMT(TEXCOORDFMT_2D) | + VFT1_TEX2_FMT(TEXCOORDFMT_2D) | + VFT1_TEX3_FMT(TEXCOORDFMT_2D)); + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void draw_quad(i830ContextPtr i830, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha, + GLfloat s0, GLfloat s1, + GLfloat t0, GLfloat t1 ) +{ + GLuint vertex_size = 8; + GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, + PRIM3D_TRIFAN, + 4*vertex_size, + vertex_size ); + intelVertex tmp; + int i; + + +/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */ +/* __FUNCTION__, */ +/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */ + + + /* initial vertex, left bottom */ + tmp.v.x = x0; + tmp.v.y = y0; + tmp.v.z = 1.0; + tmp.v.w = 1.0; + tmp.v.color.red = red; + tmp.v.color.green = green; + tmp.v.color.blue = blue; + tmp.v.color.alpha = alpha; + tmp.v.specular.red = 0; + tmp.v.specular.green = 0; + tmp.v.specular.blue = 0; + tmp.v.specular.alpha = 0; + tmp.v.u0 = s0; + tmp.v.v0 = t0; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* right bottom */ + vb += 8; + tmp.v.x = x1; + tmp.v.u0 = s1; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* right top */ + vb += 8; + tmp.v.y = y1; + tmp.v.v0 = t1; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* left top */ + vb += 8; + tmp.v.x = x0; + tmp.v.u0 = s0; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + +/* fprintf(stderr, "%s: DV1: %x\n", */ +/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */ +} + +void +i830ClearWithTris(intelContextPtr intel, GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch) +{ + i830ContextPtr i830 = I830_CONTEXT( intel ); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + intelScreenPrivate *screen = intel->intelScreen; + int x0, y0, x1, y1; + + + SET_STATE( i830, meta ); + set_initial_state( i830 ); + set_no_texture( i830 ); + set_vertex_format( i830 ); + + LOCK_HARDWARE(intel); + + if(!all) { + x0 = cx; + y0 = cy; + x1 = x0 + cw; + y1 = y0 + ch; + } else { + x0 = 0; + y0 = 0; + x1 = x0 + dPriv->w; + y1 = y0 + dPriv->h; + } + + /* Don't do any clipping to screen - these are window coordinates. + * The active cliprects will be applied as for any other geometry. + */ + + if(mask & DD_FRONT_LEFT_BIT) { + set_no_depth_stencil_write( i830 ); + set_color_mask( i830, GL_TRUE ); + set_draw_offset( i830, screen->frontOffset ); + draw_quad(i830, x0, x1, y0, y1, + intel->clear_red, intel->clear_green, + intel->clear_blue, intel->clear_alpha, + 0, 0, 0, 0); + } + + if(mask & DD_BACK_LEFT_BIT) { + set_no_depth_stencil_write( i830 ); + set_color_mask( i830, GL_TRUE ); + set_draw_offset( i830, screen->backOffset ); + + draw_quad(i830, x0, x1, y0, y1, + intel->clear_red, intel->clear_green, + intel->clear_blue, intel->clear_alpha, + 0, 0, 0, 0); + } + + if(mask & DD_STENCIL_BIT) { + set_stencil_replace( i830, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + + set_color_mask( i830, GL_FALSE ); + set_draw_offset( i830, screen->frontOffset ); + draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); + } + + UNLOCK_HARDWARE(intel); + + SET_STATE( i830, state ); +} + + + + +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->frontPitch, + textureFormat ); + + + enable_texture_blend_replace( i830, glTextureFormat ); + + + /* Set the 3d engine to draw into the agp memory + */ + + set_draw_offset( 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; +} + + +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, glTextureFormat ); + + + /* 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; +} + |