[MESA]
[reactos.git] / reactos / dll / opengl / mesa / src / mesa / drivers / common / meta.c
index 8ff1299..588dac7 100644 (file)
@@ -94,7 +94,7 @@ struct save_state
    GLboolean ColorLogicOpEnabled;
 
    /** MESA_META_COLOR_MASK */
-   GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
+   GLubyte ColorMask[4];
 
    /** MESA_META_DEPTH_TEST */
    struct gl_depthbuffer_attrib Depth;
@@ -232,29 +232,6 @@ struct copypix_state
 };
 
 
-/**
- * State for glDrawPixels()
- */
-struct drawpix_state
-{
-   GLuint ArrayObj;
-
-   GLuint StencilFP;  /**< Fragment program for drawing stencil images */
-   GLuint DepthFP;  /**< Fragment program for drawing depth images */
-};
-
-
-/**
- * State for glBitmap()
- */
-struct bitmap_state
-{
-   GLuint ArrayObj;
-   GLuint VBO;
-   struct temp_texture Tex;  /**< separate texture from other meta ops */
-};
-
-
 /**
  * State for _mesa_meta_generate_mipmap()
  */
@@ -276,15 +253,6 @@ struct decompress_state
    GLint Width, Height;
 };
 
-/**
- * State for glDrawTex()
- */
-struct drawtex_state
-{
-   GLuint ArrayObj;
-   GLuint VBO;
-};
-
 #define MAX_META_OPS_DEPTH      8
 /**
  * All per-context meta state.
@@ -298,86 +266,12 @@ struct gl_meta_state
 
    struct temp_texture TempTex;
 
-   struct blit_state Blit;    /**< For _mesa_meta_BlitFramebuffer() */
-   struct clear_state Clear;  /**< For _mesa_meta_Clear() */
    struct copypix_state CopyPix;  /**< For _mesa_meta_CopyPixels() */
-   struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
-   struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
    struct decompress_state Decompress;  /**< For texture decompression */
-   struct drawtex_state DrawTex;  /**< For _mesa_meta_DrawTex() */
 };
 
-static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit);
 static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex);
-static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear);
-
-static GLuint
-compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source)
-{
-   GLuint shader;
-   GLint ok, size;
-   GLchar *info;
-
-   shader = _mesa_CreateShaderObjectARB(target);
-   _mesa_ShaderSourceARB(shader, 1, &source, NULL);
-   _mesa_CompileShaderARB(shader);
-
-   _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok);
-   if (ok)
-      return shader;
-
-   _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
-   if (size == 0) {
-      _mesa_DeleteObjectARB(shader);
-      return 0;
-   }
-
-   info = malloc(size);
-   if (!info) {
-      _mesa_DeleteObjectARB(shader);
-      return 0;
-   }
-
-   _mesa_GetProgramInfoLog(shader, size, NULL, info);
-   _mesa_problem(ctx,
-                "meta program compile failed:\n%s\n"
-                "source:\n%s\n",
-                info, source);
-
-   free(info);
-   _mesa_DeleteObjectARB(shader);
-
-   return 0;
-}
-
-static GLuint
-link_program_with_debug(struct gl_context *ctx, GLuint program)
-{
-   GLint ok, size;
-   GLchar *info;
-
-   _mesa_LinkProgramARB(program);
-
-   _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok);
-   if (ok)
-      return program;
-
-   _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
-   if (size == 0)
-      return 0;
-
-   info = malloc(size);
-   if (!info)
-      return 0;
-
-   _mesa_GetProgramInfoLog(program, size, NULL, info);
-   _mesa_problem(ctx, "meta program link failed:\n%s", info);
-
-   free(info);
-
-   return 0;
-}
 
 /**
  * Initialize meta-ops for a context.
@@ -401,8 +295,6 @@ _mesa_meta_free(struct gl_context *ctx)
 {
    GET_CURRENT_CONTEXT(old_context);
    _mesa_make_current(ctx, NULL, NULL);
-   meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
-   meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
    cleanup_temp_texture(ctx, &ctx->Meta->TempTex);
    if (old_context)
       _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
@@ -453,10 +345,10 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
    if (state & MESA_META_COLOR_MASK) {
       memcpy(save->ColorMask, ctx->Color.ColorMask,
              sizeof(ctx->Color.ColorMask));
-      if (!ctx->Color.ColorMask[0][0] ||
-          !ctx->Color.ColorMask[0][1] ||
-          !ctx->Color.ColorMask[0][2] ||
-          !ctx->Color.ColorMask[0][3])
+      if (!ctx->Color.ColorMask[0] ||
+          !ctx->Color.ColorMask[1] ||
+          !ctx->Color.ColorMask[2] ||
+          !ctx->Color.ColorMask[3])
          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    }
 
@@ -723,21 +615,9 @@ _mesa_meta_end(struct gl_context *ctx)
    }
 
    if (state & MESA_META_COLOR_MASK) {
-      GLuint i;
-      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
-         if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
-            if (i == 0) {
-               _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
-                               save->ColorMask[i][2], save->ColorMask[i][3]);
-            }
-            else {
-               _mesa_ColorMaskIndexed(i,
-                                      save->ColorMask[i][0],
-                                      save->ColorMask[i][1],
-                                      save->ColorMask[i][2],
-                                      save->ColorMask[i][3]);
-            }
-         }
+      if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask)) {
+         _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
+                         save->ColorMask[2], save->ColorMask[3]);         
       }
    }
 
@@ -1020,24 +900,6 @@ get_temp_texture(struct gl_context *ctx)
 }
 
 
-/**
- * Return pointer to temp_texture info for _mesa_meta_bitmap().
- * We use a separate texture for bitmaps to reduce texture
- * allocation/deallocation.
- */
-static struct temp_texture *
-get_bitmap_temp_texture(struct gl_context *ctx)
-{
-   struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
-
-   if (!tex->TexObj) {
-      init_temp_texture(ctx, tex);
-   }
-
-   return tex;
-}
-
-
 /**
  * Compute the width/height of texture needed to draw an image of the
  * given size.  Return a flag indicating whether the current texture
@@ -1131,314 +993,97 @@ setup_copypix_texture(struct temp_texture *tex,
    }
 }
 
-
-/**
- * Setup/load texture for glDrawPixels.
- */
-static void
-setup_drawpix_texture(struct gl_context *ctx,
-                     struct temp_texture *tex,
-                      GLboolean newTex,
-                      GLenum texIntFormat,
-                      GLsizei width, GLsizei height,
-                      GLenum format, GLenum type,
-                      const GLvoid *pixels)
-{
-   _mesa_BindTexture(tex->Target, tex->TexObj);
-   _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-   _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-   _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-   /* copy pixel data to texture */
-   if (newTex) {
-      /* create new tex image */
-      if (tex->Width == width && tex->Height == height) {
-         /* create new tex and load image data */
-         _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
-                          tex->Width, tex->Height, 0, format, type, pixels);
-      }
-      else {
-        struct gl_buffer_object *save_unpack_obj = NULL;
-
-        _mesa_reference_buffer_object(ctx, &save_unpack_obj,
-                                      ctx->Unpack.BufferObj);
-        _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
-         /* create empty texture */
-         _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
-                          tex->Width, tex->Height, 0, format, type, NULL);
-        if (save_unpack_obj != NULL)
-           _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
-                               save_unpack_obj->Name);
-         /* load image */
-         _mesa_TexSubImage2D(tex->Target, 0,
-                             0, 0, width, height, format, type, pixels);
-      }
-   }
-   else {
-      /* replace existing tex image */
-      _mesa_TexSubImage2D(tex->Target, 0,
-                          0, 0, width, height, format, type, pixels);
-   }
-}
-
-
-
-/**
- * One-time init for drawing depth pixels.
- */
-static void
-init_blit_depth_pixels(struct gl_context *ctx)
-{
-   static const char *program =
-      "!!ARBfp1.0\n"
-      "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
-      "END \n";
-   char program2[200];
-   struct blit_state *blit = &ctx->Meta->Blit;
-   const char *texTarget;
-
-   assert(blit->DepthFP == 0);
-
-   /* replace %s with "RECT" or "2D" */
-   assert(strlen(program) + 4 < sizeof(program2));
-   texTarget = "2D";
-   _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
-   _mesa_GenPrograms(1, &blit->DepthFP);
-   _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
-   _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
-                          strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * Try to do a glBlitFramebuffer using no-copy texturing.
- * We can do this when the src renderbuffer is actually a texture.
- * But if the src buffer == dst buffer we cannot do this.
- *
- * \return new buffer mask indicating the buffers left to blit using the
- *         normal path.
- */
-static GLbitfield
-blitframebuffer_texture(struct gl_context *ctx,
-                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                        GLbitfield mask, GLenum filter)
-{
-   if (mask & GL_COLOR_BUFFER_BIT) {
-      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
-      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
-      const struct gl_renderbuffer_attachment *drawAtt =
-         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
-      const struct gl_renderbuffer_attachment *readAtt =
-         &readFb->Attachment[readFb->_ColorReadBufferIndex];
-
-      if (readAtt && readAtt->Texture) {
-         const struct gl_texture_object *texObj = readAtt->Texture;
-         const GLuint srcLevel = readAtt->TextureLevel;
-         const GLenum minFilterSave = texObj->Sampler.MinFilter;
-         const GLenum magFilterSave = texObj->Sampler.MagFilter;
-         const GLint baseLevelSave = texObj->BaseLevel;
-         const GLint maxLevelSave = texObj->MaxLevel;
-         const GLenum wrapSSave = texObj->Sampler.WrapS;
-         const GLenum wrapTSave = texObj->Sampler.WrapT;
-         const GLenum target = texObj->Target;
-
-         if (drawAtt->Texture == readAtt->Texture) {
-            /* Can't use same texture as both the source and dest.  We need
-             * to handle overlapping blits and besides, some hw may not
-             * support this.
-             */
-            return mask;
-         }
-
-         if (target != GL_TEXTURE_2D) {
-            /* Can't handle other texture types at this time */
-            return mask;
-         }
-
-         /*
-         printf("Blit from texture!\n");
-         printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);
-         printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);
-         */
-
-         /* Prepare src texture state */
-         _mesa_BindTexture(target, texObj->Name);
-         _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
-         _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
-         _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
-         _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
-         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-         _mesa_set_enable(ctx, target, GL_TRUE);
-
-         /* Prepare vertex data (the VBO was previously created and bound) */
-         {
-            struct vertex {
-               GLfloat x, y, s, t;
-            };
-            struct vertex verts[4];
-            GLfloat s0, t0, s1, t1;
-
-            const struct gl_texture_image *texImage
-                = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
-            s0 = srcX0 / (float) texImage->Width;
-            s1 = srcX1 / (float) texImage->Width;
-            t0 = srcY0 / (float) texImage->Height;
-            t1 = srcY1 / (float) texImage->Height;
-
-            verts[0].x = (GLfloat) dstX0;
-            verts[0].y = (GLfloat) dstY0;
-            verts[1].x = (GLfloat) dstX1;
-            verts[1].y = (GLfloat) dstY0;
-            verts[2].x = (GLfloat) dstX1;
-            verts[2].y = (GLfloat) dstY1;
-            verts[3].x = (GLfloat) dstX0;
-            verts[3].y = (GLfloat) dstY1;
-
-            verts[0].s = s0;
-            verts[0].t = t0;
-            verts[1].s = s1;
-            verts[1].t = t0;
-            verts[2].s = s1;
-            verts[2].t = t1;
-            verts[3].s = s0;
-            verts[3].t = t1;
-
-            _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
-         }
-
-         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-         /* Restore texture object state, the texture binding will
-          * be restored by _mesa_meta_end().
-          */
-         _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
-         _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
-         _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
-         _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
-         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
-         _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
-
-         /* Done with color buffer */
-         mask &= ~GL_COLOR_BUFFER_BIT;
-      }
-   }
-
-   return mask;
-}
-
-
 /**
- * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
- * of texture mapping and polygon rendering.
+ * Meta implementation of ctx->Driver.CopyPixels() in terms
+ * of texture mapping and polygon rendering and GLSL shaders.
  */
 void
-_mesa_meta_BlitFramebuffer(struct gl_context *ctx,
-                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                           GLbitfield mask, GLenum filter)
+_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
+                      GLsizei width, GLsizei height,
+                      GLint dstX, GLint dstY, GLenum type)
 {
-   struct blit_state *blit = &ctx->Meta->Blit;
+   struct copypix_state *copypix = &ctx->Meta->CopyPix;
    struct temp_texture *tex = get_temp_texture(ctx);
-   const GLsizei maxTexSize = tex->MaxSize;
-   const GLint srcX = MIN2(srcX0, srcX1);
-   const GLint srcY = MIN2(srcY0, srcY1);
-   const GLint srcW = abs(srcX1 - srcX0);
-   const GLint srcH = abs(srcY1 - srcY0);
-   const GLboolean srcFlipX = srcX1 < srcX0;
-   const GLboolean srcFlipY = srcY1 < srcY0;
    struct vertex {
-      GLfloat x, y, s, t;
+      GLfloat x, y, z, s, t;
    };
    struct vertex verts[4];
    GLboolean newTex;
+   GLenum intFormat = GL_RGBA;
 
-   /* In addition to falling back if the blit size is larger than the maximum
-    * texture size, fallback if the source is multisampled.  This fallback can
-    * be removed once Mesa gets support ARB_texture_multisample.
-    */
-   if (srcW > maxTexSize || srcH > maxTexSize
-       || ctx->ReadBuffer->Visual.samples > 0) {
+   if (type != GL_COLOR ||
+       ctx->_ImageTransferState ||
+       ctx->Fog.Enabled ||
+       width > tex->MaxSize ||
+       height > tex->MaxSize) {
       /* XXX avoid this fallback */
-      _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
-                              dstX0, dstY0, dstX1, dstY1, mask, filter);
+      _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
       return;
    }
 
-   if (srcFlipX) {
-      GLint tmp = dstX0;
-      dstX0 = dstX1;
-      dstX1 = tmp;
-   }
-
-   if (srcFlipY) {
-      GLint tmp = dstY0;
-      dstY0 = dstY1;
-      dstY1 = tmp;
-   }
-
-   /* only scissor effects blit so save/clear all other relevant state */
-   _mesa_meta_begin(ctx, ~MESA_META_SCISSOR);
+   /* Most GL state applies to glCopyPixels, but a there's a few things
+    * we need to override:
+    */
+   _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
+                          MESA_META_SHADER |
+                          MESA_META_TEXTURE |
+                          MESA_META_TRANSFORM |
+                          MESA_META_CLIP |
+                          MESA_META_VERTEX |
+                          MESA_META_VIEWPORT));
 
-   if (blit->ArrayObj == 0) {
+   if (copypix->ArrayObj == 0) {
       /* one-time setup */
 
       /* create vertex array object */
-      _mesa_GenVertexArrays(1, &blit->ArrayObj);
-      _mesa_BindVertexArray(blit->ArrayObj);
+      _mesa_GenVertexArrays(1, &copypix->ArrayObj);
+      _mesa_BindVertexArray(copypix->ArrayObj);
 
       /* create vertex array buffer */
-      _mesa_GenBuffersARB(1, &blit->VBO);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+      _mesa_GenBuffersARB(1, &copypix->VBO);
+      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
                           NULL, GL_DYNAMIC_DRAW_ARB);
 
       /* setup vertex arrays */
-      _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
       _mesa_EnableClientState(GL_VERTEX_ARRAY);
       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
    }
    else {
-      _mesa_BindVertexArray(blit->ArrayObj);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
-   }
-
-   /* Try faster, direct texture approach first */
-   mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
-                                  dstX0, dstY0, dstX1, dstY1, mask, filter);
-   if (mask == 0x0) {
-      _mesa_meta_end(ctx);
-      return;
+      _mesa_BindVertexArray(copypix->ArrayObj);
+      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
    }
 
-   /* Continue with "normal" approach which involves copying the src rect
-    * into a temporary texture and is "blitted" by drawing a textured quad.
-    */
-
-   newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
+   newTex = alloc_texture(tex, width, height, intFormat);
 
-   /* vertex positions/texcoords (after texture allocation!) */
+   /* vertex positionstexcoords (after texture allocation!) */
    {
-      verts[0].x = (GLfloat) dstX0;
-      verts[0].y = (GLfloat) dstY0;
-      verts[1].x = (GLfloat) dstX1;
-      verts[1].y = (GLfloat) dstY0;
-      verts[2].x = (GLfloat) dstX1;
-      verts[2].y = (GLfloat) dstY1;
-      verts[3].x = (GLfloat) dstX0;
-      verts[3].y = (GLfloat) dstY1;
+      const GLfloat dstX0 = (GLfloat) dstX;
+      const GLfloat dstY0 = (GLfloat) dstY;
+      const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
+      const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
+      const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
 
+      verts[0].x = dstX0;
+      verts[0].y = dstY0;
+      verts[0].z = z;
       verts[0].s = 0.0F;
       verts[0].t = 0.0F;
+      verts[1].x = dstX1;
+      verts[1].y = dstY0;
+      verts[1].z = z;
       verts[1].s = tex->Sright;
       verts[1].t = 0.0F;
+      verts[2].x = dstX1;
+      verts[2].y = dstY1;
+      verts[2].z = z;
       verts[2].s = tex->Sright;
       verts[2].t = tex->Ttop;
+      verts[3].x = dstX0;
+      verts[3].y = dstY1;
+      verts[3].z = z;
       verts[3].s = 0.0F;
       verts[3].t = tex->Ttop;
 
@@ -1446,1079 +1091,20 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
    }
 
-   _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
-   if (mask & GL_COLOR_BUFFER_BIT) {
-      setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
-                            GL_RGBA, filter);
-      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-      mask &= ~GL_COLOR_BUFFER_BIT;
-   }
-
-   if (mask & GL_DEPTH_BUFFER_BIT) {
-      GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
-      if (tmp) {
-         if (!blit->DepthFP)
-            init_blit_depth_pixels(ctx);
-
-         /* maybe change tex format here */
-         newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
-
-         _mesa_ReadPixels(srcX, srcY, srcW, srcH,
-                          GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
-
-         setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
-                               GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
-
-         _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
-         _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
-         _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-         _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
-         _mesa_DepthFunc(GL_ALWAYS);
-         _mesa_DepthMask(GL_TRUE);
-
-         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-         mask &= ~GL_DEPTH_BUFFER_BIT;
+   /* Alloc/setup texture */
+   setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
+                         GL_RGBA, GL_NEAREST);
 
-         free(tmp);
-      }
-   }
+   _mesa_set_enable(ctx, tex->Target, GL_TRUE);
 
-   if (mask & GL_STENCIL_BUFFER_BIT) {
-      /* XXX can't easily do stencil */
-   }
+   /* draw textured quad */
+   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
 
    _mesa_meta_end(ctx);
-
-   if (mask) {
-      _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
-                              dstX0, dstY0, dstX1, dstY1, mask, filter);
-   }
-}
-
-static void
-meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
-{
-   if (blit->ArrayObj) {
-      _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj);
-      blit->ArrayObj = 0;
-      _mesa_DeleteBuffersARB(1, &blit->VBO);
-      blit->VBO = 0;
-   }
-   if (blit->DepthFP) {
-      _mesa_DeletePrograms(1, &blit->DepthFP);
-      blit->DepthFP = 0;
-   }
 }
 
-
-/**
- * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
- */
-void
-_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
-{
-   struct clear_state *clear = &ctx->Meta->Clear;
-   struct vertex {
-      GLfloat x, y, z, r, g, b, a;
-   };
-   struct vertex verts[4];
-   /* save all state but scissor, pixel pack/unpack */
-   GLbitfield metaSave = (MESA_META_ALL -
-                         MESA_META_SCISSOR -
-                         MESA_META_PIXEL_STORE);
-   const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
-
-   if (buffers & BUFFER_BITS_COLOR) {
-      /* if clearing color buffers, don't save/restore colormask */
-      metaSave -= MESA_META_COLOR_MASK;
-   }
-
-   _mesa_meta_begin(ctx, metaSave);
-
-   if (clear->ArrayObj == 0) {
-      /* one-time setup */
-
-      /* create vertex array object */
-      _mesa_GenVertexArrays(1, &clear->ArrayObj);
-      _mesa_BindVertexArray(clear->ArrayObj);
-
-      /* create vertex array buffer */
-      _mesa_GenBuffersARB(1, &clear->VBO);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
-      /* setup vertex arrays */
-      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
-      _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
-      _mesa_EnableClientState(GL_VERTEX_ARRAY);
-      _mesa_EnableClientState(GL_COLOR_ARRAY);
-   }
-   else {
-      _mesa_BindVertexArray(clear->ArrayObj);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-   }
-
-   /* GL_COLOR_BUFFER_BIT */
-   if (buffers & BUFFER_BITS_COLOR) {
-      /* leave colormask, glDrawBuffer state as-is */
-
-      /* Clears never have the color clamped. */
-      _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
-   }
-   else {
-      ASSERT(metaSave & MESA_META_COLOR_MASK);
-      _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-   }
-
-   /* GL_DEPTH_BUFFER_BIT */
-   if (buffers & BUFFER_BIT_DEPTH) {
-      _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
-      _mesa_DepthFunc(GL_ALWAYS);
-      _mesa_DepthMask(GL_TRUE);
-   }
-   else {
-      assert(!ctx->Depth.Test);
-   }
-
-   /* GL_STENCIL_BUFFER_BIT */
-   if (buffers & BUFFER_BIT_STENCIL) {
-      _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
-      _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
-                              GL_REPLACE, GL_REPLACE, GL_REPLACE);
-      _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
-                                ctx->Stencil.Clear & stencilMax,
-                                ctx->Stencil.WriteMask[0]);
-   }
-   else {
-      assert(!ctx->Stencil.Enabled);
-   }
-
-   /* vertex positions/colors */
-   {
-      const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
-      const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
-      const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
-      const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
-      const GLfloat z = invert_z(ctx->Depth.Clear);
-      GLuint i;
-
-      verts[0].x = x0;
-      verts[0].y = y0;
-      verts[0].z = z;
-      verts[1].x = x1;
-      verts[1].y = y0;
-      verts[1].z = z;
-      verts[2].x = x1;
-      verts[2].y = y1;
-      verts[2].z = z;
-      verts[3].x = x0;
-      verts[3].y = y1;
-      verts[3].z = z;
-
-      /* vertex colors */
-      for (i = 0; i < 4; i++) {
-         verts[i].r = ctx->Color.ClearColor.f[0];
-         verts[i].g = ctx->Color.ClearColor.f[1];
-         verts[i].b = ctx->Color.ClearColor.f[2];
-         verts[i].a = ctx->Color.ClearColor.f[3];
-      }
-
-      /* upload new vertex data */
-      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
-                         GL_DYNAMIC_DRAW_ARB);
-   }
-
-   /* draw quad */
-   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-   _mesa_meta_end(ctx);
-}
-
-static void
-meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
-{
-   const char *vs_source =
-      "attribute vec4 position;\n"
-      "void main()\n"
-      "{\n"
-      "   gl_Position = position;\n"
-      "}\n";
-   const char *fs_source =
-      "uniform vec4 color;\n"
-      "void main()\n"
-      "{\n"
-      "   gl_FragColor = color;\n"
-      "}\n";
-   const char *vs_int_source =
-      "#version 130\n"
-      "attribute vec4 position;\n"
-      "void main()\n"
-      "{\n"
-      "   gl_Position = position;\n"
-      "}\n";
-   const char *fs_int_source =
-      "#version 130\n"
-      "uniform ivec4 color;\n"
-      "out ivec4 out_color;\n"
-      "\n"
-      "void main()\n"
-      "{\n"
-      "   out_color = color;\n"
-      "}\n";
-   GLuint vs, fs;
-
-   if (clear->ArrayObj != 0)
-      return;
-
-   /* create vertex array object */
-   _mesa_GenVertexArrays(1, &clear->ArrayObj);
-   _mesa_BindVertexArray(clear->ArrayObj);
-
-   /* create vertex array buffer */
-   _mesa_GenBuffersARB(1, &clear->VBO);
-   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
-   /* setup vertex arrays */
-   _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-   _mesa_EnableVertexAttribArrayARB(0);
-
-   vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER);
-   _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL);
-   _mesa_CompileShaderARB(vs);
-
-   fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
-   _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL);
-   _mesa_CompileShaderARB(fs);
-
-   clear->ShaderProg = _mesa_CreateProgramObjectARB();
-   _mesa_AttachShader(clear->ShaderProg, fs);
-   _mesa_DeleteObjectARB(fs);
-   _mesa_AttachShader(clear->ShaderProg, vs);
-   _mesa_DeleteObjectARB(vs);
-   _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position");
-   _mesa_LinkProgramARB(clear->ShaderProg);
-
-   clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg,
-                                                     "color");
-
-   if (ctx->Const.GLSLVersion >= 130) {
-      vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
-      fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
-
-      clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
-      _mesa_AttachShader(clear->IntegerShaderProg, fs);
-      _mesa_DeleteObjectARB(fs);
-      _mesa_AttachShader(clear->IntegerShaderProg, vs);
-      _mesa_DeleteObjectARB(vs);
-      _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position");
-
-      /* Note that user-defined out attributes get automatically assigned
-       * locations starting from 0, so we don't need to explicitly
-       * BindFragDataLocation to 0.
-       */
-
-      link_program_with_debug(ctx, clear->IntegerShaderProg);
-
-      clear->IntegerColorLocation =
-        _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color");
-   }
-}
-
-static void
-meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
-{
-   if (clear->ArrayObj == 0)
-      return;
-   _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj);
-   clear->ArrayObj = 0;
-   _mesa_DeleteBuffersARB(1, &clear->VBO);
-   clear->VBO = 0;
-   _mesa_DeleteObjectARB(clear->ShaderProg);
-   clear->ShaderProg = 0;
-
-   if (clear->IntegerShaderProg) {
-      _mesa_DeleteObjectARB(clear->IntegerShaderProg);
-      clear->IntegerShaderProg = 0;
-   }
-}
-
-/**
- * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
- */
-void
-_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
-{
-   struct clear_state *clear = &ctx->Meta->Clear;
-   GLbitfield metaSave;
-   const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   const float x0 = ((float)fb->_Xmin / fb->Width)  * 2.0f - 1.0f;
-   const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f;
-   const float x1 = ((float)fb->_Xmax / fb->Width)  * 2.0f - 1.0f;
-   const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f;
-   const float z = -invert_z(ctx->Depth.Clear);
-   struct vertex {
-      GLfloat x, y, z;
-   } verts[4];
-
-   metaSave = (MESA_META_ALPHA_TEST |
-              MESA_META_BLEND |
-              MESA_META_DEPTH_TEST |
-              MESA_META_RASTERIZATION |
-              MESA_META_SHADER |
-              MESA_META_STENCIL_TEST |
-              MESA_META_VERTEX |
-              MESA_META_VIEWPORT |
-              MESA_META_CLIP |
-              MESA_META_CLAMP_FRAGMENT_COLOR);
-
-   if (!(buffers & BUFFER_BITS_COLOR)) {
-      /* We'll use colormask to disable color writes.  Otherwise,
-       * respect color mask
-       */
-      metaSave |= MESA_META_COLOR_MASK;
-   }
-
-   _mesa_meta_begin(ctx, metaSave);
-
-   meta_glsl_clear_init(ctx, clear);
-
-   if (fb->_IntegerColor) {
-      _mesa_UseProgramObjectARB(clear->IntegerShaderProg);
-      _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1,
-                         ctx->Color.ClearColor.i);
-   } else {
-      _mesa_UseProgramObjectARB(clear->ShaderProg);
-      _mesa_Uniform4fvARB(clear->ColorLocation, 1,
-                         ctx->Color.ClearColor.f);
-   }
-
-   _mesa_BindVertexArray(clear->ArrayObj);
-   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
-
-   /* GL_COLOR_BUFFER_BIT */
-   if (buffers & BUFFER_BITS_COLOR) {
-      /* leave colormask, glDrawBuffer state as-is */
-
-      /* Clears never have the color clamped. */
-      _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
-   }
-   else {
-      ASSERT(metaSave & MESA_META_COLOR_MASK);
-      _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-   }
-
-   /* GL_DEPTH_BUFFER_BIT */
-   if (buffers & BUFFER_BIT_DEPTH) {
-      _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
-      _mesa_DepthFunc(GL_ALWAYS);
-      _mesa_DepthMask(GL_TRUE);
-   }
-   else {
-      assert(!ctx->Depth.Test);
-   }
-
-   /* GL_STENCIL_BUFFER_BIT */
-   if (buffers & BUFFER_BIT_STENCIL) {
-      _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
-      _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
-                              GL_REPLACE, GL_REPLACE, GL_REPLACE);
-      _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
-                                ctx->Stencil.Clear & stencilMax,
-                                ctx->Stencil.WriteMask[0]);
-   }
-   else {
-      assert(!ctx->Stencil.Enabled);
-   }
-
-   /* vertex positions */
-   verts[0].x = x0;
-   verts[0].y = y0;
-   verts[0].z = z;
-   verts[1].x = x1;
-   verts[1].y = y0;
-   verts[1].z = z;
-   verts[2].x = x1;
-   verts[2].y = y1;
-   verts[2].z = z;
-   verts[3].x = x0;
-   verts[3].y = y1;
-   verts[3].z = z;
-
-   /* upload new vertex data */
-   _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
-                      GL_DYNAMIC_DRAW_ARB);
-
-   /* draw quad */
-   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-   _mesa_meta_end(ctx);
-}
-
-/**
- * Meta implementation of ctx->Driver.CopyPixels() in terms
- * of texture mapping and polygon rendering and GLSL shaders.
- */
-void
-_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
-                      GLsizei width, GLsizei height,
-                      GLint dstX, GLint dstY, GLenum type)
-{
-   struct copypix_state *copypix = &ctx->Meta->CopyPix;
-   struct temp_texture *tex = get_temp_texture(ctx);
-   struct vertex {
-      GLfloat x, y, z, s, t;
-   };
-   struct vertex verts[4];
-   GLboolean newTex;
-   GLenum intFormat = GL_RGBA;
-
-   if (type != GL_COLOR ||
-       ctx->_ImageTransferState ||
-       ctx->Fog.Enabled ||
-       width > tex->MaxSize ||
-       height > tex->MaxSize) {
-      /* XXX avoid this fallback */
-      _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
-      return;
-   }
-
-   /* Most GL state applies to glCopyPixels, but a there's a few things
-    * we need to override:
-    */
-   _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
-                          MESA_META_SHADER |
-                          MESA_META_TEXTURE |
-                          MESA_META_TRANSFORM |
-                          MESA_META_CLIP |
-                          MESA_META_VERTEX |
-                          MESA_META_VIEWPORT));
-
-   if (copypix->ArrayObj == 0) {
-      /* one-time setup */
-
-      /* create vertex array object */
-      _mesa_GenVertexArrays(1, &copypix->ArrayObj);
-      _mesa_BindVertexArray(copypix->ArrayObj);
-
-      /* create vertex array buffer */
-      _mesa_GenBuffersARB(1, &copypix->VBO);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
-      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
-                          NULL, GL_DYNAMIC_DRAW_ARB);
-
-      /* setup vertex arrays */
-      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
-      _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
-      _mesa_EnableClientState(GL_VERTEX_ARRAY);
-      _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
-   }
-   else {
-      _mesa_BindVertexArray(copypix->ArrayObj);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
-   }
-
-   newTex = alloc_texture(tex, width, height, intFormat);
-
-   /* vertex positions, texcoords (after texture allocation!) */
-   {
-      const GLfloat dstX0 = (GLfloat) dstX;
-      const GLfloat dstY0 = (GLfloat) dstY;
-      const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
-      const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
-      const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
-
-      verts[0].x = dstX0;
-      verts[0].y = dstY0;
-      verts[0].z = z;
-      verts[0].s = 0.0F;
-      verts[0].t = 0.0F;
-      verts[1].x = dstX1;
-      verts[1].y = dstY0;
-      verts[1].z = z;
-      verts[1].s = tex->Sright;
-      verts[1].t = 0.0F;
-      verts[2].x = dstX1;
-      verts[2].y = dstY1;
-      verts[2].z = z;
-      verts[2].s = tex->Sright;
-      verts[2].t = tex->Ttop;
-      verts[3].x = dstX0;
-      verts[3].y = dstY1;
-      verts[3].z = z;
-      verts[3].s = 0.0F;
-      verts[3].t = tex->Ttop;
-
-      /* upload new vertex data */
-      _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
-   }
-
-   /* Alloc/setup texture */
-   setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
-                         GL_RGBA, GL_NEAREST);
-
-   _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
-   /* draw textured quad */
-   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-   _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
-   _mesa_meta_end(ctx);
-}
-
-
-
-/**
- * When the glDrawPixels() image size is greater than the max rectangle
- * texture size we use this function to break the glDrawPixels() image
- * into tiles which fit into the max texture size.
- */
-static void
-tiled_draw_pixels(struct gl_context *ctx,
-                  GLint tileSize,
-                  GLint x, GLint y, GLsizei width, GLsizei height,
-                  GLenum format, GLenum type,
-                  const struct gl_pixelstore_attrib *unpack,
-                  const GLvoid *pixels)
-{
-   struct gl_pixelstore_attrib tileUnpack = *unpack;
-   GLint i, j;
-
-   if (tileUnpack.RowLength == 0)
-      tileUnpack.RowLength = width;
-
-   for (i = 0; i < width; i += tileSize) {
-      const GLint tileWidth = MIN2(tileSize, width - i);
-      const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
-
-      tileUnpack.SkipPixels = unpack->SkipPixels + i;
-
-      for (j = 0; j < height; j += tileSize) {
-         const GLint tileHeight = MIN2(tileSize, height - j);
-         const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
-
-         tileUnpack.SkipRows = unpack->SkipRows + j;
-
-         _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
-                               format, type, &tileUnpack, pixels);
-      }
-   }
-}
-
-
-/**
- * One-time init for drawing stencil pixels.
- */
-static void
-init_draw_stencil_pixels(struct gl_context *ctx)
-{
-   /* This program is run eight times, once for each stencil bit.
-    * The stencil values to draw are found in an 8-bit alpha texture.
-    * We read the texture/stencil value and test if bit 'b' is set.
-    * If the bit is not set, use KIL to kill the fragment.
-    * Finally, we use the stencil test to update the stencil buffer.
-    *
-    * The basic algorithm for checking if a bit is set is:
-    *   if (is_odd(value / (1 << bit)))
-    *      result is one (or non-zero).
-    *   else
-    *      result is zero.
-    * The program parameter contains three values:
-    *   parm.x = 255 / (1 << bit)
-    *   parm.y = 0.5
-    *   parm.z = 0.0
-    */
-   static const char *program =
-      "!!ARBfp1.0\n"
-      "PARAM parm = program.local[0]; \n"
-      "TEMP t; \n"
-      "TEX t, fragment.texcoord[0], texture[0], %s; \n"   /* NOTE %s here! */
-      "# t = t * 255 / bit \n"
-      "MUL t.x, t.a, parm.x; \n"
-      "# t = (int) t \n"
-      "FRC t.y, t.x; \n"
-      "SUB t.x, t.x, t.y; \n"
-      "# t = t * 0.5 \n"
-      "MUL t.x, t.x, parm.y; \n"
-      "# t = fract(t.x) \n"
-      "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
-      "# t.x = (t.x == 0 ? 1 : 0) \n"
-      "SGE t.x, -t.x, parm.z; \n"
-      "KIL -t.x; \n"
-      "# for debug only \n"
-      "#MOV result.color, t.x; \n"
-      "END \n";
-   char program2[1000];
-   struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
-   const char *texTarget;
-
-   assert(drawpix->StencilFP == 0);
-
-   /* replace %s with "RECT" or "2D" */
-   assert(strlen(program) + 4 < sizeof(program2));
-   texTarget = "2D";
-   _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
-   _mesa_GenPrograms(1, &drawpix->StencilFP);
-   _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
-   _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
-                          strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * One-time init for drawing depth pixels.
- */
-static void
-init_draw_depth_pixels(struct gl_context *ctx)
-{
-   static const char *program =
-      "!!ARBfp1.0\n"
-      "PARAM color = program.local[0]; \n"
-      "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
-      "MOV result.color, color; \n"
-      "END \n";
-   char program2[200];
-   struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
-   const char *texTarget;
-
-   assert(drawpix->DepthFP == 0);
-
-   /* replace %s with "RECT" or "2D" */
-   assert(strlen(program) + 4 < sizeof(program2));
-   texTarget = "2D";
-   _mesa_snprintf(program2, sizeof(program2), program, texTarget);
-
-   _mesa_GenPrograms(1, &drawpix->DepthFP);
-   _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
-   _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
-                          strlen(program2), (const GLubyte *) program2);
-}
-
-
-/**
- * Meta implementation of ctx->Driver.DrawPixels() in terms
- * of texture mapping and polygon rendering.
- */
-void
-_mesa_meta_DrawPixels(struct gl_context *ctx,
-                      GLint x, GLint y, GLsizei width, GLsizei height,
-                      GLenum format, GLenum type,
-                      const struct gl_pixelstore_attrib *unpack,
-                      const GLvoid *pixels)
-{
-   struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
-   struct temp_texture *tex = get_temp_texture(ctx);
-   const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
-   const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
-   struct vertex {
-      GLfloat x, y, z, s, t;
-   };
-   struct vertex verts[4];
-   GLenum texIntFormat;
-   GLboolean fallback, newTex;
-   GLbitfield metaExtraSave = 0x0;
-   GLuint vbo;
-
-   /*
-    * Determine if we can do the glDrawPixels with texture mapping.
-    */
-   fallback = GL_FALSE;
-   if (ctx->_ImageTransferState ||
-       ctx->Fog.Enabled) {
-      fallback = GL_TRUE;
-   }
-
-   if (_mesa_is_color_format(format)) {
-      /* use more compact format when possible */
-      /* XXX disable special case for GL_LUMINANCE for now to work around
-       * apparent i965 driver bug (see bug #23670).
-       */
-      if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
-         texIntFormat = format;
-      else
-         texIntFormat = GL_RGBA;
-
-      /* If we're not supposed to clamp the resulting color, then just
-       * promote our texture to fully float.  We could do better by
-       * just going for the matching set of channels, in floating
-       * point.
-       */
-      if (ctx->Color.ClampFragmentColor != GL_TRUE &&
-         ctx->Extensions.ARB_texture_float)
-        texIntFormat = GL_RGBA32F;
-   }
-   else if (_mesa_is_stencil_format(format)) {
-      if (ctx->Extensions.ARB_fragment_program &&
-          ctx->Pixel.IndexShift == 0 &&
-          ctx->Pixel.IndexOffset == 0 &&
-          type == GL_UNSIGNED_BYTE) {
-         /* We'll store stencil as alpha.  This only works for GLubyte
-          * image data because of how incoming values are mapped to alpha
-          * in [0,1].
-          */
-         texIntFormat = GL_ALPHA;
-         metaExtraSave = (MESA_META_COLOR_MASK |
-                          MESA_META_DEPTH_TEST |
-                          MESA_META_SHADER |
-                          MESA_META_STENCIL_TEST);
-      }
-      else {
-         fallback = GL_TRUE;
-      }
-   }
-   else if (_mesa_is_depth_format(format)) {
-      fallback = GL_TRUE;
-   }
-   else {
-      fallback = GL_TRUE;
-   }
-
-   if (fallback) {
-      _swrast_DrawPixels(ctx, x, y, width, height,
-                         format, type, unpack, pixels);
-      return;
-   }
-
-   /*
-    * Check image size against max texture size, draw as tiles if needed.
-    */
-   if (width > tex->MaxSize || height > tex->MaxSize) {
-      tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
-                        format, type, unpack, pixels);
-      return;
-   }
-
-   /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
-    * but a there's a few things we need to override:
-    */
-   _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
-                          MESA_META_SHADER |
-                          MESA_META_TEXTURE |
-                          MESA_META_TRANSFORM |
-                          MESA_META_CLIP |
-                          MESA_META_VERTEX |
-                          MESA_META_VIEWPORT |
-                         MESA_META_CLAMP_FRAGMENT_COLOR |
-                          metaExtraSave));
-
-   newTex = alloc_texture(tex, width, height, texIntFormat);
-
-   /* vertex positions, texcoords (after texture allocation!) */
-   {
-      const GLfloat x0 = (GLfloat) x;
-      const GLfloat y0 = (GLfloat) y;
-      const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
-      const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
-      const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
-
-      verts[0].x = x0;
-      verts[0].y = y0;
-      verts[0].z = z;
-      verts[0].s = 0.0F;
-      verts[0].t = 0.0F;
-      verts[1].x = x1;
-      verts[1].y = y0;
-      verts[1].z = z;
-      verts[1].s = tex->Sright;
-      verts[1].t = 0.0F;
-      verts[2].x = x1;
-      verts[2].y = y1;
-      verts[2].z = z;
-      verts[2].s = tex->Sright;
-      verts[2].t = tex->Ttop;
-      verts[3].x = x0;
-      verts[3].y = y1;
-      verts[3].z = z;
-      verts[3].s = 0.0F;
-      verts[3].t = tex->Ttop;
-   }
-
-   if (drawpix->ArrayObj == 0) {
-      /* one-time setup: create vertex array object */
-      _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
-   }
-   _mesa_BindVertexArray(drawpix->ArrayObj);
-
-   /* create vertex array buffer */
-   _mesa_GenBuffersARB(1, &vbo);
-   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
-   _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
-                       verts, GL_DYNAMIC_DRAW_ARB);
-
-   /* setup vertex arrays */
-   _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
-   _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
-   _mesa_EnableClientState(GL_VERTEX_ARRAY);
-   _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-   /* set given unpack params */
-   ctx->Unpack = *unpack;
-
-   _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
-   if (_mesa_is_stencil_format(format)) {
-      /* Drawing stencil */
-      GLint bit;
-
-      if (!drawpix->StencilFP)
-         init_draw_stencil_pixels(ctx);
-
-      setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
-                            GL_ALPHA, type, pixels);
-
-      _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-      _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
-
-      /* set all stencil bits to 0 */
-      _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-      _mesa_StencilFunc(GL_ALWAYS, 0, 255);
-      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-  
-      /* set stencil bits to 1 where needed */
-      _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
-      _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
-      _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
-
-      for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
-         const GLuint mask = 1 << bit;
-         if (mask & origStencilMask) {
-            _mesa_StencilFunc(GL_ALWAYS, mask, mask);
-            _mesa_StencilMask(mask);
-
-            _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
-                                             255.0 / mask, 0.5, 0.0, 0.0);
-
-            _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-         }
-      }
-   }
-   else if (_mesa_is_depth_format(format)) {
-      /* Drawing depth */
-      if (!drawpix->DepthFP)
-         init_draw_depth_pixels(ctx);
-
-      _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
-      _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
-
-      /* polygon color = current raster color */
-      _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
-                                        ctx->Current.RasterColor);
-
-      setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
-                            format, type, pixels);
-
-      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-   }
-   else {
-      /* Drawing RGBA */
-      setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
-                            format, type, pixels);
-      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-   }
-
-   _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
-   _mesa_DeleteBuffersARB(1, &vbo);
-
-   /* restore unpack params */
-   ctx->Unpack = unpackSave;
-
-   _mesa_meta_end(ctx);
-}
-
-static GLboolean
-alpha_test_raster_color(struct gl_context *ctx)
-{
-   GLfloat alpha = ctx->Current.RasterColor[ACOMP];
-   GLfloat ref = ctx->Color.AlphaRef;
-
-   switch (ctx->Color.AlphaFunc) {
-      case GL_NEVER:
-        return GL_FALSE;
-      case GL_LESS:
-        return alpha < ref;
-      case GL_EQUAL:
-        return alpha == ref;
-      case GL_LEQUAL:
-        return alpha <= ref;
-      case GL_GREATER:
-        return alpha > ref;
-      case GL_NOTEQUAL:
-        return alpha != ref;
-      case GL_GEQUAL:
-        return alpha >= ref;
-      case GL_ALWAYS:
-        return GL_TRUE;
-      default:
-        assert(0);
-        return GL_FALSE;
-   }
-}
-
-/**
- * Do glBitmap with a alpha texture quad.  Use the alpha test to cull
- * the 'off' bits.  A bitmap cache as in the gallium/mesa state
- * tracker would improve performance a lot.
- */
-void
-_mesa_meta_Bitmap(struct gl_context *ctx,
-                  GLint x, GLint y, GLsizei width, GLsizei height,
-                  const struct gl_pixelstore_attrib *unpack,
-                  const GLubyte *bitmap1)
-{
-   struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
-   struct temp_texture *tex = get_bitmap_temp_texture(ctx);
-   const GLenum texIntFormat = GL_ALPHA;
-   const struct gl_pixelstore_attrib unpackSave = *unpack;
-   GLubyte fg, bg;
-   struct vertex {
-      GLfloat x, y, z, s, t, r, g, b, a;
-   };
-   struct vertex verts[4];
-   GLboolean newTex;
-   GLubyte *bitmap8;
-
-   /*
-    * Check if swrast fallback is needed.
-    */
-   if (ctx->_ImageTransferState ||
-       ctx->FragmentProgram._Enabled ||
-       ctx->Fog.Enabled ||
-       ctx->Texture._EnabledUnits ||
-       width > tex->MaxSize ||
-       height > tex->MaxSize) {
-      _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
-      return;
-   }
-
-   if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
-      return;
-
-   /* Most GL state applies to glBitmap (like blending, stencil, etc),
-    * but a there's a few things we need to override:
-    */
-   _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST |
-                          MESA_META_PIXEL_STORE |
-                          MESA_META_RASTERIZATION |
-                          MESA_META_SHADER |
-                          MESA_META_TEXTURE |
-                          MESA_META_TRANSFORM |
-                          MESA_META_CLIP |
-                          MESA_META_VERTEX |
-                          MESA_META_VIEWPORT));
-
-   if (bitmap->ArrayObj == 0) {
-      /* one-time setup */
-
-      /* create vertex array object */
-      _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
-      _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
-
-      /* create vertex array buffer */
-      _mesa_GenBuffersARB(1, &bitmap->VBO);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
-      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
-                          NULL, GL_DYNAMIC_DRAW_ARB);
-
-      /* setup vertex arrays */
-      _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
-      _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
-      _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
-      _mesa_EnableClientState(GL_VERTEX_ARRAY);
-      _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
-      _mesa_EnableClientState(GL_COLOR_ARRAY);
-   }
-   else {
-      _mesa_BindVertexArray(bitmap->ArrayObj);
-      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
-   }
-
-   newTex = alloc_texture(tex, width, height, texIntFormat);
-
-   /* vertex positions, texcoords, colors (after texture allocation!) */
-   {
-      const GLfloat x0 = (GLfloat) x;
-      const GLfloat y0 = (GLfloat) y;
-      const GLfloat x1 = (GLfloat) (x + width);
-      const GLfloat y1 = (GLfloat) (y + height);
-      const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
-      GLuint i;
-
-      verts[0].x = x0;
-      verts[0].y = y0;
-      verts[0].z = z;
-      verts[0].s = 0.0F;
-      verts[0].t = 0.0F;
-      verts[1].x = x1;
-      verts[1].y = y0;
-      verts[1].z = z;
-      verts[1].s = tex->Sright;
-      verts[1].t = 0.0F;
-      verts[2].x = x1;
-      verts[2].y = y1;
-      verts[2].z = z;
-      verts[2].s = tex->Sright;
-      verts[2].t = tex->Ttop;
-      verts[3].x = x0;
-      verts[3].y = y1;
-      verts[3].z = z;
-      verts[3].s = 0.0F;
-      verts[3].t = tex->Ttop;
-
-      for (i = 0; i < 4; i++) {
-         verts[i].r = ctx->Current.RasterColor[0];
-         verts[i].g = ctx->Current.RasterColor[1];
-         verts[i].b = ctx->Current.RasterColor[2];
-         verts[i].a = ctx->Current.RasterColor[3];
-      }
-
-      /* upload new vertex data */
-      _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
-   }
-
-   /* choose different foreground/background alpha values */
-   CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
-   bg = (fg > 127 ? 0 : 255);
-
-   bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
-   if (!bitmap1) {
-      _mesa_meta_end(ctx);
-      return;
-   }
-
-   bitmap8 = (GLubyte *) malloc(width * height);
-   if (bitmap8) {
-      memset(bitmap8, bg, width * height);
-      _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
-                          bitmap8, width, fg);
-
-      _mesa_set_enable(ctx, tex->Target, GL_TRUE);
-
-      _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
-      _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
-
-      setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
-                            GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
-
-      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-      _mesa_set_enable(ctx, tex->Target, GL_FALSE);
-
-      free(bitmap8);
-   }
-
-   _mesa_unmap_pbo_source(ctx, &unpackSave);
-
-   _mesa_meta_end(ctx);
-}
-
-
 /**
  * Check if the call to _mesa_meta_GenerateMipmap() will require a
  * software fallback.  The fallback path will require that the texture