Another round of fixing attribute interpolation for glDraw/CopyPixels.
authorBrian <brian@i915.localnet.net>
Thu, 21 Jun 2007 15:15:32 +0000 (09:15 -0600)
committerBrian <brian@i915.localnet.net>
Thu, 21 Jun 2007 15:15:32 +0000 (09:15 -0600)
Need to turn off FRAG_BIT_COL0 in swrast->_ActiveAttribMask when doing
glRead/CopyPixels to prevent the user's colors from getting overwritten
when a fragment program is active.
This was happening in the DRI drivers when MaintainTexEnv program was
used (the texenv fragment program was enabled when _swrast_DrawPixels was
called).
This still isn't an ideal solution, but fixes things for now.

src/mesa/drivers/dri/i915/intel_pixel.c
src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
src/mesa/swrast/s_copypix.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_span.c

index a52a81bf131e1948eecf517022537d9ad3f2734f..d175870a0c5e3c48bc660049afb70ffd6d98620a 100644 (file)
@@ -439,21 +439,25 @@ intelDrawPixels( GLcontext *ctx,
    if (INTEL_DEBUG & DEBUG_PIXEL)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
-   if (!intelTryDrawPixels( ctx, x, y, width, height, format, type,
-                            unpack, pixels )) {
-      if (ctx->FragmentProgram._Current == 
-          ctx->FragmentProgram._TexEnvProgram) {
-         /* don't want the i915 texenv program to be applied to DrawPixels */
-         struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
-         ctx->FragmentProgram._Current = NULL;
-         _swrast_DrawPixels( ctx, x, y, width, height, format, type,
-                             unpack, pixels );
-         ctx->FragmentProgram._Current = fpSave;
-      }
-      else {
-         _swrast_DrawPixels( ctx, x, y, width, height, format, type,
-                             unpack, pixels );
-      }
+   if (intelTryDrawPixels( ctx, x, y, width, height, format, type,
+                           unpack, pixels ))
+      return;
+
+   if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
+      /*
+       * We don't want the i915 texenv program to be applied to DrawPixels.
+       * This is really just a performance optimization (mesa will other-
+       * wise happily run the fragment program on each pixel in the image).
+       */
+      struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
+      ctx->FragmentProgram._Current = NULL;
+      _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+                          unpack, pixels );
+      ctx->FragmentProgram._Current = fpSave;
+   }
+   else {
+      _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+                          unpack, pixels );
    }
 }
 
index 46480da1b124eb6c509b02759b6fed945bb1a9b8..77c67c821eb07118df3fac7e85ba6bdf0af669c1 100644 (file)
@@ -363,9 +363,12 @@ intelDrawPixels(GLcontext * ctx,
    if (INTEL_DEBUG & DEBUG_PIXEL)
       _mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
 
-   if (ctx->FragmentProgram._Current == 
-       ctx->FragmentProgram._TexEnvProgram) {
-      /* don't want the i915 texenv program to be applied to DrawPixels */
+   if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) {
+      /*
+       * We don't want the i915 texenv program to be applied to DrawPixels.
+       * This is really just a performance optimization (mesa will other-
+       * wise happily run the fragment program on each pixel in the image).
+       */
       struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current;
       ctx->FragmentProgram._Current = NULL;
       _swrast_DrawPixels( ctx, x, y, width, height, format, type,
index 53e584b3b6bc366e06564ce475180141dc3bef41..2383015000aaf30b1b01797b2d3e9562fae71e30 100644 (file)
@@ -188,6 +188,8 @@ static void
 copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                  GLint width, GLint height, GLint destx, GLint desty)
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLbitfield prevActiveAttribs = swrast->_ActiveAttribMask;
    GLfloat *tmpImage, *p;
    GLint sy, dy, stepy, row;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
@@ -197,12 +199,15 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
 
    if (!ctx->ReadBuffer->_ColorReadBuffer) {
       /* no readbuffer - OK */
-      return;
+      goto end;
    }
 
+   /* don't interpolate COL0 and overwrite the glDrawPixel colors! */
+   swrast->_ActiveAttribMask &= ~FRAG_BIT_COL0;
+
    if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
       copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
-      return;
+      goto end;
    }
    else if (ctx->Pixel.Convolution1DEnabled) {
       /* make sure we don't apply 1D convolution */
@@ -239,7 +244,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
       if (!tmpImage) {
          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
-         return;
+         goto end;
       }
       /* read the source image as RGBA/float */
       p = tmpImage;
@@ -294,6 +299,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
 
    if (overlapping)
       _mesa_free(tmpImage);
+
+end:
+   swrast->_ActiveAttribMask = prevActiveAttribs;
 }
 
 
index d971d90fb9a7e29ffa0a57b7bcffcf3d59acee4c..925358d77eb5ba8a26c592d48d8389e1e6f156fb 100644 (file)
@@ -532,16 +532,22 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLbitfield prevActiveAttribs = swrast->_ActiveAttribMask;
    const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLfloat *convImage = NULL;
    GLbitfield transferOps = ctx->_ImageTransferState;
    SWspan span;
 
+   /* don't interpolate COL0 and overwrite the glDrawPixel colors! */
+   swrast->_ActiveAttribMask &= ~FRAG_BIT_COL0;
+
    /* Try an optimized glDrawPixels first */
    if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
-                             unpack, pixels))
-      return;
+                             unpack, pixels)) {
+      goto end;
+   }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0x0, SPAN_RGBA);
    _swrast_span_default_attribs(ctx, &span);
@@ -559,13 +565,13 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
       tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!tmpImage) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
-         return;
+         goto end;
       }
       convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
       if (!convImage) {
          _mesa_free(tmpImage);
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
-         return;
+         goto end;
       }
 
       /* Unpack the image and apply transfer ops up to convolution */
@@ -669,6 +675,9 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
    if (convImage) {
       _mesa_free(convImage);
    }
+
+end:
+   swrast->_ActiveAttribMask = prevActiveAttribs;
 }
 
 
index 3aaa3395e4c155324017fdbdcd394410bb7c8cd4..431629efb1fdfb1d4a567c4a85e74a5baabe5a1b 100644 (file)
@@ -171,6 +171,11 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
+   /* for glDraw/CopyPixels() we may have turned off some bits in
+    * the _ActiveAttribMask - be sure to obey that mask now.
+    */
+   attrMask &= swrast->_ActiveAttribMask;
+
    ATTRIB_LOOP_BEGIN
       if (attrMask & (1 << attr)) {
          const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
@@ -1169,15 +1174,10 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
    if (ctx->FragmentProgram._Current ||
        ctx->ATIFragmentShader._Enabled) {
       /* programmable shading */
-      if (span->primitive == GL_BITMAP) {
-         if (span->array->ChanType != GL_FLOAT)
-            convert_color_type(span, GL_FLOAT, 0);
-         interpolate_active_attribs(ctx, span, ~FRAG_ATTRIB_COL0);
-      }
-      else {
-         /* point, line, triangle */
-         interpolate_active_attribs(ctx, span, ~0);
+      if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
+         convert_color_type(span, GL_FLOAT, 0);
       }
+      interpolate_active_attribs(ctx, span, ~0);
       span->array->ChanType = GL_FLOAT;
 
       if (!(span->arrayMask & SPAN_Z))