Home | History | Annotate | Download | only in common
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.6
      4  *
      5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /**
     26  * Meta operations.  Some GL operations can be expressed in terms of
     27  * other GL operations.  For example, glBlitFramebuffer() can be done
     28  * with texture mapping and glClear() can be done with polygon rendering.
     29  *
     30  * \author Brian Paul
     31  */
     32 
     33 
     34 #include "main/glheader.h"
     35 #include "main/mtypes.h"
     36 #include "main/imports.h"
     37 #include "main/arbprogram.h"
     38 #include "main/arrayobj.h"
     39 #include "main/blend.h"
     40 #include "main/bufferobj.h"
     41 #include "main/buffers.h"
     42 #include "main/colortab.h"
     43 #include "main/condrender.h"
     44 #include "main/depth.h"
     45 #include "main/enable.h"
     46 #include "main/fbobject.h"
     47 #include "main/feedback.h"
     48 #include "main/formats.h"
     49 #include "main/glformats.h"
     50 #include "main/image.h"
     51 #include "main/macros.h"
     52 #include "main/matrix.h"
     53 #include "main/mipmap.h"
     54 #include "main/pixel.h"
     55 #include "main/pbo.h"
     56 #include "main/polygon.h"
     57 #include "main/readpix.h"
     58 #include "main/scissor.h"
     59 #include "main/shaderapi.h"
     60 #include "main/shaderobj.h"
     61 #include "main/state.h"
     62 #include "main/stencil.h"
     63 #include "main/texobj.h"
     64 #include "main/texenv.h"
     65 #include "main/texgetimage.h"
     66 #include "main/teximage.h"
     67 #include "main/texparam.h"
     68 #include "main/texstate.h"
     69 #include "main/transformfeedback.h"
     70 #include "main/uniforms.h"
     71 #include "main/varray.h"
     72 #include "main/viewport.h"
     73 #include "main/samplerobj.h"
     74 #include "program/program.h"
     75 #include "swrast/swrast.h"
     76 #include "drivers/common/meta.h"
     77 #include "main/enums.h"
     78 #include "main/glformats.h"
     79 #include "../glsl/ralloc.h"
     80 
     81 /** Return offset in bytes of the field within a vertex struct */
     82 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
     83 
     84 /**
     85  * State which we may save/restore across meta ops.
     86  * XXX this may be incomplete...
     87  */
     88 struct save_state
     89 {
     90    GLbitfield SavedState;  /**< bitmask of MESA_META_* flags */
     91 
     92    /** MESA_META_ALPHA_TEST */
     93    GLboolean AlphaEnabled;
     94    GLenum AlphaFunc;
     95    GLclampf AlphaRef;
     96 
     97    /** MESA_META_BLEND */
     98    GLbitfield BlendEnabled;
     99    GLboolean ColorLogicOpEnabled;
    100 
    101    /** MESA_META_COLOR_MASK */
    102    GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
    103 
    104    /** MESA_META_DEPTH_TEST */
    105    struct gl_depthbuffer_attrib Depth;
    106 
    107    /** MESA_META_FOG */
    108    GLboolean Fog;
    109 
    110    /** MESA_META_PIXEL_STORE */
    111    struct gl_pixelstore_attrib Pack, Unpack;
    112 
    113    /** MESA_META_PIXEL_TRANSFER */
    114    GLfloat RedBias, RedScale;
    115    GLfloat GreenBias, GreenScale;
    116    GLfloat BlueBias, BlueScale;
    117    GLfloat AlphaBias, AlphaScale;
    118    GLfloat DepthBias, DepthScale;
    119    GLboolean MapColorFlag;
    120 
    121    /** MESA_META_RASTERIZATION */
    122    GLenum FrontPolygonMode, BackPolygonMode;
    123    GLboolean PolygonOffset;
    124    GLboolean PolygonSmooth;
    125    GLboolean PolygonStipple;
    126    GLboolean PolygonCull;
    127 
    128    /** MESA_META_SCISSOR */
    129    struct gl_scissor_attrib Scissor;
    130 
    131    /** MESA_META_SHADER */
    132    GLboolean VertexProgramEnabled;
    133    struct gl_vertex_program *VertexProgram;
    134    GLboolean FragmentProgramEnabled;
    135    struct gl_fragment_program *FragmentProgram;
    136    GLboolean ATIFragmentShaderEnabled;
    137    struct gl_shader_program *VertexShader;
    138    struct gl_shader_program *GeometryShader;
    139    struct gl_shader_program *FragmentShader;
    140    struct gl_shader_program *ActiveShader;
    141 
    142    /** MESA_META_STENCIL_TEST */
    143    struct gl_stencil_attrib Stencil;
    144 
    145    /** MESA_META_TRANSFORM */
    146    GLenum MatrixMode;
    147    GLfloat ModelviewMatrix[16];
    148    GLfloat ProjectionMatrix[16];
    149    GLfloat TextureMatrix[16];
    150 
    151    /** MESA_META_CLIP */
    152    GLbitfield ClipPlanesEnabled;
    153 
    154    /** MESA_META_TEXTURE */
    155    GLuint ActiveUnit;
    156    GLuint ClientActiveUnit;
    157    /** for unit[0] only */
    158    struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
    159    /** mask of TEXTURE_2D_BIT, etc */
    160    GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
    161    GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
    162    GLuint EnvMode;  /* unit[0] only */
    163 
    164    /** MESA_META_VERTEX */
    165    struct gl_array_object *ArrayObj;
    166    struct gl_buffer_object *ArrayBufferObj;
    167 
    168    /** MESA_META_VIEWPORT */
    169    GLint ViewportX, ViewportY, ViewportW, ViewportH;
    170    GLclampd DepthNear, DepthFar;
    171 
    172    /** MESA_META_CLAMP_FRAGMENT_COLOR */
    173    GLenum ClampFragmentColor;
    174 
    175    /** MESA_META_CLAMP_VERTEX_COLOR */
    176    GLenum ClampVertexColor;
    177 
    178    /** MESA_META_CONDITIONAL_RENDER */
    179    struct gl_query_object *CondRenderQuery;
    180    GLenum CondRenderMode;
    181 
    182 #if FEATURE_feedback
    183    /** MESA_META_SELECT_FEEDBACK */
    184    GLenum RenderMode;
    185    struct gl_selection Select;
    186    struct gl_feedback Feedback;
    187 #endif
    188 
    189    /** MESA_META_MULTISAMPLE */
    190    GLboolean MultisampleEnabled;
    191 
    192    /** Miscellaneous (always disabled) */
    193    GLboolean Lighting;
    194    GLboolean RasterDiscard;
    195 #if FEATURE_EXT_transform_feedback
    196    GLboolean TransformFeedbackNeedsResume;
    197 #endif
    198 };
    199 
    200 /**
    201  * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
    202  * This is currently shared by all the meta ops.  But we could create a
    203  * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
    204  */
    205 struct temp_texture
    206 {
    207    GLuint TexObj;
    208    GLenum Target;         /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
    209    GLsizei MinSize;       /**< Min texture size to allocate */
    210    GLsizei MaxSize;       /**< Max possible texture size */
    211    GLboolean NPOT;        /**< Non-power of two size OK? */
    212    GLsizei Width, Height; /**< Current texture size */
    213    GLenum IntFormat;
    214    GLfloat Sright, Ttop;  /**< right, top texcoords */
    215 };
    216 
    217 
    218 /**
    219  * State for glBlitFramebufer()
    220  */
    221 struct blit_state
    222 {
    223    GLuint ArrayObj;
    224    GLuint VBO;
    225    GLuint DepthFP;
    226 };
    227 
    228 
    229 /**
    230  * State for glClear()
    231  */
    232 struct clear_state
    233 {
    234    GLuint ArrayObj;
    235    GLuint VBO;
    236    GLuint ShaderProg;
    237    GLint ColorLocation;
    238 
    239    GLuint IntegerShaderProg;
    240    GLint IntegerColorLocation;
    241 };
    242 
    243 
    244 /**
    245  * State for glCopyPixels()
    246  */
    247 struct copypix_state
    248 {
    249    GLuint ArrayObj;
    250    GLuint VBO;
    251 };
    252 
    253 
    254 /**
    255  * State for glDrawPixels()
    256  */
    257 struct drawpix_state
    258 {
    259    GLuint ArrayObj;
    260 
    261    GLuint StencilFP;  /**< Fragment program for drawing stencil images */
    262    GLuint DepthFP;  /**< Fragment program for drawing depth images */
    263 };
    264 
    265 
    266 /**
    267  * State for glBitmap()
    268  */
    269 struct bitmap_state
    270 {
    271    GLuint ArrayObj;
    272    GLuint VBO;
    273    struct temp_texture Tex;  /**< separate texture from other meta ops */
    274 };
    275 
    276 /**
    277  * State for GLSL texture sampler which is used to generate fragment
    278  * shader in _mesa_meta_generate_mipmap().
    279  */
    280 struct glsl_sampler {
    281    const char *type;
    282    const char *func;
    283    const char *texcoords;
    284    GLuint shader_prog;
    285 };
    286 
    287 /**
    288  * State for _mesa_meta_generate_mipmap()
    289  */
    290 struct gen_mipmap_state
    291 {
    292    GLuint ArrayObj;
    293    GLuint VBO;
    294    GLuint FBO;
    295    GLuint Sampler;
    296    GLuint ShaderProg;
    297    struct glsl_sampler sampler_1d;
    298    struct glsl_sampler sampler_2d;
    299    struct glsl_sampler sampler_3d;
    300    struct glsl_sampler sampler_cubemap;
    301    struct glsl_sampler sampler_1d_array;
    302    struct glsl_sampler sampler_2d_array;
    303 };
    304 
    305 /**
    306  * State for texture decompression
    307  */
    308 struct decompress_state
    309 {
    310    GLuint ArrayObj;
    311    GLuint VBO, FBO, RBO, Sampler;
    312    GLint Width, Height;
    313 };
    314 
    315 /**
    316  * State for glDrawTex()
    317  */
    318 struct drawtex_state
    319 {
    320    GLuint ArrayObj;
    321    GLuint VBO;
    322 };
    323 
    324 #define MAX_META_OPS_DEPTH      8
    325 /**
    326  * All per-context meta state.
    327  */
    328 struct gl_meta_state
    329 {
    330    /** Stack of state saved during meta-ops */
    331    struct save_state Save[MAX_META_OPS_DEPTH];
    332    /** Save stack depth */
    333    GLuint SaveStackDepth;
    334 
    335    struct temp_texture TempTex;
    336 
    337    struct blit_state Blit;    /**< For _mesa_meta_BlitFramebuffer() */
    338    struct clear_state Clear;  /**< For _mesa_meta_Clear() */
    339    struct copypix_state CopyPix;  /**< For _mesa_meta_CopyPixels() */
    340    struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
    341    struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
    342    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
    343    struct decompress_state Decompress;  /**< For texture decompression */
    344    struct drawtex_state DrawTex;  /**< For _mesa_meta_DrawTex() */
    345 };
    346 
    347 static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit);
    348 static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex);
    349 static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear);
    350 static void meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
    351                                               struct gen_mipmap_state *mipmap);
    352 
    353 static GLuint
    354 compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source)
    355 {
    356    GLuint shader;
    357    GLint ok, size;
    358    GLchar *info;
    359 
    360    shader = _mesa_CreateShaderObjectARB(target);
    361    _mesa_ShaderSourceARB(shader, 1, &source, NULL);
    362    _mesa_CompileShaderARB(shader);
    363 
    364    _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok);
    365    if (ok)
    366       return shader;
    367 
    368    _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
    369    if (size == 0) {
    370       _mesa_DeleteObjectARB(shader);
    371       return 0;
    372    }
    373 
    374    info = malloc(size);
    375    if (!info) {
    376       _mesa_DeleteObjectARB(shader);
    377       return 0;
    378    }
    379 
    380    _mesa_GetProgramInfoLog(shader, size, NULL, info);
    381    _mesa_problem(ctx,
    382 		 "meta program compile failed:\n%s\n"
    383 		 "source:\n%s\n",
    384 		 info, source);
    385 
    386    free(info);
    387    _mesa_DeleteObjectARB(shader);
    388 
    389    return 0;
    390 }
    391 
    392 static GLuint
    393 link_program_with_debug(struct gl_context *ctx, GLuint program)
    394 {
    395    GLint ok, size;
    396    GLchar *info;
    397 
    398    _mesa_LinkProgramARB(program);
    399 
    400    _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok);
    401    if (ok)
    402       return program;
    403 
    404    _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
    405    if (size == 0)
    406       return 0;
    407 
    408    info = malloc(size);
    409    if (!info)
    410       return 0;
    411 
    412    _mesa_GetProgramInfoLog(program, size, NULL, info);
    413    _mesa_problem(ctx, "meta program link failed:\n%s", info);
    414 
    415    free(info);
    416 
    417    return 0;
    418 }
    419 
    420 /**
    421  * Initialize meta-ops for a context.
    422  * To be called once during context creation.
    423  */
    424 void
    425 _mesa_meta_init(struct gl_context *ctx)
    426 {
    427    ASSERT(!ctx->Meta);
    428 
    429    ctx->Meta = CALLOC_STRUCT(gl_meta_state);
    430 }
    431 
    432 
    433 /**
    434  * Free context meta-op state.
    435  * To be called once during context destruction.
    436  */
    437 void
    438 _mesa_meta_free(struct gl_context *ctx)
    439 {
    440    GET_CURRENT_CONTEXT(old_context);
    441    _mesa_make_current(ctx, NULL, NULL);
    442    meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
    443    meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
    444    meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap);
    445    cleanup_temp_texture(ctx, &ctx->Meta->TempTex);
    446    if (old_context)
    447       _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
    448    else
    449       _mesa_make_current(NULL, NULL, NULL);
    450    free(ctx->Meta);
    451    ctx->Meta = NULL;
    452 }
    453 
    454 
    455 /**
    456  * This is an alternative to _mesa_set_enable() to handle some special cases.
    457  * See comments inside.
    458  */
    459 static void
    460 meta_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
    461 {
    462    switch (cap) {
    463    case GL_MULTISAMPLE:
    464       /* We need to enable/disable multisample when using GLES but this enum
    465        * is not supported there.
    466        */
    467       if (ctx->Multisample.Enabled == state)
    468          return;
    469       FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
    470       ctx->Multisample.Enabled = state;
    471       break;
    472    default:
    473       _mesa_problem(ctx, "Unexpected cap in _meta_set_enable()");
    474       return;
    475    }
    476 
    477    if (ctx->Driver.Enable) {
    478       ctx->Driver.Enable(ctx, cap, state);
    479    }
    480 }
    481 
    482 
    483 
    484 /**
    485  * Enter meta state.  This is like a light-weight version of glPushAttrib
    486  * but it also resets most GL state back to default values.
    487  *
    488  * \param state  bitmask of MESA_META_* flags indicating which attribute groups
    489  *               to save and reset to their defaults
    490  */
    491 void
    492 _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
    493 {
    494    struct save_state *save;
    495 
    496    /* hope MAX_META_OPS_DEPTH is large enough */
    497    assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);
    498 
    499    save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
    500    memset(save, 0, sizeof(*save));
    501    save->SavedState = state;
    502 
    503 #if FEATURE_EXT_transform_feedback
    504    /* Pausing transform feedback needs to be done early, or else we won't be
    505     * able to change other state.
    506     */
    507    save->TransformFeedbackNeedsResume =
    508       ctx->TransformFeedback.CurrentObject->Active &&
    509       !ctx->TransformFeedback.CurrentObject->Paused;
    510    if (save->TransformFeedbackNeedsResume)
    511       _mesa_PauseTransformFeedback();
    512 #endif
    513 
    514    if (state & MESA_META_ALPHA_TEST) {
    515       save->AlphaEnabled = ctx->Color.AlphaEnabled;
    516       save->AlphaFunc = ctx->Color.AlphaFunc;
    517       save->AlphaRef = ctx->Color.AlphaRef;
    518       if (ctx->Color.AlphaEnabled)
    519          _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
    520    }
    521 
    522    if (state & MESA_META_BLEND) {
    523       save->BlendEnabled = ctx->Color.BlendEnabled;
    524       if (ctx->Color.BlendEnabled) {
    525          if (ctx->Extensions.EXT_draw_buffers2) {
    526             GLuint i;
    527             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
    528                _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
    529             }
    530          }
    531          else {
    532             _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
    533          }
    534       }
    535       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
    536       if (ctx->Color.ColorLogicOpEnabled)
    537          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
    538    }
    539 
    540    if (state & MESA_META_COLOR_MASK) {
    541       memcpy(save->ColorMask, ctx->Color.ColorMask,
    542              sizeof(ctx->Color.ColorMask));
    543       if (!ctx->Color.ColorMask[0][0] ||
    544           !ctx->Color.ColorMask[0][1] ||
    545           !ctx->Color.ColorMask[0][2] ||
    546           !ctx->Color.ColorMask[0][3])
    547          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    548    }
    549 
    550    if (state & MESA_META_DEPTH_TEST) {
    551       save->Depth = ctx->Depth; /* struct copy */
    552       if (ctx->Depth.Test)
    553          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
    554    }
    555 
    556    if ((state & MESA_META_FOG)
    557        && ctx->API != API_OPENGL_CORE
    558        && ctx->API != API_OPENGLES2) {
    559       save->Fog = ctx->Fog.Enabled;
    560       if (ctx->Fog.Enabled)
    561          _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
    562    }
    563 
    564    if (state & MESA_META_PIXEL_STORE) {
    565       save->Pack = ctx->Pack;
    566       save->Unpack = ctx->Unpack;
    567       ctx->Pack = ctx->DefaultPacking;
    568       ctx->Unpack = ctx->DefaultPacking;
    569    }
    570 
    571    if (state & MESA_META_PIXEL_TRANSFER) {
    572       save->RedScale = ctx->Pixel.RedScale;
    573       save->RedBias = ctx->Pixel.RedBias;
    574       save->GreenScale = ctx->Pixel.GreenScale;
    575       save->GreenBias = ctx->Pixel.GreenBias;
    576       save->BlueScale = ctx->Pixel.BlueScale;
    577       save->BlueBias = ctx->Pixel.BlueBias;
    578       save->AlphaScale = ctx->Pixel.AlphaScale;
    579       save->AlphaBias = ctx->Pixel.AlphaBias;
    580       save->MapColorFlag = ctx->Pixel.MapColorFlag;
    581       ctx->Pixel.RedScale = 1.0F;
    582       ctx->Pixel.RedBias = 0.0F;
    583       ctx->Pixel.GreenScale = 1.0F;
    584       ctx->Pixel.GreenBias = 0.0F;
    585       ctx->Pixel.BlueScale = 1.0F;
    586       ctx->Pixel.BlueBias = 0.0F;
    587       ctx->Pixel.AlphaScale = 1.0F;
    588       ctx->Pixel.AlphaBias = 0.0F;
    589       ctx->Pixel.MapColorFlag = GL_FALSE;
    590       /* XXX more state */
    591       ctx->NewState |=_NEW_PIXEL;
    592    }
    593 
    594    if (state & MESA_META_RASTERIZATION) {
    595       save->FrontPolygonMode = ctx->Polygon.FrontMode;
    596       save->BackPolygonMode = ctx->Polygon.BackMode;
    597       save->PolygonOffset = ctx->Polygon.OffsetFill;
    598       save->PolygonSmooth = ctx->Polygon.SmoothFlag;
    599       save->PolygonStipple = ctx->Polygon.StippleFlag;
    600       save->PolygonCull = ctx->Polygon.CullFlag;
    601       _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    602       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
    603       if (ctx->API == API_OPENGL) {
    604          _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
    605          _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
    606       }
    607       _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
    608    }
    609 
    610    if (state & MESA_META_SCISSOR) {
    611       save->Scissor = ctx->Scissor; /* struct copy */
    612       _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE);
    613    }
    614 
    615    if (state & MESA_META_SHADER) {
    616       if (ctx->API == API_OPENGL && ctx->Extensions.ARB_vertex_program) {
    617          save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
    618          _mesa_reference_vertprog(ctx, &save->VertexProgram,
    619 				  ctx->VertexProgram.Current);
    620          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
    621       }
    622 
    623       if (ctx->API == API_OPENGL && ctx->Extensions.ARB_fragment_program) {
    624          save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
    625          _mesa_reference_fragprog(ctx, &save->FragmentProgram,
    626 				  ctx->FragmentProgram.Current);
    627          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
    628       }
    629 
    630       if (ctx->API == API_OPENGL && ctx->Extensions.ATI_fragment_shader) {
    631          save->ATIFragmentShaderEnabled = ctx->ATIFragmentShader.Enabled;
    632          _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE);
    633       }
    634 
    635       if (ctx->Extensions.ARB_shader_objects) {
    636 	 _mesa_reference_shader_program(ctx, &save->VertexShader,
    637 					ctx->Shader.CurrentVertexProgram);
    638 	 _mesa_reference_shader_program(ctx, &save->GeometryShader,
    639 					ctx->Shader.CurrentGeometryProgram);
    640 	 _mesa_reference_shader_program(ctx, &save->FragmentShader,
    641 					ctx->Shader.CurrentFragmentProgram);
    642 	 _mesa_reference_shader_program(ctx, &save->ActiveShader,
    643 					ctx->Shader.ActiveProgram);
    644 
    645          _mesa_UseProgramObjectARB(0);
    646       }
    647    }
    648 
    649    if (state & MESA_META_STENCIL_TEST) {
    650       save->Stencil = ctx->Stencil; /* struct copy */
    651       if (ctx->Stencil.Enabled)
    652          _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
    653       /* NOTE: other stencil state not reset */
    654    }
    655 
    656    if (state & MESA_META_TEXTURE) {
    657       GLuint u, tgt;
    658 
    659       save->ActiveUnit = ctx->Texture.CurrentUnit;
    660       save->ClientActiveUnit = ctx->Array.ActiveTexture;
    661       save->EnvMode = ctx->Texture.Unit[0].EnvMode;
    662 
    663       /* Disable all texture units */
    664       if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) {
    665          for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
    666             save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
    667             save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
    668             if (ctx->Texture.Unit[u].Enabled ||
    669                 ctx->Texture.Unit[u].TexGenEnabled) {
    670                _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
    671                _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
    672                if (ctx->Extensions.ARB_texture_cube_map)
    673                   _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
    674                if (ctx->Extensions.OES_EGL_image_external)
    675                   _mesa_set_enable(ctx, GL_TEXTURE_EXTERNAL_OES, GL_FALSE);
    676 
    677                if (ctx->API == API_OPENGL) {
    678                   _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
    679                   _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
    680                   if (ctx->Extensions.NV_texture_rectangle)
    681                      _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
    682                   _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
    683                   _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
    684                   _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
    685                   _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
    686                } else {
    687                   _mesa_set_enable(ctx, GL_TEXTURE_GEN_STR_OES, GL_FALSE);
    688                }
    689             }
    690          }
    691       }
    692 
    693       /* save current texture objects for unit[0] only */
    694       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
    695          _mesa_reference_texobj(&save->CurrentTexture[tgt],
    696                                 ctx->Texture.Unit[0].CurrentTex[tgt]);
    697       }
    698 
    699       /* set defaults for unit[0] */
    700       _mesa_ActiveTextureARB(GL_TEXTURE0);
    701       _mesa_ClientActiveTextureARB(GL_TEXTURE0);
    702       if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) {
    703          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    704       }
    705    }
    706 
    707    if (state & MESA_META_TRANSFORM) {
    708       GLuint activeTexture = ctx->Texture.CurrentUnit;
    709       memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
    710              16 * sizeof(GLfloat));
    711       memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
    712              16 * sizeof(GLfloat));
    713       memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
    714              16 * sizeof(GLfloat));
    715       save->MatrixMode = ctx->Transform.MatrixMode;
    716       /* set 1:1 vertex:pixel coordinate transform */
    717       _mesa_ActiveTextureARB(GL_TEXTURE0);
    718       _mesa_MatrixMode(GL_TEXTURE);
    719       _mesa_LoadIdentity();
    720       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
    721       _mesa_MatrixMode(GL_MODELVIEW);
    722       _mesa_LoadIdentity();
    723       _mesa_MatrixMode(GL_PROJECTION);
    724       _mesa_LoadIdentity();
    725       _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
    726                   0.0, ctx->DrawBuffer->Height,
    727                   -1.0, 1.0);
    728    }
    729 
    730    if (state & MESA_META_CLIP) {
    731       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
    732       if (ctx->Transform.ClipPlanesEnabled) {
    733          GLuint i;
    734          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
    735             _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
    736          }
    737       }
    738    }
    739 
    740    if (state & MESA_META_VERTEX) {
    741       /* save vertex array object state */
    742       _mesa_reference_array_object(ctx, &save->ArrayObj,
    743                                    ctx->Array.ArrayObj);
    744       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
    745                                     ctx->Array.ArrayBufferObj);
    746       /* set some default state? */
    747    }
    748 
    749    if (state & MESA_META_VIEWPORT) {
    750       /* save viewport state */
    751       save->ViewportX = ctx->Viewport.X;
    752       save->ViewportY = ctx->Viewport.Y;
    753       save->ViewportW = ctx->Viewport.Width;
    754       save->ViewportH = ctx->Viewport.Height;
    755       /* set viewport to match window size */
    756       if (ctx->Viewport.X != 0 ||
    757           ctx->Viewport.Y != 0 ||
    758           ctx->Viewport.Width != ctx->DrawBuffer->Width ||
    759           ctx->Viewport.Height != ctx->DrawBuffer->Height) {
    760          _mesa_set_viewport(ctx, 0, 0,
    761                             ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
    762       }
    763       /* save depth range state */
    764       save->DepthNear = ctx->Viewport.Near;
    765       save->DepthFar = ctx->Viewport.Far;
    766       /* set depth range to default */
    767       _mesa_DepthRange(0.0, 1.0);
    768    }
    769 
    770    if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
    771       save->ClampFragmentColor = ctx->Color.ClampFragmentColor;
    772 
    773       /* Generally in here we want to do clamping according to whether
    774        * it's for the pixel path (ClampFragmentColor is GL_TRUE),
    775        * regardless of the internal implementation of the metaops.
    776        */
    777       if (ctx->Color.ClampFragmentColor != GL_TRUE)
    778 	 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
    779    }
    780 
    781    if (state & MESA_META_CLAMP_VERTEX_COLOR) {
    782       save->ClampVertexColor = ctx->Light.ClampVertexColor;
    783 
    784       /* Generally in here we never want vertex color clamping --
    785        * result clamping is only dependent on fragment clamping.
    786        */
    787       _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
    788    }
    789 
    790    if (state & MESA_META_CONDITIONAL_RENDER) {
    791       save->CondRenderQuery = ctx->Query.CondRenderQuery;
    792       save->CondRenderMode = ctx->Query.CondRenderMode;
    793 
    794       if (ctx->Query.CondRenderQuery)
    795 	 _mesa_EndConditionalRender();
    796    }
    797 
    798 #if FEATURE_feedback
    799    if (state & MESA_META_SELECT_FEEDBACK) {
    800       save->RenderMode = ctx->RenderMode;
    801       if (ctx->RenderMode == GL_SELECT) {
    802 	 save->Select = ctx->Select; /* struct copy */
    803 	 _mesa_RenderMode(GL_RENDER);
    804       } else if (ctx->RenderMode == GL_FEEDBACK) {
    805 	 save->Feedback = ctx->Feedback; /* struct copy */
    806 	 _mesa_RenderMode(GL_RENDER);
    807       }
    808    }
    809 #endif
    810 
    811    if (state & MESA_META_MULTISAMPLE) {
    812       save->MultisampleEnabled = ctx->Multisample.Enabled;
    813       if (ctx->Multisample.Enabled)
    814          meta_set_enable(ctx, GL_MULTISAMPLE, GL_FALSE);
    815    }
    816 
    817    /* misc */
    818    {
    819       save->Lighting = ctx->Light.Enabled;
    820       if (ctx->Light.Enabled)
    821          _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
    822       save->RasterDiscard = ctx->RasterDiscard;
    823       if (ctx->RasterDiscard)
    824          _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE);
    825    }
    826 }
    827 
    828 
    829 /**
    830  * Leave meta state.  This is like a light-weight version of glPopAttrib().
    831  */
    832 void
    833 _mesa_meta_end(struct gl_context *ctx)
    834 {
    835    struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1];
    836    const GLbitfield state = save->SavedState;
    837 
    838    if (state & MESA_META_ALPHA_TEST) {
    839       if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
    840          _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
    841       _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
    842    }
    843 
    844    if (state & MESA_META_BLEND) {
    845       if (ctx->Color.BlendEnabled != save->BlendEnabled) {
    846          if (ctx->Extensions.EXT_draw_buffers2) {
    847             GLuint i;
    848             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
    849                _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
    850             }
    851          }
    852          else {
    853             _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
    854          }
    855       }
    856       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
    857          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
    858    }
    859 
    860    if (state & MESA_META_COLOR_MASK) {
    861       GLuint i;
    862       for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
    863          if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
    864             if (i == 0) {
    865                _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
    866                                save->ColorMask[i][2], save->ColorMask[i][3]);
    867             }
    868             else {
    869                _mesa_ColorMaskIndexed(i,
    870                                       save->ColorMask[i][0],
    871                                       save->ColorMask[i][1],
    872                                       save->ColorMask[i][2],
    873                                       save->ColorMask[i][3]);
    874             }
    875          }
    876       }
    877    }
    878 
    879    if (state & MESA_META_DEPTH_TEST) {
    880       if (ctx->Depth.Test != save->Depth.Test)
    881          _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
    882       _mesa_DepthFunc(save->Depth.Func);
    883       _mesa_DepthMask(save->Depth.Mask);
    884    }
    885 
    886    if ((state & MESA_META_FOG)
    887        && ctx->API != API_OPENGL_CORE
    888        && ctx->API != API_OPENGLES2) {
    889       _mesa_set_enable(ctx, GL_FOG, save->Fog);
    890    }
    891 
    892    if (state & MESA_META_PIXEL_STORE) {
    893       ctx->Pack = save->Pack;
    894       ctx->Unpack = save->Unpack;
    895    }
    896 
    897    if (state & MESA_META_PIXEL_TRANSFER) {
    898       ctx->Pixel.RedScale = save->RedScale;
    899       ctx->Pixel.RedBias = save->RedBias;
    900       ctx->Pixel.GreenScale = save->GreenScale;
    901       ctx->Pixel.GreenBias = save->GreenBias;
    902       ctx->Pixel.BlueScale = save->BlueScale;
    903       ctx->Pixel.BlueBias = save->BlueBias;
    904       ctx->Pixel.AlphaScale = save->AlphaScale;
    905       ctx->Pixel.AlphaBias = save->AlphaBias;
    906       ctx->Pixel.MapColorFlag = save->MapColorFlag;
    907       /* XXX more state */
    908       ctx->NewState |=_NEW_PIXEL;
    909    }
    910 
    911    if (state & MESA_META_RASTERIZATION) {
    912       /* Core context requires that front and back mode be the same.
    913        */
    914       if (ctx->API == API_OPENGL_CORE) {
    915          _mesa_PolygonMode(GL_FRONT_AND_BACK, save->FrontPolygonMode);
    916       } else {
    917          _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
    918          _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
    919       }
    920       if (ctx->API == API_OPENGL) {
    921          _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
    922          _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
    923       }
    924       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
    925       _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
    926    }
    927 
    928    if (state & MESA_META_SCISSOR) {
    929       _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
    930       _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
    931                     save->Scissor.Width, save->Scissor.Height);
    932    }
    933 
    934    if (state & MESA_META_SHADER) {
    935       if (ctx->API == API_OPENGL && ctx->Extensions.ARB_vertex_program) {
    936          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
    937                           save->VertexProgramEnabled);
    938          _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
    939                                   save->VertexProgram);
    940 	 _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL);
    941       }
    942 
    943       if (ctx->API == API_OPENGL && ctx->Extensions.ARB_fragment_program) {
    944          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
    945                           save->FragmentProgramEnabled);
    946          _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
    947                                   save->FragmentProgram);
    948 	 _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
    949       }
    950 
    951       if (ctx->API == API_OPENGL && ctx->Extensions.ATI_fragment_shader) {
    952          _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI,
    953                           save->ATIFragmentShaderEnabled);
    954       }
    955 
    956       if (ctx->Extensions.ARB_vertex_shader)
    957 	 _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
    958 
    959       if (ctx->Extensions.ARB_geometry_shader4)
    960 	 _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
    961 				  save->GeometryShader);
    962 
    963       if (ctx->Extensions.ARB_fragment_shader)
    964 	 _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
    965 				  save->FragmentShader);
    966 
    967       _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram,
    968 				     save->ActiveShader);
    969 
    970       _mesa_reference_shader_program(ctx, &save->VertexShader, NULL);
    971       _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL);
    972       _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL);
    973       _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL);
    974    }
    975 
    976    if (state & MESA_META_STENCIL_TEST) {
    977       const struct gl_stencil_attrib *stencil = &save->Stencil;
    978 
    979       _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
    980       _mesa_ClearStencil(stencil->Clear);
    981       if (ctx->API == API_OPENGL && ctx->Extensions.EXT_stencil_two_side) {
    982          _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
    983                           stencil->TestTwoSide);
    984          _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
    985                                     ? GL_BACK : GL_FRONT);
    986       }
    987       /* front state */
    988       _mesa_StencilFuncSeparate(GL_FRONT,
    989                                 stencil->Function[0],
    990                                 stencil->Ref[0],
    991                                 stencil->ValueMask[0]);
    992       _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
    993       _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
    994                               stencil->ZFailFunc[0],
    995                               stencil->ZPassFunc[0]);
    996       /* back state */
    997       _mesa_StencilFuncSeparate(GL_BACK,
    998                                 stencil->Function[1],
    999                                 stencil->Ref[1],
   1000                                 stencil->ValueMask[1]);
   1001       _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
   1002       _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
   1003                               stencil->ZFailFunc[1],
   1004                               stencil->ZPassFunc[1]);
   1005    }
   1006 
   1007    if (state & MESA_META_TEXTURE) {
   1008       GLuint u, tgt;
   1009 
   1010       ASSERT(ctx->Texture.CurrentUnit == 0);
   1011 
   1012       /* restore texenv for unit[0] */
   1013       if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) {
   1014          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
   1015       }
   1016 
   1017       /* restore texture objects for unit[0] only */
   1018       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
   1019 	 if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) {
   1020 	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   1021 	    _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
   1022 				   save->CurrentTexture[tgt]);
   1023 	 }
   1024          _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
   1025       }
   1026 
   1027       /* Restore fixed function texture enables, texgen */
   1028       if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) {
   1029          for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
   1030             if (ctx->Texture.Unit[u].Enabled != save->TexEnabled[u]) {
   1031                FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   1032                ctx->Texture.Unit[u].Enabled = save->TexEnabled[u];
   1033             }
   1034 
   1035             if (ctx->Texture.Unit[u].TexGenEnabled != save->TexGenEnabled[u]) {
   1036                FLUSH_VERTICES(ctx, _NEW_TEXTURE);
   1037                ctx->Texture.Unit[u].TexGenEnabled = save->TexGenEnabled[u];
   1038             }
   1039          }
   1040       }
   1041 
   1042       /* restore current unit state */
   1043       _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
   1044       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
   1045    }
   1046 
   1047    if (state & MESA_META_TRANSFORM) {
   1048       GLuint activeTexture = ctx->Texture.CurrentUnit;
   1049       _mesa_ActiveTextureARB(GL_TEXTURE0);
   1050       _mesa_MatrixMode(GL_TEXTURE);
   1051       _mesa_LoadMatrixf(save->TextureMatrix);
   1052       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
   1053 
   1054       _mesa_MatrixMode(GL_MODELVIEW);
   1055       _mesa_LoadMatrixf(save->ModelviewMatrix);
   1056 
   1057       _mesa_MatrixMode(GL_PROJECTION);
   1058       _mesa_LoadMatrixf(save->ProjectionMatrix);
   1059 
   1060       _mesa_MatrixMode(save->MatrixMode);
   1061    }
   1062 
   1063    if (state & MESA_META_CLIP) {
   1064       if (save->ClipPlanesEnabled) {
   1065          GLuint i;
   1066          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
   1067             if (save->ClipPlanesEnabled & (1 << i)) {
   1068                _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
   1069             }
   1070          }
   1071       }
   1072    }
   1073 
   1074    if (state & MESA_META_VERTEX) {
   1075       /* restore vertex buffer object */
   1076       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
   1077       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
   1078 
   1079       /* restore vertex array object */
   1080       _mesa_BindVertexArray(save->ArrayObj->Name);
   1081       _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
   1082    }
   1083 
   1084    if (state & MESA_META_VIEWPORT) {
   1085       if (save->ViewportX != ctx->Viewport.X ||
   1086           save->ViewportY != ctx->Viewport.Y ||
   1087           save->ViewportW != ctx->Viewport.Width ||
   1088           save->ViewportH != ctx->Viewport.Height) {
   1089          _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
   1090                             save->ViewportW, save->ViewportH);
   1091       }
   1092       _mesa_DepthRange(save->DepthNear, save->DepthFar);
   1093    }
   1094 
   1095    if (state & MESA_META_CLAMP_FRAGMENT_COLOR) {
   1096       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor);
   1097    }
   1098 
   1099    if (state & MESA_META_CLAMP_VERTEX_COLOR) {
   1100       _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor);
   1101    }
   1102 
   1103    if (state & MESA_META_CONDITIONAL_RENDER) {
   1104       if (save->CondRenderQuery)
   1105 	 _mesa_BeginConditionalRender(save->CondRenderQuery->Id,
   1106 				      save->CondRenderMode);
   1107    }
   1108 
   1109 #if FEATURE_feedback
   1110    if (state & MESA_META_SELECT_FEEDBACK) {
   1111       if (save->RenderMode == GL_SELECT) {
   1112 	 _mesa_RenderMode(GL_SELECT);
   1113 	 ctx->Select = save->Select;
   1114       } else if (save->RenderMode == GL_FEEDBACK) {
   1115 	 _mesa_RenderMode(GL_FEEDBACK);
   1116 	 ctx->Feedback = save->Feedback;
   1117       }
   1118    }
   1119 #endif
   1120 
   1121    if (state & MESA_META_MULTISAMPLE) {
   1122       if (ctx->Multisample.Enabled != save->MultisampleEnabled)
   1123          meta_set_enable(ctx, GL_MULTISAMPLE, save->MultisampleEnabled);
   1124    }
   1125 
   1126    /* misc */
   1127    if (save->Lighting) {
   1128       _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
   1129    }
   1130    if (save->RasterDiscard) {
   1131       _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE);
   1132    }
   1133 #if FEATURE_EXT_transform_feedback
   1134    if (save->TransformFeedbackNeedsResume)
   1135       _mesa_ResumeTransformFeedback();
   1136 #endif
   1137 
   1138    ctx->Meta->SaveStackDepth--;
   1139 }
   1140 
   1141 
   1142 /**
   1143  * Determine whether Mesa is currently in a meta state.
   1144  */
   1145 GLboolean
   1146 _mesa_meta_in_progress(struct gl_context *ctx)
   1147 {
   1148    return ctx->Meta->SaveStackDepth != 0;
   1149 }
   1150 
   1151 
   1152 /**
   1153  * Convert Z from a normalized value in the range [0, 1] to an object-space
   1154  * Z coordinate in [-1, +1] so that drawing at the new Z position with the
   1155  * default/identity ortho projection results in the original Z value.
   1156  * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z
   1157  * value comes from the clear value or raster position.
   1158  */
   1159 static INLINE GLfloat
   1160 invert_z(GLfloat normZ)
   1161 {
   1162    GLfloat objZ = 1.0f - 2.0f * normZ;
   1163    return objZ;
   1164 }
   1165 
   1166 
   1167 /**
   1168  * One-time init for a temp_texture object.
   1169  * Choose tex target, compute max tex size, etc.
   1170  */
   1171 static void
   1172 init_temp_texture(struct gl_context *ctx, struct temp_texture *tex)
   1173 {
   1174    /* prefer texture rectangle */
   1175    if (ctx->Extensions.NV_texture_rectangle) {
   1176       tex->Target = GL_TEXTURE_RECTANGLE;
   1177       tex->MaxSize = ctx->Const.MaxTextureRectSize;
   1178       tex->NPOT = GL_TRUE;
   1179    }
   1180    else {
   1181       /* use 2D texture, NPOT if possible */
   1182       tex->Target = GL_TEXTURE_2D;
   1183       tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
   1184       tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
   1185    }
   1186    tex->MinSize = 16;  /* 16 x 16 at least */
   1187    assert(tex->MaxSize > 0);
   1188 
   1189    _mesa_GenTextures(1, &tex->TexObj);
   1190 }
   1191 
   1192 static void
   1193 cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex)
   1194 {
   1195    if (!tex->TexObj)
   1196      return;
   1197    _mesa_DeleteTextures(1, &tex->TexObj);
   1198    tex->TexObj = 0;
   1199 }
   1200 
   1201 
   1202 /**
   1203  * Return pointer to temp_texture info for non-bitmap ops.
   1204  * This does some one-time init if needed.
   1205  */
   1206 static struct temp_texture *
   1207 get_temp_texture(struct gl_context *ctx)
   1208 {
   1209    struct temp_texture *tex = &ctx->Meta->TempTex;
   1210 
   1211    if (!tex->TexObj) {
   1212       init_temp_texture(ctx, tex);
   1213    }
   1214 
   1215    return tex;
   1216 }
   1217 
   1218 
   1219 /**
   1220  * Return pointer to temp_texture info for _mesa_meta_bitmap().
   1221  * We use a separate texture for bitmaps to reduce texture
   1222  * allocation/deallocation.
   1223  */
   1224 static struct temp_texture *
   1225 get_bitmap_temp_texture(struct gl_context *ctx)
   1226 {
   1227    struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
   1228 
   1229    if (!tex->TexObj) {
   1230       init_temp_texture(ctx, tex);
   1231    }
   1232 
   1233    return tex;
   1234 }
   1235 
   1236 
   1237 /**
   1238  * Compute the width/height of texture needed to draw an image of the
   1239  * given size.  Return a flag indicating whether the current texture
   1240  * can be re-used (glTexSubImage2D) or if a new texture needs to be
   1241  * allocated (glTexImage2D).
   1242  * Also, compute s/t texcoords for drawing.
   1243  *
   1244  * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
   1245  */
   1246 static GLboolean
   1247 alloc_texture(struct temp_texture *tex,
   1248               GLsizei width, GLsizei height, GLenum intFormat)
   1249 {
   1250    GLboolean newTex = GL_FALSE;
   1251 
   1252    ASSERT(width <= tex->MaxSize);
   1253    ASSERT(height <= tex->MaxSize);
   1254 
   1255    if (width > tex->Width ||
   1256        height > tex->Height ||
   1257        intFormat != tex->IntFormat) {
   1258       /* alloc new texture (larger or different format) */
   1259 
   1260       if (tex->NPOT) {
   1261          /* use non-power of two size */
   1262          tex->Width = MAX2(tex->MinSize, width);
   1263          tex->Height = MAX2(tex->MinSize, height);
   1264       }
   1265       else {
   1266          /* find power of two size */
   1267          GLsizei w, h;
   1268          w = h = tex->MinSize;
   1269          while (w < width)
   1270             w *= 2;
   1271          while (h < height)
   1272             h *= 2;
   1273          tex->Width = w;
   1274          tex->Height = h;
   1275       }
   1276 
   1277       tex->IntFormat = intFormat;
   1278 
   1279       newTex = GL_TRUE;
   1280    }
   1281 
   1282    /* compute texcoords */
   1283    if (tex->Target == GL_TEXTURE_RECTANGLE) {
   1284       tex->Sright = (GLfloat) width;
   1285       tex->Ttop = (GLfloat) height;
   1286    }
   1287    else {
   1288       tex->Sright = (GLfloat) width / tex->Width;
   1289       tex->Ttop = (GLfloat) height / tex->Height;
   1290    }
   1291 
   1292    return newTex;
   1293 }
   1294 
   1295 
   1296 /**
   1297  * Setup/load texture for glCopyPixels or glBlitFramebuffer.
   1298  */
   1299 static void
   1300 setup_copypix_texture(struct temp_texture *tex,
   1301                       GLboolean newTex,
   1302                       GLint srcX, GLint srcY,
   1303                       GLsizei width, GLsizei height, GLenum intFormat,
   1304                       GLenum filter)
   1305 {
   1306    _mesa_BindTexture(tex->Target, tex->TexObj);
   1307    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
   1308    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
   1309    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   1310 
   1311    /* copy framebuffer image to texture */
   1312    if (newTex) {
   1313       /* create new tex image */
   1314       if (tex->Width == width && tex->Height == height) {
   1315          /* create new tex with framebuffer data */
   1316          _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
   1317                               srcX, srcY, width, height, 0);
   1318       }
   1319       else {
   1320          /* create empty texture */
   1321          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
   1322                           tex->Width, tex->Height, 0,
   1323                           intFormat, GL_UNSIGNED_BYTE, NULL);
   1324          /* load image */
   1325          _mesa_CopyTexSubImage2D(tex->Target, 0,
   1326                                  0, 0, srcX, srcY, width, height);
   1327       }
   1328    }
   1329    else {
   1330       /* replace existing tex image */
   1331       _mesa_CopyTexSubImage2D(tex->Target, 0,
   1332                               0, 0, srcX, srcY, width, height);
   1333    }
   1334 }
   1335 
   1336 
   1337 /**
   1338  * Setup/load texture for glDrawPixels.
   1339  */
   1340 static void
   1341 setup_drawpix_texture(struct gl_context *ctx,
   1342 		      struct temp_texture *tex,
   1343                       GLboolean newTex,
   1344                       GLenum texIntFormat,
   1345                       GLsizei width, GLsizei height,
   1346                       GLenum format, GLenum type,
   1347                       const GLvoid *pixels)
   1348 {
   1349    _mesa_BindTexture(tex->Target, tex->TexObj);
   1350    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1351    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1352    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   1353 
   1354    /* copy pixel data to texture */
   1355    if (newTex) {
   1356       /* create new tex image */
   1357       if (tex->Width == width && tex->Height == height) {
   1358          /* create new tex and load image data */
   1359          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
   1360                           tex->Width, tex->Height, 0, format, type, pixels);
   1361       }
   1362       else {
   1363 	 struct gl_buffer_object *save_unpack_obj = NULL;
   1364 
   1365 	 _mesa_reference_buffer_object(ctx, &save_unpack_obj,
   1366 				       ctx->Unpack.BufferObj);
   1367 	 _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
   1368          /* create empty texture */
   1369          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
   1370                           tex->Width, tex->Height, 0, format, type, NULL);
   1371 	 if (save_unpack_obj != NULL)
   1372 	    _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
   1373 				save_unpack_obj->Name);
   1374          /* load image */
   1375          _mesa_TexSubImage2D(tex->Target, 0,
   1376                              0, 0, width, height, format, type, pixels);
   1377       }
   1378    }
   1379    else {
   1380       /* replace existing tex image */
   1381       _mesa_TexSubImage2D(tex->Target, 0,
   1382                           0, 0, width, height, format, type, pixels);
   1383    }
   1384 }
   1385 
   1386 
   1387 
   1388 /**
   1389  * One-time init for drawing depth pixels.
   1390  */
   1391 static void
   1392 init_blit_depth_pixels(struct gl_context *ctx)
   1393 {
   1394    static const char *program =
   1395       "!!ARBfp1.0\n"
   1396       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
   1397       "END \n";
   1398    char program2[200];
   1399    struct blit_state *blit = &ctx->Meta->Blit;
   1400    struct temp_texture *tex = get_temp_texture(ctx);
   1401    const char *texTarget;
   1402 
   1403    assert(blit->DepthFP == 0);
   1404 
   1405    /* replace %s with "RECT" or "2D" */
   1406    assert(strlen(program) + 4 < sizeof(program2));
   1407    if (tex->Target == GL_TEXTURE_RECTANGLE)
   1408       texTarget = "RECT";
   1409    else
   1410       texTarget = "2D";
   1411    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
   1412 
   1413    _mesa_GenPrograms(1, &blit->DepthFP);
   1414    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
   1415    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
   1416                           strlen(program2), (const GLubyte *) program2);
   1417 }
   1418 
   1419 
   1420 /**
   1421  * Try to do a glBlitFramebuffer using no-copy texturing.
   1422  * We can do this when the src renderbuffer is actually a texture.
   1423  * But if the src buffer == dst buffer we cannot do this.
   1424  *
   1425  * \return new buffer mask indicating the buffers left to blit using the
   1426  *         normal path.
   1427  */
   1428 static GLbitfield
   1429 blitframebuffer_texture(struct gl_context *ctx,
   1430                         GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   1431                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   1432                         GLbitfield mask, GLenum filter)
   1433 {
   1434    if (mask & GL_COLOR_BUFFER_BIT) {
   1435       const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
   1436       const struct gl_framebuffer *readFb = ctx->ReadBuffer;
   1437       const struct gl_renderbuffer_attachment *drawAtt =
   1438          &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
   1439       const struct gl_renderbuffer_attachment *readAtt =
   1440          &readFb->Attachment[readFb->_ColorReadBufferIndex];
   1441 
   1442       if (readAtt && readAtt->Texture) {
   1443          const struct gl_texture_object *texObj = readAtt->Texture;
   1444          const GLuint srcLevel = readAtt->TextureLevel;
   1445          const GLint baseLevelSave = texObj->BaseLevel;
   1446          const GLint maxLevelSave = texObj->MaxLevel;
   1447          const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;
   1448          const GLenum target = texObj->Target;
   1449          GLuint sampler, samplerSave =
   1450             ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ?
   1451             ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
   1452 
   1453          if (drawAtt->Texture == readAtt->Texture) {
   1454             /* Can't use same texture as both the source and dest.  We need
   1455              * to handle overlapping blits and besides, some hw may not
   1456              * support this.
   1457              */
   1458             return mask;
   1459          }
   1460 
   1461          if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
   1462             /* Can't handle other texture types at this time */
   1463             return mask;
   1464          }
   1465 
   1466          _mesa_GenSamplers(1, &sampler);
   1467          _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler);
   1468 
   1469          /*
   1470          printf("Blit from texture!\n");
   1471          printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);
   1472          printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);
   1473          */
   1474 
   1475          /* Prepare src texture state */
   1476          _mesa_BindTexture(target, texObj->Name);
   1477          _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter);
   1478          _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter);
   1479          if (target != GL_TEXTURE_RECTANGLE_ARB) {
   1480             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
   1481             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
   1482          }
   1483          _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1484          _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1485 
   1486 	 /* Always do our blits with no sRGB decode or encode.*/
   1487 	 if (ctx->Extensions.EXT_texture_sRGB_decode) {
   1488 	    _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT,
   1489 				GL_SKIP_DECODE_EXT);
   1490 	 }
   1491          if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_framebuffer_sRGB)
   1492              || _mesa_is_gles3(ctx)) {
   1493             _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);
   1494          }
   1495 
   1496          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   1497          _mesa_set_enable(ctx, target, GL_TRUE);
   1498 
   1499          /* Prepare vertex data (the VBO was previously created and bound) */
   1500          {
   1501             struct vertex {
   1502                GLfloat x, y, s, t;
   1503             };
   1504             struct vertex verts[4];
   1505             GLfloat s0, t0, s1, t1;
   1506 
   1507             if (target == GL_TEXTURE_2D) {
   1508                const struct gl_texture_image *texImage
   1509                    = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
   1510                s0 = srcX0 / (float) texImage->Width;
   1511                s1 = srcX1 / (float) texImage->Width;
   1512                t0 = srcY0 / (float) texImage->Height;
   1513                t1 = srcY1 / (float) texImage->Height;
   1514             }
   1515             else {
   1516                assert(target == GL_TEXTURE_RECTANGLE_ARB);
   1517                s0 = srcX0;
   1518                s1 = srcX1;
   1519                t0 = srcY0;
   1520                t1 = srcY1;
   1521             }
   1522 
   1523             verts[0].x = (GLfloat) dstX0;
   1524             verts[0].y = (GLfloat) dstY0;
   1525             verts[1].x = (GLfloat) dstX1;
   1526             verts[1].y = (GLfloat) dstY0;
   1527             verts[2].x = (GLfloat) dstX1;
   1528             verts[2].y = (GLfloat) dstY1;
   1529             verts[3].x = (GLfloat) dstX0;
   1530             verts[3].y = (GLfloat) dstY1;
   1531 
   1532             verts[0].s = s0;
   1533             verts[0].t = t0;
   1534             verts[1].s = s1;
   1535             verts[1].t = t0;
   1536             verts[2].s = s1;
   1537             verts[2].t = t1;
   1538             verts[3].s = s0;
   1539             verts[3].t = t1;
   1540 
   1541             _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   1542          }
   1543 
   1544          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   1545 
   1546          /* Restore texture object state, the texture binding will
   1547           * be restored by _mesa_meta_end().
   1548           */
   1549          if (target != GL_TEXTURE_RECTANGLE_ARB) {
   1550             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
   1551             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
   1552          }
   1553 	 if (ctx->Extensions.EXT_framebuffer_sRGB && fbo_srgb_save) {
   1554 	    _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);
   1555 	 }
   1556 
   1557          _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave);
   1558          _mesa_DeleteSamplers(1, &sampler);
   1559 
   1560          /* Done with color buffer */
   1561          mask &= ~GL_COLOR_BUFFER_BIT;
   1562       }
   1563    }
   1564 
   1565    return mask;
   1566 }
   1567 
   1568 
   1569 /**
   1570  * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
   1571  * of texture mapping and polygon rendering.
   1572  */
   1573 void
   1574 _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
   1575                            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   1576                            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   1577                            GLbitfield mask, GLenum filter)
   1578 {
   1579    struct blit_state *blit = &ctx->Meta->Blit;
   1580    struct temp_texture *tex = get_temp_texture(ctx);
   1581    const GLsizei maxTexSize = tex->MaxSize;
   1582    const GLint srcX = MIN2(srcX0, srcX1);
   1583    const GLint srcY = MIN2(srcY0, srcY1);
   1584    const GLint srcW = abs(srcX1 - srcX0);
   1585    const GLint srcH = abs(srcY1 - srcY0);
   1586    const GLboolean srcFlipX = srcX1 < srcX0;
   1587    const GLboolean srcFlipY = srcY1 < srcY0;
   1588    struct vertex {
   1589       GLfloat x, y, s, t;
   1590    };
   1591    struct vertex verts[4];
   1592    GLboolean newTex;
   1593 
   1594    /* In addition to falling back if the blit size is larger than the maximum
   1595     * texture size, fallback if the source is multisampled.  This fallback can
   1596     * be removed once Mesa gets support ARB_texture_multisample.
   1597     */
   1598    if (srcW > maxTexSize || srcH > maxTexSize
   1599        || ctx->ReadBuffer->Visual.samples > 0) {
   1600       /* XXX avoid this fallback */
   1601       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
   1602                               dstX0, dstY0, dstX1, dstY1, mask, filter);
   1603       return;
   1604    }
   1605 
   1606    if (srcFlipX) {
   1607       GLint tmp = dstX0;
   1608       dstX0 = dstX1;
   1609       dstX1 = tmp;
   1610    }
   1611 
   1612    if (srcFlipY) {
   1613       GLint tmp = dstY0;
   1614       dstY0 = dstY1;
   1615       dstY1 = tmp;
   1616    }
   1617 
   1618    /* only scissor effects blit so save/clear all other relevant state */
   1619    _mesa_meta_begin(ctx, ~MESA_META_SCISSOR);
   1620 
   1621    if (blit->ArrayObj == 0) {
   1622       /* one-time setup */
   1623 
   1624       /* create vertex array object */
   1625       _mesa_GenVertexArrays(1, &blit->ArrayObj);
   1626       _mesa_BindVertexArray(blit->ArrayObj);
   1627 
   1628       /* create vertex array buffer */
   1629       _mesa_GenBuffersARB(1, &blit->VBO);
   1630       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
   1631       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   1632                           NULL, GL_DYNAMIC_DRAW_ARB);
   1633 
   1634       /* setup vertex arrays */
   1635       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   1636       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
   1637       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   1638       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   1639    }
   1640    else {
   1641       _mesa_BindVertexArray(blit->ArrayObj);
   1642       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
   1643    }
   1644 
   1645    /* Try faster, direct texture approach first */
   1646    mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
   1647                                   dstX0, dstY0, dstX1, dstY1, mask, filter);
   1648    if (mask == 0x0) {
   1649       _mesa_meta_end(ctx);
   1650       return;
   1651    }
   1652 
   1653    /* Continue with "normal" approach which involves copying the src rect
   1654     * into a temporary texture and is "blitted" by drawing a textured quad.
   1655     */
   1656 
   1657    newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
   1658 
   1659    /* vertex positions/texcoords (after texture allocation!) */
   1660    {
   1661       verts[0].x = (GLfloat) dstX0;
   1662       verts[0].y = (GLfloat) dstY0;
   1663       verts[1].x = (GLfloat) dstX1;
   1664       verts[1].y = (GLfloat) dstY0;
   1665       verts[2].x = (GLfloat) dstX1;
   1666       verts[2].y = (GLfloat) dstY1;
   1667       verts[3].x = (GLfloat) dstX0;
   1668       verts[3].y = (GLfloat) dstY1;
   1669 
   1670       verts[0].s = 0.0F;
   1671       verts[0].t = 0.0F;
   1672       verts[1].s = tex->Sright;
   1673       verts[1].t = 0.0F;
   1674       verts[2].s = tex->Sright;
   1675       verts[2].t = tex->Ttop;
   1676       verts[3].s = 0.0F;
   1677       verts[3].t = tex->Ttop;
   1678 
   1679       /* upload new vertex data */
   1680       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   1681    }
   1682 
   1683    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
   1684 
   1685    if (mask & GL_COLOR_BUFFER_BIT) {
   1686       setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
   1687                             GL_RGBA, filter);
   1688       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   1689       mask &= ~GL_COLOR_BUFFER_BIT;
   1690    }
   1691 
   1692    if (mask & GL_DEPTH_BUFFER_BIT) {
   1693       GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
   1694       if (tmp) {
   1695          if (!blit->DepthFP)
   1696             init_blit_depth_pixels(ctx);
   1697 
   1698          /* maybe change tex format here */
   1699          newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
   1700 
   1701          _mesa_ReadPixels(srcX, srcY, srcW, srcH,
   1702                           GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
   1703 
   1704          setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
   1705                                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
   1706 
   1707          _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
   1708          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
   1709          _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1710          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
   1711          _mesa_DepthFunc(GL_ALWAYS);
   1712          _mesa_DepthMask(GL_TRUE);
   1713 
   1714          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   1715          mask &= ~GL_DEPTH_BUFFER_BIT;
   1716 
   1717          free(tmp);
   1718       }
   1719    }
   1720 
   1721    if (mask & GL_STENCIL_BUFFER_BIT) {
   1722       /* XXX can't easily do stencil */
   1723    }
   1724 
   1725    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
   1726 
   1727    _mesa_meta_end(ctx);
   1728 
   1729    if (mask) {
   1730       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
   1731                               dstX0, dstY0, dstX1, dstY1, mask, filter);
   1732    }
   1733 }
   1734 
   1735 static void
   1736 meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
   1737 {
   1738    if (blit->ArrayObj) {
   1739       _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj);
   1740       blit->ArrayObj = 0;
   1741       _mesa_DeleteBuffersARB(1, &blit->VBO);
   1742       blit->VBO = 0;
   1743    }
   1744    if (blit->DepthFP) {
   1745       _mesa_DeletePrograms(1, &blit->DepthFP);
   1746       blit->DepthFP = 0;
   1747    }
   1748 }
   1749 
   1750 
   1751 /**
   1752  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
   1753  */
   1754 void
   1755 _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
   1756 {
   1757    struct clear_state *clear = &ctx->Meta->Clear;
   1758    struct vertex {
   1759       GLfloat x, y, z, r, g, b, a;
   1760    };
   1761    struct vertex verts[4];
   1762    /* save all state but scissor, pixel pack/unpack */
   1763    GLbitfield metaSave = (MESA_META_ALL -
   1764 			  MESA_META_SCISSOR -
   1765 			  MESA_META_PIXEL_STORE -
   1766 			  MESA_META_CONDITIONAL_RENDER);
   1767    const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
   1768 
   1769    if (buffers & BUFFER_BITS_COLOR) {
   1770       /* if clearing color buffers, don't save/restore colormask */
   1771       metaSave -= MESA_META_COLOR_MASK;
   1772    }
   1773 
   1774    _mesa_meta_begin(ctx, metaSave);
   1775 
   1776    if (clear->ArrayObj == 0) {
   1777       /* one-time setup */
   1778 
   1779       /* create vertex array object */
   1780       _mesa_GenVertexArrays(1, &clear->ArrayObj);
   1781       _mesa_BindVertexArray(clear->ArrayObj);
   1782 
   1783       /* create vertex array buffer */
   1784       _mesa_GenBuffersARB(1, &clear->VBO);
   1785       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
   1786 
   1787       /* setup vertex arrays */
   1788       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   1789       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
   1790       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   1791       _mesa_EnableClientState(GL_COLOR_ARRAY);
   1792    }
   1793    else {
   1794       _mesa_BindVertexArray(clear->ArrayObj);
   1795       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
   1796    }
   1797 
   1798    /* GL_COLOR_BUFFER_BIT */
   1799    if (buffers & BUFFER_BITS_COLOR) {
   1800       /* leave colormask, glDrawBuffer state as-is */
   1801 
   1802       /* Clears never have the color clamped. */
   1803       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
   1804    }
   1805    else {
   1806       ASSERT(metaSave & MESA_META_COLOR_MASK);
   1807       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1808    }
   1809 
   1810    /* GL_DEPTH_BUFFER_BIT */
   1811    if (buffers & BUFFER_BIT_DEPTH) {
   1812       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
   1813       _mesa_DepthFunc(GL_ALWAYS);
   1814       _mesa_DepthMask(GL_TRUE);
   1815    }
   1816    else {
   1817       assert(!ctx->Depth.Test);
   1818    }
   1819 
   1820    /* GL_STENCIL_BUFFER_BIT */
   1821    if (buffers & BUFFER_BIT_STENCIL) {
   1822       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
   1823       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
   1824                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
   1825       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
   1826                                 ctx->Stencil.Clear & stencilMax,
   1827                                 ctx->Stencil.WriteMask[0]);
   1828    }
   1829    else {
   1830       assert(!ctx->Stencil.Enabled);
   1831    }
   1832 
   1833    /* vertex positions/colors */
   1834    {
   1835       const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
   1836       const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
   1837       const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
   1838       const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
   1839       const GLfloat z = invert_z(ctx->Depth.Clear);
   1840       GLuint i;
   1841 
   1842       verts[0].x = x0;
   1843       verts[0].y = y0;
   1844       verts[0].z = z;
   1845       verts[1].x = x1;
   1846       verts[1].y = y0;
   1847       verts[1].z = z;
   1848       verts[2].x = x1;
   1849       verts[2].y = y1;
   1850       verts[2].z = z;
   1851       verts[3].x = x0;
   1852       verts[3].y = y1;
   1853       verts[3].z = z;
   1854 
   1855       /* vertex colors */
   1856       for (i = 0; i < 4; i++) {
   1857          verts[i].r = ctx->Color.ClearColor.f[0];
   1858          verts[i].g = ctx->Color.ClearColor.f[1];
   1859          verts[i].b = ctx->Color.ClearColor.f[2];
   1860          verts[i].a = ctx->Color.ClearColor.f[3];
   1861       }
   1862 
   1863       /* upload new vertex data */
   1864       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
   1865 			  GL_DYNAMIC_DRAW_ARB);
   1866    }
   1867 
   1868    /* draw quad */
   1869    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   1870 
   1871    _mesa_meta_end(ctx);
   1872 }
   1873 
   1874 static void
   1875 meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
   1876 {
   1877    const char *vs_source =
   1878       "attribute vec4 position;\n"
   1879       "void main()\n"
   1880       "{\n"
   1881       "   gl_Position = position;\n"
   1882       "}\n";
   1883    const char *fs_source =
   1884       "uniform vec4 color;\n"
   1885       "void main()\n"
   1886       "{\n"
   1887       "   gl_FragColor = color;\n"
   1888       "}\n";
   1889    const char *vs_int_source =
   1890       "#version 130\n"
   1891       "in vec4 position;\n"
   1892       "void main()\n"
   1893       "{\n"
   1894       "   gl_Position = position;\n"
   1895       "}\n";
   1896    const char *fs_int_source =
   1897       "#version 130\n"
   1898       "uniform ivec4 color;\n"
   1899       "out ivec4 out_color;\n"
   1900       "\n"
   1901       "void main()\n"
   1902       "{\n"
   1903       "   out_color = color;\n"
   1904       "}\n";
   1905    GLuint vs, fs;
   1906 
   1907    if (clear->ArrayObj != 0)
   1908       return;
   1909 
   1910    /* create vertex array object */
   1911    _mesa_GenVertexArrays(1, &clear->ArrayObj);
   1912    _mesa_BindVertexArray(clear->ArrayObj);
   1913 
   1914    /* create vertex array buffer */
   1915    _mesa_GenBuffersARB(1, &clear->VBO);
   1916    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
   1917 
   1918    /* setup vertex arrays */
   1919    _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
   1920    _mesa_EnableVertexAttribArrayARB(0);
   1921 
   1922    vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER);
   1923    _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL);
   1924    _mesa_CompileShaderARB(vs);
   1925 
   1926    fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
   1927    _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL);
   1928    _mesa_CompileShaderARB(fs);
   1929 
   1930    clear->ShaderProg = _mesa_CreateProgramObjectARB();
   1931    _mesa_AttachShader(clear->ShaderProg, fs);
   1932    _mesa_DeleteObjectARB(fs);
   1933    _mesa_AttachShader(clear->ShaderProg, vs);
   1934    _mesa_DeleteObjectARB(vs);
   1935    _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position");
   1936    _mesa_LinkProgramARB(clear->ShaderProg);
   1937 
   1938    clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg,
   1939 						      "color");
   1940 
   1941    if (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) {
   1942       vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
   1943       fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
   1944 
   1945       clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
   1946       _mesa_AttachShader(clear->IntegerShaderProg, fs);
   1947       _mesa_DeleteObjectARB(fs);
   1948       _mesa_AttachShader(clear->IntegerShaderProg, vs);
   1949       _mesa_DeleteObjectARB(vs);
   1950       _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position");
   1951 
   1952       /* Note that user-defined out attributes get automatically assigned
   1953        * locations starting from 0, so we don't need to explicitly
   1954        * BindFragDataLocation to 0.
   1955        */
   1956 
   1957       link_program_with_debug(ctx, clear->IntegerShaderProg);
   1958 
   1959       clear->IntegerColorLocation =
   1960 	 _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color");
   1961    }
   1962 }
   1963 
   1964 static void
   1965 meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
   1966 {
   1967    if (clear->ArrayObj == 0)
   1968       return;
   1969    _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj);
   1970    clear->ArrayObj = 0;
   1971    _mesa_DeleteBuffersARB(1, &clear->VBO);
   1972    clear->VBO = 0;
   1973    _mesa_DeleteObjectARB(clear->ShaderProg);
   1974    clear->ShaderProg = 0;
   1975 
   1976    if (clear->IntegerShaderProg) {
   1977       _mesa_DeleteObjectARB(clear->IntegerShaderProg);
   1978       clear->IntegerShaderProg = 0;
   1979    }
   1980 }
   1981 
   1982 /**
   1983  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
   1984  */
   1985 void
   1986 _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
   1987 {
   1988    struct clear_state *clear = &ctx->Meta->Clear;
   1989    GLbitfield metaSave;
   1990    const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
   1991    struct gl_framebuffer *fb = ctx->DrawBuffer;
   1992    const float x0 = ((float)fb->_Xmin / fb->Width)  * 2.0f - 1.0f;
   1993    const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f;
   1994    const float x1 = ((float)fb->_Xmax / fb->Width)  * 2.0f - 1.0f;
   1995    const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f;
   1996    const float z = -invert_z(ctx->Depth.Clear);
   1997    struct vertex {
   1998       GLfloat x, y, z;
   1999    } verts[4];
   2000 
   2001    metaSave = (MESA_META_ALPHA_TEST |
   2002 	       MESA_META_BLEND |
   2003 	       MESA_META_DEPTH_TEST |
   2004 	       MESA_META_RASTERIZATION |
   2005 	       MESA_META_SHADER |
   2006 	       MESA_META_STENCIL_TEST |
   2007 	       MESA_META_VERTEX |
   2008 	       MESA_META_VIEWPORT |
   2009 	       MESA_META_CLIP |
   2010 	       MESA_META_CLAMP_FRAGMENT_COLOR |
   2011                MESA_META_MULTISAMPLE);
   2012 
   2013    if (!(buffers & BUFFER_BITS_COLOR)) {
   2014       /* We'll use colormask to disable color writes.  Otherwise,
   2015        * respect color mask
   2016        */
   2017       metaSave |= MESA_META_COLOR_MASK;
   2018    }
   2019 
   2020    _mesa_meta_begin(ctx, metaSave);
   2021 
   2022    meta_glsl_clear_init(ctx, clear);
   2023 
   2024    if (fb->_IntegerColor) {
   2025       _mesa_UseProgramObjectARB(clear->IntegerShaderProg);
   2026       _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1,
   2027 			  ctx->Color.ClearColor.i);
   2028    } else {
   2029       _mesa_UseProgramObjectARB(clear->ShaderProg);
   2030       _mesa_Uniform4fvARB(clear->ColorLocation, 1,
   2031 			  ctx->Color.ClearColor.f);
   2032    }
   2033 
   2034    _mesa_BindVertexArray(clear->ArrayObj);
   2035    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
   2036 
   2037    /* GL_COLOR_BUFFER_BIT */
   2038    if (buffers & BUFFER_BITS_COLOR) {
   2039       /* leave colormask, glDrawBuffer state as-is */
   2040 
   2041       /* Clears never have the color clamped. */
   2042       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
   2043    }
   2044    else {
   2045       ASSERT(metaSave & MESA_META_COLOR_MASK);
   2046       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   2047    }
   2048 
   2049    /* GL_DEPTH_BUFFER_BIT */
   2050    if (buffers & BUFFER_BIT_DEPTH) {
   2051       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
   2052       _mesa_DepthFunc(GL_ALWAYS);
   2053       _mesa_DepthMask(GL_TRUE);
   2054    }
   2055    else {
   2056       assert(!ctx->Depth.Test);
   2057    }
   2058 
   2059    /* GL_STENCIL_BUFFER_BIT */
   2060    if (buffers & BUFFER_BIT_STENCIL) {
   2061       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
   2062       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
   2063                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
   2064       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
   2065                                 ctx->Stencil.Clear & stencilMax,
   2066                                 ctx->Stencil.WriteMask[0]);
   2067    }
   2068    else {
   2069       assert(!ctx->Stencil.Enabled);
   2070    }
   2071 
   2072    /* vertex positions */
   2073    verts[0].x = x0;
   2074    verts[0].y = y0;
   2075    verts[0].z = z;
   2076    verts[1].x = x1;
   2077    verts[1].y = y0;
   2078    verts[1].z = z;
   2079    verts[2].x = x1;
   2080    verts[2].y = y1;
   2081    verts[2].z = z;
   2082    verts[3].x = x0;
   2083    verts[3].y = y1;
   2084    verts[3].z = z;
   2085 
   2086    /* upload new vertex data */
   2087    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
   2088 		       GL_DYNAMIC_DRAW_ARB);
   2089 
   2090    /* draw quad */
   2091    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2092 
   2093    _mesa_meta_end(ctx);
   2094 }
   2095 
   2096 /**
   2097  * Meta implementation of ctx->Driver.CopyPixels() in terms
   2098  * of texture mapping and polygon rendering and GLSL shaders.
   2099  */
   2100 void
   2101 _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
   2102                       GLsizei width, GLsizei height,
   2103                       GLint dstX, GLint dstY, GLenum type)
   2104 {
   2105    struct copypix_state *copypix = &ctx->Meta->CopyPix;
   2106    struct temp_texture *tex = get_temp_texture(ctx);
   2107    struct vertex {
   2108       GLfloat x, y, z, s, t;
   2109    };
   2110    struct vertex verts[4];
   2111    GLboolean newTex;
   2112    GLenum intFormat = GL_RGBA;
   2113 
   2114    if (type != GL_COLOR ||
   2115        ctx->_ImageTransferState ||
   2116        ctx->Fog.Enabled ||
   2117        width > tex->MaxSize ||
   2118        height > tex->MaxSize) {
   2119       /* XXX avoid this fallback */
   2120       _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
   2121       return;
   2122    }
   2123 
   2124    /* Most GL state applies to glCopyPixels, but a there's a few things
   2125     * we need to override:
   2126     */
   2127    _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
   2128                           MESA_META_SHADER |
   2129                           MESA_META_TEXTURE |
   2130                           MESA_META_TRANSFORM |
   2131                           MESA_META_CLIP |
   2132                           MESA_META_VERTEX |
   2133                           MESA_META_VIEWPORT));
   2134 
   2135    if (copypix->ArrayObj == 0) {
   2136       /* one-time setup */
   2137 
   2138       /* create vertex array object */
   2139       _mesa_GenVertexArrays(1, &copypix->ArrayObj);
   2140       _mesa_BindVertexArray(copypix->ArrayObj);
   2141 
   2142       /* create vertex array buffer */
   2143       _mesa_GenBuffersARB(1, &copypix->VBO);
   2144       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
   2145       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   2146                           NULL, GL_DYNAMIC_DRAW_ARB);
   2147 
   2148       /* setup vertex arrays */
   2149       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   2150       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
   2151       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   2152       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   2153    }
   2154    else {
   2155       _mesa_BindVertexArray(copypix->ArrayObj);
   2156       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
   2157    }
   2158 
   2159    newTex = alloc_texture(tex, width, height, intFormat);
   2160 
   2161    /* vertex positions, texcoords (after texture allocation!) */
   2162    {
   2163       const GLfloat dstX0 = (GLfloat) dstX;
   2164       const GLfloat dstY0 = (GLfloat) dstY;
   2165       const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
   2166       const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
   2167       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
   2168 
   2169       verts[0].x = dstX0;
   2170       verts[0].y = dstY0;
   2171       verts[0].z = z;
   2172       verts[0].s = 0.0F;
   2173       verts[0].t = 0.0F;
   2174       verts[1].x = dstX1;
   2175       verts[1].y = dstY0;
   2176       verts[1].z = z;
   2177       verts[1].s = tex->Sright;
   2178       verts[1].t = 0.0F;
   2179       verts[2].x = dstX1;
   2180       verts[2].y = dstY1;
   2181       verts[2].z = z;
   2182       verts[2].s = tex->Sright;
   2183       verts[2].t = tex->Ttop;
   2184       verts[3].x = dstX0;
   2185       verts[3].y = dstY1;
   2186       verts[3].z = z;
   2187       verts[3].s = 0.0F;
   2188       verts[3].t = tex->Ttop;
   2189 
   2190       /* upload new vertex data */
   2191       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   2192    }
   2193 
   2194    /* Alloc/setup texture */
   2195    setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
   2196                          GL_RGBA, GL_NEAREST);
   2197 
   2198    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
   2199 
   2200    /* draw textured quad */
   2201    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2202 
   2203    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
   2204 
   2205    _mesa_meta_end(ctx);
   2206 }
   2207 
   2208 
   2209 
   2210 /**
   2211  * When the glDrawPixels() image size is greater than the max rectangle
   2212  * texture size we use this function to break the glDrawPixels() image
   2213  * into tiles which fit into the max texture size.
   2214  */
   2215 static void
   2216 tiled_draw_pixels(struct gl_context *ctx,
   2217                   GLint tileSize,
   2218                   GLint x, GLint y, GLsizei width, GLsizei height,
   2219                   GLenum format, GLenum type,
   2220                   const struct gl_pixelstore_attrib *unpack,
   2221                   const GLvoid *pixels)
   2222 {
   2223    struct gl_pixelstore_attrib tileUnpack = *unpack;
   2224    GLint i, j;
   2225 
   2226    if (tileUnpack.RowLength == 0)
   2227       tileUnpack.RowLength = width;
   2228 
   2229    for (i = 0; i < width; i += tileSize) {
   2230       const GLint tileWidth = MIN2(tileSize, width - i);
   2231       const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
   2232 
   2233       tileUnpack.SkipPixels = unpack->SkipPixels + i;
   2234 
   2235       for (j = 0; j < height; j += tileSize) {
   2236          const GLint tileHeight = MIN2(tileSize, height - j);
   2237          const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
   2238 
   2239          tileUnpack.SkipRows = unpack->SkipRows + j;
   2240 
   2241          _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
   2242                                format, type, &tileUnpack, pixels);
   2243       }
   2244    }
   2245 }
   2246 
   2247 
   2248 /**
   2249  * One-time init for drawing stencil pixels.
   2250  */
   2251 static void
   2252 init_draw_stencil_pixels(struct gl_context *ctx)
   2253 {
   2254    /* This program is run eight times, once for each stencil bit.
   2255     * The stencil values to draw are found in an 8-bit alpha texture.
   2256     * We read the texture/stencil value and test if bit 'b' is set.
   2257     * If the bit is not set, use KIL to kill the fragment.
   2258     * Finally, we use the stencil test to update the stencil buffer.
   2259     *
   2260     * The basic algorithm for checking if a bit is set is:
   2261     *   if (is_odd(value / (1 << bit)))
   2262     *      result is one (or non-zero).
   2263     *   else
   2264     *      result is zero.
   2265     * The program parameter contains three values:
   2266     *   parm.x = 255 / (1 << bit)
   2267     *   parm.y = 0.5
   2268     *   parm.z = 0.0
   2269     */
   2270    static const char *program =
   2271       "!!ARBfp1.0\n"
   2272       "PARAM parm = program.local[0]; \n"
   2273       "TEMP t; \n"
   2274       "TEX t, fragment.texcoord[0], texture[0], %s; \n"   /* NOTE %s here! */
   2275       "# t = t * 255 / bit \n"
   2276       "MUL t.x, t.a, parm.x; \n"
   2277       "# t = (int) t \n"
   2278       "FRC t.y, t.x; \n"
   2279       "SUB t.x, t.x, t.y; \n"
   2280       "# t = t * 0.5 \n"
   2281       "MUL t.x, t.x, parm.y; \n"
   2282       "# t = fract(t.x) \n"
   2283       "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
   2284       "# t.x = (t.x == 0 ? 1 : 0) \n"
   2285       "SGE t.x, -t.x, parm.z; \n"
   2286       "KIL -t.x; \n"
   2287       "# for debug only \n"
   2288       "#MOV result.color, t.x; \n"
   2289       "END \n";
   2290    char program2[1000];
   2291    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
   2292    struct temp_texture *tex = get_temp_texture(ctx);
   2293    const char *texTarget;
   2294 
   2295    assert(drawpix->StencilFP == 0);
   2296 
   2297    /* replace %s with "RECT" or "2D" */
   2298    assert(strlen(program) + 4 < sizeof(program2));
   2299    if (tex->Target == GL_TEXTURE_RECTANGLE)
   2300       texTarget = "RECT";
   2301    else
   2302       texTarget = "2D";
   2303    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
   2304 
   2305    _mesa_GenPrograms(1, &drawpix->StencilFP);
   2306    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
   2307    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
   2308                           strlen(program2), (const GLubyte *) program2);
   2309 }
   2310 
   2311 
   2312 /**
   2313  * One-time init for drawing depth pixels.
   2314  */
   2315 static void
   2316 init_draw_depth_pixels(struct gl_context *ctx)
   2317 {
   2318    static const char *program =
   2319       "!!ARBfp1.0\n"
   2320       "PARAM color = program.local[0]; \n"
   2321       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
   2322       "MOV result.color, color; \n"
   2323       "END \n";
   2324    char program2[200];
   2325    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
   2326    struct temp_texture *tex = get_temp_texture(ctx);
   2327    const char *texTarget;
   2328 
   2329    assert(drawpix->DepthFP == 0);
   2330 
   2331    /* replace %s with "RECT" or "2D" */
   2332    assert(strlen(program) + 4 < sizeof(program2));
   2333    if (tex->Target == GL_TEXTURE_RECTANGLE)
   2334       texTarget = "RECT";
   2335    else
   2336       texTarget = "2D";
   2337    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
   2338 
   2339    _mesa_GenPrograms(1, &drawpix->DepthFP);
   2340    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
   2341    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
   2342                           strlen(program2), (const GLubyte *) program2);
   2343 }
   2344 
   2345 
   2346 /**
   2347  * Meta implementation of ctx->Driver.DrawPixels() in terms
   2348  * of texture mapping and polygon rendering.
   2349  */
   2350 void
   2351 _mesa_meta_DrawPixels(struct gl_context *ctx,
   2352                       GLint x, GLint y, GLsizei width, GLsizei height,
   2353                       GLenum format, GLenum type,
   2354                       const struct gl_pixelstore_attrib *unpack,
   2355                       const GLvoid *pixels)
   2356 {
   2357    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
   2358    struct temp_texture *tex = get_temp_texture(ctx);
   2359    const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
   2360    const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
   2361    struct vertex {
   2362       GLfloat x, y, z, s, t;
   2363    };
   2364    struct vertex verts[4];
   2365    GLenum texIntFormat;
   2366    GLboolean fallback, newTex;
   2367    GLbitfield metaExtraSave = 0x0;
   2368    GLuint vbo;
   2369 
   2370    /*
   2371     * Determine if we can do the glDrawPixels with texture mapping.
   2372     */
   2373    fallback = GL_FALSE;
   2374    if (ctx->Fog.Enabled) {
   2375       fallback = GL_TRUE;
   2376    }
   2377 
   2378    if (_mesa_is_color_format(format)) {
   2379       /* use more compact format when possible */
   2380       /* XXX disable special case for GL_LUMINANCE for now to work around
   2381        * apparent i965 driver bug (see bug #23670).
   2382        */
   2383       if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
   2384          texIntFormat = format;
   2385       else
   2386          texIntFormat = GL_RGBA;
   2387 
   2388       /* If we're not supposed to clamp the resulting color, then just
   2389        * promote our texture to fully float.  We could do better by
   2390        * just going for the matching set of channels, in floating
   2391        * point.
   2392        */
   2393       if (ctx->Color.ClampFragmentColor != GL_TRUE &&
   2394 	  ctx->Extensions.ARB_texture_float)
   2395 	 texIntFormat = GL_RGBA32F;
   2396    }
   2397    else if (_mesa_is_stencil_format(format)) {
   2398       if (ctx->Extensions.ARB_fragment_program &&
   2399           ctx->Pixel.IndexShift == 0 &&
   2400           ctx->Pixel.IndexOffset == 0 &&
   2401           type == GL_UNSIGNED_BYTE) {
   2402          /* We'll store stencil as alpha.  This only works for GLubyte
   2403           * image data because of how incoming values are mapped to alpha
   2404           * in [0,1].
   2405           */
   2406          texIntFormat = GL_ALPHA;
   2407          metaExtraSave = (MESA_META_COLOR_MASK |
   2408                           MESA_META_DEPTH_TEST |
   2409                           MESA_META_PIXEL_TRANSFER |
   2410                           MESA_META_SHADER |
   2411                           MESA_META_STENCIL_TEST);
   2412       }
   2413       else {
   2414          fallback = GL_TRUE;
   2415       }
   2416    }
   2417    else if (_mesa_is_depth_format(format)) {
   2418       if (ctx->Extensions.ARB_depth_texture &&
   2419           ctx->Extensions.ARB_fragment_program) {
   2420          texIntFormat = GL_DEPTH_COMPONENT;
   2421          metaExtraSave = (MESA_META_SHADER);
   2422       }
   2423       else {
   2424          fallback = GL_TRUE;
   2425       }
   2426    }
   2427    else {
   2428       fallback = GL_TRUE;
   2429    }
   2430 
   2431    if (fallback) {
   2432       _swrast_DrawPixels(ctx, x, y, width, height,
   2433                          format, type, unpack, pixels);
   2434       return;
   2435    }
   2436 
   2437    /*
   2438     * Check image size against max texture size, draw as tiles if needed.
   2439     */
   2440    if (width > tex->MaxSize || height > tex->MaxSize) {
   2441       tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
   2442                         format, type, unpack, pixels);
   2443       return;
   2444    }
   2445 
   2446    /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
   2447     * but a there's a few things we need to override:
   2448     */
   2449    _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
   2450                           MESA_META_SHADER |
   2451                           MESA_META_TEXTURE |
   2452                           MESA_META_TRANSFORM |
   2453                           MESA_META_CLIP |
   2454                           MESA_META_VERTEX |
   2455                           MESA_META_VIEWPORT |
   2456                           metaExtraSave));
   2457 
   2458    newTex = alloc_texture(tex, width, height, texIntFormat);
   2459 
   2460    /* vertex positions, texcoords (after texture allocation!) */
   2461    {
   2462       const GLfloat x0 = (GLfloat) x;
   2463       const GLfloat y0 = (GLfloat) y;
   2464       const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
   2465       const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
   2466       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
   2467 
   2468       verts[0].x = x0;
   2469       verts[0].y = y0;
   2470       verts[0].z = z;
   2471       verts[0].s = 0.0F;
   2472       verts[0].t = 0.0F;
   2473       verts[1].x = x1;
   2474       verts[1].y = y0;
   2475       verts[1].z = z;
   2476       verts[1].s = tex->Sright;
   2477       verts[1].t = 0.0F;
   2478       verts[2].x = x1;
   2479       verts[2].y = y1;
   2480       verts[2].z = z;
   2481       verts[2].s = tex->Sright;
   2482       verts[2].t = tex->Ttop;
   2483       verts[3].x = x0;
   2484       verts[3].y = y1;
   2485       verts[3].z = z;
   2486       verts[3].s = 0.0F;
   2487       verts[3].t = tex->Ttop;
   2488    }
   2489 
   2490    if (drawpix->ArrayObj == 0) {
   2491       /* one-time setup: create vertex array object */
   2492       _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
   2493    }
   2494    _mesa_BindVertexArray(drawpix->ArrayObj);
   2495 
   2496    /* create vertex array buffer */
   2497    _mesa_GenBuffersARB(1, &vbo);
   2498    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
   2499    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   2500                        verts, GL_DYNAMIC_DRAW_ARB);
   2501 
   2502    /* setup vertex arrays */
   2503    _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   2504    _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
   2505    _mesa_EnableClientState(GL_VERTEX_ARRAY);
   2506    _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   2507 
   2508    /* set given unpack params */
   2509    ctx->Unpack = *unpack;
   2510 
   2511    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
   2512 
   2513    if (_mesa_is_stencil_format(format)) {
   2514       /* Drawing stencil */
   2515       GLint bit;
   2516 
   2517       if (!drawpix->StencilFP)
   2518          init_draw_stencil_pixels(ctx);
   2519 
   2520       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
   2521                             GL_ALPHA, type, pixels);
   2522 
   2523       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   2524 
   2525       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
   2526 
   2527       /* set all stencil bits to 0 */
   2528       _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
   2529       _mesa_StencilFunc(GL_ALWAYS, 0, 255);
   2530       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2531 
   2532       /* set stencil bits to 1 where needed */
   2533       _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
   2534 
   2535       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
   2536       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
   2537 
   2538       for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
   2539          const GLuint mask = 1 << bit;
   2540          if (mask & origStencilMask) {
   2541             _mesa_StencilFunc(GL_ALWAYS, mask, mask);
   2542             _mesa_StencilMask(mask);
   2543 
   2544             _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
   2545                                              255.0 / mask, 0.5, 0.0, 0.0);
   2546 
   2547             _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2548          }
   2549       }
   2550    }
   2551    else if (_mesa_is_depth_format(format)) {
   2552       /* Drawing depth */
   2553       if (!drawpix->DepthFP)
   2554          init_draw_depth_pixels(ctx);
   2555 
   2556       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
   2557       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
   2558 
   2559       /* polygon color = current raster color */
   2560       _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
   2561                                         ctx->Current.RasterColor);
   2562 
   2563       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
   2564                             format, type, pixels);
   2565 
   2566       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2567    }
   2568    else {
   2569       /* Drawing RGBA */
   2570       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
   2571                             format, type, pixels);
   2572       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2573    }
   2574 
   2575    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
   2576 
   2577    _mesa_DeleteBuffersARB(1, &vbo);
   2578 
   2579    /* restore unpack params */
   2580    ctx->Unpack = unpackSave;
   2581 
   2582    _mesa_meta_end(ctx);
   2583 }
   2584 
   2585 static GLboolean
   2586 alpha_test_raster_color(struct gl_context *ctx)
   2587 {
   2588    GLfloat alpha = ctx->Current.RasterColor[ACOMP];
   2589    GLfloat ref = ctx->Color.AlphaRef;
   2590 
   2591    switch (ctx->Color.AlphaFunc) {
   2592       case GL_NEVER:
   2593 	 return GL_FALSE;
   2594       case GL_LESS:
   2595 	 return alpha < ref;
   2596       case GL_EQUAL:
   2597 	 return alpha == ref;
   2598       case GL_LEQUAL:
   2599 	 return alpha <= ref;
   2600       case GL_GREATER:
   2601 	 return alpha > ref;
   2602       case GL_NOTEQUAL:
   2603 	 return alpha != ref;
   2604       case GL_GEQUAL:
   2605 	 return alpha >= ref;
   2606       case GL_ALWAYS:
   2607 	 return GL_TRUE;
   2608       default:
   2609 	 assert(0);
   2610 	 return GL_FALSE;
   2611    }
   2612 }
   2613 
   2614 /**
   2615  * Do glBitmap with a alpha texture quad.  Use the alpha test to cull
   2616  * the 'off' bits.  A bitmap cache as in the gallium/mesa state
   2617  * tracker would improve performance a lot.
   2618  */
   2619 void
   2620 _mesa_meta_Bitmap(struct gl_context *ctx,
   2621                   GLint x, GLint y, GLsizei width, GLsizei height,
   2622                   const struct gl_pixelstore_attrib *unpack,
   2623                   const GLubyte *bitmap1)
   2624 {
   2625    struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
   2626    struct temp_texture *tex = get_bitmap_temp_texture(ctx);
   2627    const GLenum texIntFormat = GL_ALPHA;
   2628    const struct gl_pixelstore_attrib unpackSave = *unpack;
   2629    GLubyte fg, bg;
   2630    struct vertex {
   2631       GLfloat x, y, z, s, t, r, g, b, a;
   2632    };
   2633    struct vertex verts[4];
   2634    GLboolean newTex;
   2635    GLubyte *bitmap8;
   2636 
   2637    /*
   2638     * Check if swrast fallback is needed.
   2639     */
   2640    if (ctx->_ImageTransferState ||
   2641        ctx->FragmentProgram._Enabled ||
   2642        ctx->Fog.Enabled ||
   2643        ctx->Texture._EnabledUnits ||
   2644        width > tex->MaxSize ||
   2645        height > tex->MaxSize) {
   2646       _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
   2647       return;
   2648    }
   2649 
   2650    if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
   2651       return;
   2652 
   2653    /* Most GL state applies to glBitmap (like blending, stencil, etc),
   2654     * but a there's a few things we need to override:
   2655     */
   2656    _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST |
   2657                           MESA_META_PIXEL_STORE |
   2658                           MESA_META_RASTERIZATION |
   2659                           MESA_META_SHADER |
   2660                           MESA_META_TEXTURE |
   2661                           MESA_META_TRANSFORM |
   2662                           MESA_META_CLIP |
   2663                           MESA_META_VERTEX |
   2664                           MESA_META_VIEWPORT));
   2665 
   2666    if (bitmap->ArrayObj == 0) {
   2667       /* one-time setup */
   2668 
   2669       /* create vertex array object */
   2670       _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
   2671       _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
   2672 
   2673       /* create vertex array buffer */
   2674       _mesa_GenBuffersARB(1, &bitmap->VBO);
   2675       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
   2676       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   2677                           NULL, GL_DYNAMIC_DRAW_ARB);
   2678 
   2679       /* setup vertex arrays */
   2680       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   2681       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
   2682       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
   2683       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   2684       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   2685       _mesa_EnableClientState(GL_COLOR_ARRAY);
   2686    }
   2687    else {
   2688       _mesa_BindVertexArray(bitmap->ArrayObj);
   2689       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
   2690    }
   2691 
   2692    newTex = alloc_texture(tex, width, height, texIntFormat);
   2693 
   2694    /* vertex positions, texcoords, colors (after texture allocation!) */
   2695    {
   2696       const GLfloat x0 = (GLfloat) x;
   2697       const GLfloat y0 = (GLfloat) y;
   2698       const GLfloat x1 = (GLfloat) (x + width);
   2699       const GLfloat y1 = (GLfloat) (y + height);
   2700       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
   2701       GLuint i;
   2702 
   2703       verts[0].x = x0;
   2704       verts[0].y = y0;
   2705       verts[0].z = z;
   2706       verts[0].s = 0.0F;
   2707       verts[0].t = 0.0F;
   2708       verts[1].x = x1;
   2709       verts[1].y = y0;
   2710       verts[1].z = z;
   2711       verts[1].s = tex->Sright;
   2712       verts[1].t = 0.0F;
   2713       verts[2].x = x1;
   2714       verts[2].y = y1;
   2715       verts[2].z = z;
   2716       verts[2].s = tex->Sright;
   2717       verts[2].t = tex->Ttop;
   2718       verts[3].x = x0;
   2719       verts[3].y = y1;
   2720       verts[3].z = z;
   2721       verts[3].s = 0.0F;
   2722       verts[3].t = tex->Ttop;
   2723 
   2724       for (i = 0; i < 4; i++) {
   2725          verts[i].r = ctx->Current.RasterColor[0];
   2726          verts[i].g = ctx->Current.RasterColor[1];
   2727          verts[i].b = ctx->Current.RasterColor[2];
   2728          verts[i].a = ctx->Current.RasterColor[3];
   2729       }
   2730 
   2731       /* upload new vertex data */
   2732       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   2733    }
   2734 
   2735    /* choose different foreground/background alpha values */
   2736    CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
   2737    bg = (fg > 127 ? 0 : 255);
   2738 
   2739    bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
   2740    if (!bitmap1) {
   2741       _mesa_meta_end(ctx);
   2742       return;
   2743    }
   2744 
   2745    bitmap8 = (GLubyte *) malloc(width * height);
   2746    if (bitmap8) {
   2747       memset(bitmap8, bg, width * height);
   2748       _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
   2749                           bitmap8, width, fg);
   2750 
   2751       _mesa_set_enable(ctx, tex->Target, GL_TRUE);
   2752 
   2753       _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
   2754       _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
   2755 
   2756       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
   2757                             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
   2758 
   2759       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   2760 
   2761       _mesa_set_enable(ctx, tex->Target, GL_FALSE);
   2762 
   2763       free(bitmap8);
   2764    }
   2765 
   2766    _mesa_unmap_pbo_source(ctx, &unpackSave);
   2767 
   2768    _mesa_meta_end(ctx);
   2769 }
   2770 
   2771 
   2772 /**
   2773  * Check if the call to _mesa_meta_GenerateMipmap() will require a
   2774  * software fallback.  The fallback path will require that the texture
   2775  * images are mapped.
   2776  * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
   2777  */
   2778 GLboolean
   2779 _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
   2780                                           struct gl_texture_object *texObj)
   2781 {
   2782    const GLuint fboSave = ctx->DrawBuffer->Name;
   2783    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
   2784    struct gl_texture_image *baseImage;
   2785    GLuint srcLevel;
   2786    GLenum status;
   2787 
   2788    /* check for fallbacks */
   2789    if (!ctx->Extensions.EXT_framebuffer_object ||
   2790        target == GL_TEXTURE_3D ||
   2791        target == GL_TEXTURE_1D_ARRAY ||
   2792        target == GL_TEXTURE_2D_ARRAY) {
   2793       return GL_TRUE;
   2794    }
   2795 
   2796    srcLevel = texObj->BaseLevel;
   2797    baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
   2798    if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) {
   2799       return GL_TRUE;
   2800    }
   2801 
   2802    if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB &&
   2803        !ctx->Extensions.EXT_texture_sRGB_decode) {
   2804       /* The texture format is sRGB but we can't turn off sRGB->linear
   2805        * texture sample conversion.  So we won't be able to generate the
   2806        * right colors when rendering.  Need to use a fallback.
   2807        */
   2808       return GL_TRUE;
   2809    }
   2810 
   2811    /*
   2812     * Test that we can actually render in the texture's format.
   2813     */
   2814    if (!mipmap->FBO)
   2815       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
   2816    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
   2817 
   2818    if (target == GL_TEXTURE_1D) {
   2819       _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
   2820                                     GL_COLOR_ATTACHMENT0_EXT,
   2821                                     target, texObj->Name, srcLevel);
   2822    }
   2823 #if 0
   2824    /* other work is needed to enable 3D mipmap generation */
   2825    else if (target == GL_TEXTURE_3D) {
   2826       GLint zoffset = 0;
   2827       _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
   2828                                     GL_COLOR_ATTACHMENT0_EXT,
   2829                                     target, texObj->Name, srcLevel, zoffset);
   2830    }
   2831 #endif
   2832    else {
   2833       /* 2D / cube */
   2834       _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
   2835                                     GL_COLOR_ATTACHMENT0_EXT,
   2836                                     target, texObj->Name, srcLevel);
   2837    }
   2838 
   2839    status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
   2840 
   2841    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
   2842 
   2843    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   2844       return GL_TRUE;
   2845    }
   2846 
   2847    return GL_FALSE;
   2848 }
   2849 
   2850 
   2851 /**
   2852  * Compute the texture coordinates for the four vertices of a quad for
   2853  * drawing a 2D texture image or slice of a cube/3D texture.
   2854  * \param faceTarget  GL_TEXTURE_1D/2D/3D or cube face name
   2855  * \param slice  slice of a 1D/2D array texture or 3D texture
   2856  * \param width  width of the texture image
   2857  * \param height  height of the texture image
   2858  * \param coords0/1/2/3  returns the computed texcoords
   2859  */
   2860 static void
   2861 setup_texture_coords(GLenum faceTarget,
   2862                      GLint slice,
   2863                      GLint width,
   2864                      GLint height,
   2865                      GLfloat coords0[3],
   2866                      GLfloat coords1[3],
   2867                      GLfloat coords2[3],
   2868                      GLfloat coords3[3])
   2869 {
   2870    static const GLfloat st[4][2] = {
   2871       {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
   2872    };
   2873    GLuint i;
   2874    GLfloat r;
   2875 
   2876    switch (faceTarget) {
   2877    case GL_TEXTURE_1D:
   2878    case GL_TEXTURE_2D:
   2879    case GL_TEXTURE_3D:
   2880    case GL_TEXTURE_2D_ARRAY:
   2881       if (faceTarget == GL_TEXTURE_3D)
   2882          r = 1.0F / slice;
   2883       else if (faceTarget == GL_TEXTURE_2D_ARRAY)
   2884          r = slice;
   2885       else
   2886          r = 0.0F;
   2887       coords0[0] = 0.0F; /* s */
   2888       coords0[1] = 0.0F; /* t */
   2889       coords0[2] = r; /* r */
   2890       coords1[0] = 1.0F;
   2891       coords1[1] = 0.0F;
   2892       coords1[2] = r;
   2893       coords2[0] = 1.0F;
   2894       coords2[1] = 1.0F;
   2895       coords2[2] = r;
   2896       coords3[0] = 0.0F;
   2897       coords3[1] = 1.0F;
   2898       coords3[2] = r;
   2899       break;
   2900    case GL_TEXTURE_RECTANGLE_ARB:
   2901       coords0[0] = 0.0F; /* s */
   2902       coords0[1] = 0.0F; /* t */
   2903       coords0[2] = 0.0F; /* r */
   2904       coords1[0] = width;
   2905       coords1[1] = 0.0F;
   2906       coords1[2] = 0.0F;
   2907       coords2[0] = width;
   2908       coords2[1] = height;
   2909       coords2[2] = 0.0F;
   2910       coords3[0] = 0.0F;
   2911       coords3[1] = height;
   2912       coords3[2] = 0.0F;
   2913       break;
   2914    case GL_TEXTURE_1D_ARRAY:
   2915       coords0[0] = 0.0F; /* s */
   2916       coords0[1] = slice; /* t */
   2917       coords0[2] = 0.0F; /* r */
   2918       coords1[0] = 1.0f;
   2919       coords1[1] = slice;
   2920       coords1[2] = 0.0F;
   2921       coords2[0] = 1.0F;
   2922       coords2[1] = slice;
   2923       coords2[2] = 0.0F;
   2924       coords3[0] = 0.0F;
   2925       coords3[1] = slice;
   2926       coords3[2] = 0.0F;
   2927       break;
   2928 
   2929    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   2930    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   2931    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   2932    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   2933    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   2934    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   2935       /* loop over quad verts */
   2936       for (i = 0; i < 4; i++) {
   2937          /* Compute sc = +/-scale and tc = +/-scale.
   2938           * Not +/-1 to avoid cube face selection ambiguity near the edges,
   2939           * though that can still sometimes happen with this scale factor...
   2940           */
   2941          const GLfloat scale = 0.9999f;
   2942          const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
   2943          const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
   2944          GLfloat *coord;
   2945 
   2946          switch (i) {
   2947          case 0:
   2948             coord = coords0;
   2949             break;
   2950          case 1:
   2951             coord = coords1;
   2952             break;
   2953          case 2:
   2954             coord = coords2;
   2955             break;
   2956          case 3:
   2957             coord = coords3;
   2958             break;
   2959          default:
   2960             assert(0);
   2961          }
   2962 
   2963          switch (faceTarget) {
   2964          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   2965             coord[0] = 1.0f;
   2966             coord[1] = -tc;
   2967             coord[2] = -sc;
   2968             break;
   2969          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   2970             coord[0] = -1.0f;
   2971             coord[1] = -tc;
   2972             coord[2] = sc;
   2973             break;
   2974          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   2975             coord[0] = sc;
   2976             coord[1] = 1.0f;
   2977             coord[2] = tc;
   2978             break;
   2979          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   2980             coord[0] = sc;
   2981             coord[1] = -1.0f;
   2982             coord[2] = -tc;
   2983             break;
   2984          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   2985             coord[0] = sc;
   2986             coord[1] = -tc;
   2987             coord[2] = 1.0f;
   2988             break;
   2989          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   2990             coord[0] = -sc;
   2991             coord[1] = -tc;
   2992             coord[2] = -1.0f;
   2993             break;
   2994          default:
   2995             assert(0);
   2996          }
   2997       }
   2998       break;
   2999    default:
   3000       assert(0 && "unexpected target in meta setup_texture_coords()");
   3001    }
   3002 }
   3003 
   3004 
   3005 static void
   3006 setup_ff_generate_mipmap(struct gl_context *ctx,
   3007                          struct gen_mipmap_state *mipmap)
   3008 {
   3009    struct vertex {
   3010       GLfloat x, y, tex[3];
   3011    };
   3012 
   3013    if (mipmap->ArrayObj == 0) {
   3014       /* one-time setup */
   3015       /* create vertex array object */
   3016       _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
   3017       _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
   3018 
   3019       /* create vertex array buffer */
   3020       _mesa_GenBuffersARB(1, &mipmap->VBO);
   3021       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
   3022       /* setup vertex arrays */
   3023       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   3024       _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex));
   3025       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   3026       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   3027    }
   3028 
   3029    /* setup projection matrix */
   3030    _mesa_MatrixMode(GL_PROJECTION);
   3031    _mesa_LoadIdentity();
   3032    _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
   3033 }
   3034 
   3035 
   3036 static struct glsl_sampler *
   3037 setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap)
   3038 {
   3039    switch(target) {
   3040    case GL_TEXTURE_1D:
   3041       mipmap->sampler_1d.type = "sampler1D";
   3042       mipmap->sampler_1d.func = "texture1D";
   3043       mipmap->sampler_1d.texcoords = "texCoords.x";
   3044       return &mipmap->sampler_1d;
   3045    case GL_TEXTURE_2D:
   3046       mipmap->sampler_2d.type = "sampler2D";
   3047       mipmap->sampler_2d.func = "texture2D";
   3048       mipmap->sampler_2d.texcoords = "texCoords.xy";
   3049       return &mipmap->sampler_2d;
   3050    case GL_TEXTURE_3D:
   3051       /* Code for mipmap generation with 3D textures is not used yet.
   3052        * It's a sw fallback.
   3053        */
   3054       mipmap->sampler_3d.type = "sampler3D";
   3055       mipmap->sampler_3d.func = "texture3D";
   3056       mipmap->sampler_3d.texcoords = "texCoords";
   3057       return &mipmap->sampler_3d;
   3058    case GL_TEXTURE_CUBE_MAP:
   3059       mipmap->sampler_cubemap.type = "samplerCube";
   3060       mipmap->sampler_cubemap.func = "textureCube";
   3061       mipmap->sampler_cubemap.texcoords = "texCoords";
   3062       return &mipmap->sampler_cubemap;
   3063    case GL_TEXTURE_1D_ARRAY:
   3064       mipmap->sampler_1d_array.type = "sampler1DArray";
   3065       mipmap->sampler_1d_array.func = "texture1DArray";
   3066       mipmap->sampler_1d_array.texcoords = "texCoords.xy";
   3067       return &mipmap->sampler_1d_array;
   3068    case GL_TEXTURE_2D_ARRAY:
   3069       mipmap->sampler_2d_array.type = "sampler2DArray";
   3070       mipmap->sampler_2d_array.func = "texture2DArray";
   3071       mipmap->sampler_2d_array.texcoords = "texCoords";
   3072       return &mipmap->sampler_2d_array;
   3073    default:
   3074       _mesa_problem(NULL, "Unexpected texture target 0x%x in"
   3075                     " setup_texture_sampler()\n", target);
   3076       return NULL;
   3077    }
   3078 }
   3079 
   3080 
   3081 static void
   3082 setup_glsl_generate_mipmap(struct gl_context *ctx,
   3083                            struct gen_mipmap_state *mipmap,
   3084                            GLenum target)
   3085 {
   3086    struct vertex {
   3087       GLfloat x, y, tex[3];
   3088    };
   3089    struct glsl_sampler *sampler;
   3090    const char *vs_source;
   3091    char *fs_source;
   3092    GLuint vs, fs;
   3093    void *mem_ctx;
   3094 
   3095    /* Check if already initialized */
   3096    if (mipmap->ArrayObj == 0) {
   3097 
   3098       /* create vertex array object */
   3099       _mesa_GenVertexArrays(1, &mipmap->ArrayObj);
   3100       _mesa_BindVertexArray(mipmap->ArrayObj);
   3101 
   3102       /* create vertex array buffer */
   3103       _mesa_GenBuffersARB(1, &mipmap->VBO);
   3104       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
   3105 
   3106       /* setup vertex arrays */
   3107       _mesa_VertexAttribPointerARB(0, 2, GL_FLOAT, GL_FALSE,
   3108                                    sizeof(struct vertex), OFFSET(x));
   3109       _mesa_VertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE,
   3110                                    sizeof(struct vertex), OFFSET(tex));
   3111    }
   3112 
   3113    /* Generate a fragment shader program appropriate for the texture target */
   3114    sampler = setup_texture_sampler(target, mipmap);
   3115    assert(sampler != NULL);
   3116    if (sampler->shader_prog != 0) {
   3117       mipmap->ShaderProg = sampler->shader_prog;
   3118       return;
   3119    }
   3120 
   3121    mem_ctx = ralloc_context(NULL);
   3122 
   3123    if (ctx->API == API_OPENGLES2 || ctx->Const.GLSLVersion < 130) {
   3124       const char *fs_template;
   3125       const char *extension_mode;
   3126 
   3127       vs_source =
   3128          "attribute vec2 position;\n"
   3129          "attribute vec3 textureCoords;\n"
   3130          "varying vec3 texCoords;\n"
   3131          "void main()\n"
   3132          "{\n"
   3133          "   texCoords = textureCoords;\n"
   3134          "   gl_Position = vec4(position, 0.0, 1.0);\n"
   3135          "}\n";
   3136       fs_template =
   3137          "#extension GL_EXT_texture_array : %s\n"
   3138          "uniform %s texSampler;\n"
   3139          "varying vec3 texCoords;\n"
   3140          "void main()\n"
   3141          "{\n"
   3142          "   gl_FragColor = %s(texSampler, %s);\n"
   3143          "}\n";
   3144 
   3145       extension_mode = ((target == GL_TEXTURE_1D_ARRAY) ||
   3146                         (target == GL_TEXTURE_2D_ARRAY)) ?
   3147                        "require" : "disable";
   3148 
   3149       fs_source = ralloc_asprintf(mem_ctx, fs_template,
   3150                                   extension_mode, sampler->type,
   3151                                   sampler->func, sampler->texcoords);
   3152    }
   3153    else {
   3154       const char *fs_template;
   3155 
   3156       vs_source =
   3157          "#version 130\n"
   3158          "in vec2 position;\n"
   3159          "in vec3 textureCoords;\n"
   3160          "out vec3 texCoords;\n"
   3161          "void main()\n"
   3162          "{\n"
   3163          "   texCoords = textureCoords;\n"
   3164          "   gl_Position = vec4(position, 0.0, 1.0);\n"
   3165          "}\n";
   3166       fs_template =
   3167          "#version 130\n"
   3168          "uniform %s texSampler;\n"
   3169          "in vec3 texCoords;\n"
   3170          "out %s out_color;\n"
   3171          "\n"
   3172          "void main()\n"
   3173          "{\n"
   3174          "   out_color = texture(texSampler, %s);\n"
   3175          "}\n";
   3176 
   3177       fs_source = ralloc_asprintf(mem_ctx, fs_template,
   3178                                   sampler->type, "vec4",
   3179                                   sampler->texcoords);
   3180    }
   3181 
   3182    vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source);
   3183    fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source);
   3184 
   3185    mipmap->ShaderProg = _mesa_CreateProgramObjectARB();
   3186    _mesa_AttachShader(mipmap->ShaderProg, fs);
   3187    _mesa_DeleteObjectARB(fs);
   3188    _mesa_AttachShader(mipmap->ShaderProg, vs);
   3189    _mesa_DeleteObjectARB(vs);
   3190    _mesa_BindAttribLocationARB(mipmap->ShaderProg, 0, "position");
   3191    _mesa_BindAttribLocationARB(mipmap->ShaderProg, 1, "texcoords");
   3192    _mesa_EnableVertexAttribArrayARB(0);
   3193    _mesa_EnableVertexAttribArrayARB(1);
   3194    link_program_with_debug(ctx, mipmap->ShaderProg);
   3195    sampler->shader_prog = mipmap->ShaderProg;
   3196    ralloc_free(mem_ctx);
   3197 }
   3198 
   3199 
   3200 static void
   3201 meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
   3202                                  struct gen_mipmap_state *mipmap)
   3203 {
   3204    if (mipmap->ArrayObj == 0)
   3205       return;
   3206    _mesa_DeleteVertexArraysAPPLE(1, &mipmap->ArrayObj);
   3207    mipmap->ArrayObj = 0;
   3208    _mesa_DeleteBuffersARB(1, &mipmap->VBO);
   3209    mipmap->VBO = 0;
   3210 
   3211    _mesa_DeleteObjectARB(mipmap->sampler_1d.shader_prog);
   3212    _mesa_DeleteObjectARB(mipmap->sampler_2d.shader_prog);
   3213    _mesa_DeleteObjectARB(mipmap->sampler_3d.shader_prog);
   3214    _mesa_DeleteObjectARB(mipmap->sampler_cubemap.shader_prog);
   3215    _mesa_DeleteObjectARB(mipmap->sampler_1d_array.shader_prog);
   3216    _mesa_DeleteObjectARB(mipmap->sampler_2d_array.shader_prog);
   3217 
   3218    mipmap->sampler_1d.shader_prog = 0;
   3219    mipmap->sampler_2d.shader_prog = 0;
   3220    mipmap->sampler_3d.shader_prog = 0;
   3221    mipmap->sampler_cubemap.shader_prog = 0;
   3222    mipmap->sampler_1d_array.shader_prog = 0;
   3223    mipmap->sampler_2d_array.shader_prog = 0;
   3224 }
   3225 
   3226 
   3227 /**
   3228  * Called via ctx->Driver.GenerateMipmap()
   3229  * Note: We don't yet support 3D textures, 1D/2D array textures or texture
   3230  * borders.
   3231  */
   3232 void
   3233 _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
   3234                           struct gl_texture_object *texObj)
   3235 {
   3236    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
   3237    struct vertex {
   3238       GLfloat x, y, tex[3];
   3239    };
   3240    struct vertex verts[4];
   3241    const GLuint baseLevel = texObj->BaseLevel;
   3242    const GLuint maxLevel = texObj->MaxLevel;
   3243    const GLint maxLevelSave = texObj->MaxLevel;
   3244    const GLboolean genMipmapSave = texObj->GenerateMipmap;
   3245    const GLenum srgbBufferSave = ctx->Color.sRGBEnabled;
   3246    const GLuint fboSave = ctx->DrawBuffer->Name;
   3247    const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit;
   3248    const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader &&
   3249                                       ctx->Extensions.ARB_fragment_shader &&
   3250 				      (ctx->API != API_OPENGLES);
   3251    GLenum faceTarget;
   3252    GLuint dstLevel;
   3253    const GLint slice = 0;
   3254    GLuint samplerSave;
   3255 
   3256    if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
   3257       _mesa_generate_mipmap(ctx, target, texObj);
   3258       return;
   3259    }
   3260 
   3261    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
   3262        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
   3263       faceTarget = target;
   3264       target = GL_TEXTURE_CUBE_MAP;
   3265    }
   3266    else {
   3267       faceTarget = target;
   3268    }
   3269 
   3270    _mesa_meta_begin(ctx, MESA_META_ALL);
   3271 
   3272    /* Choose between glsl version and fixed function version of
   3273     * GenerateMipmap function.
   3274     */
   3275    if (use_glsl_version) {
   3276       setup_glsl_generate_mipmap(ctx, mipmap, target);
   3277       _mesa_UseProgramObjectARB(mipmap->ShaderProg);
   3278    }
   3279    else {
   3280       setup_ff_generate_mipmap(ctx, mipmap);
   3281       _mesa_set_enable(ctx, target, GL_TRUE);
   3282    }
   3283 
   3284    _mesa_BindVertexArray(mipmap->ArrayObj);
   3285    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
   3286 
   3287    samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ?
   3288       ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
   3289 
   3290    if (currentTexUnitSave != 0)
   3291       _mesa_BindTexture(target, texObj->Name);
   3292 
   3293    if (!mipmap->FBO) {
   3294       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
   3295    }
   3296 
   3297    if (!mipmap->Sampler) {
   3298       _mesa_GenSamplers(1, &mipmap->Sampler);
   3299       _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler);
   3300 
   3301       _mesa_SamplerParameteri(mipmap->Sampler,
   3302                               GL_TEXTURE_MIN_FILTER,
   3303                               GL_LINEAR_MIPMAP_LINEAR);
   3304       _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   3305       _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   3306       _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   3307       _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
   3308 
   3309       /* We don't want to encode or decode sRGB values; treat them as linear.
   3310        * This is not technically correct for GLES3 but we don't get any API
   3311        * error at the moment.
   3312        */
   3313       if (ctx->Extensions.EXT_texture_sRGB_decode) {
   3314          _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT,
   3315                GL_SKIP_DECODE_EXT);
   3316       }
   3317 
   3318    } else {
   3319       _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler);
   3320    }
   3321 
   3322    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
   3323 
   3324    if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES)
   3325       _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
   3326    else
   3327       assert(!genMipmapSave);
   3328 
   3329    if ((ctx->Extensions.EXT_framebuffer_sRGB &&
   3330         _mesa_is_desktop_gl(ctx)) ||
   3331        _mesa_is_gles3(ctx)) {
   3332       _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);
   3333    }
   3334 
   3335   /* Setup texture coordinates */
   3336    setup_texture_coords(faceTarget,
   3337                         slice,
   3338                         0, 0, /* width, height never used here */
   3339                         verts[0].tex,
   3340                         verts[1].tex,
   3341                         verts[2].tex,
   3342                         verts[3].tex);
   3343 
   3344    /* setup vertex positions */
   3345    verts[0].x = -1.0F;
   3346    verts[0].y = -1.0F;
   3347    verts[1].x =  1.0F;
   3348    verts[1].y = -1.0F;
   3349    verts[2].x =  1.0F;
   3350    verts[2].y =  1.0F;
   3351    verts[3].x = -1.0F;
   3352    verts[3].y =  1.0F;
   3353 
   3354    /* upload vertex data */
   3355    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   3356                        verts, GL_DYNAMIC_DRAW_ARB);
   3357 
   3358    /* texture is already locked, unlock now */
   3359    _mesa_unlock_texture(ctx, texObj);
   3360 
   3361    for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
   3362       const struct gl_texture_image *srcImage;
   3363       const GLuint srcLevel = dstLevel - 1;
   3364       GLsizei srcWidth, srcHeight, srcDepth;
   3365       GLsizei dstWidth, dstHeight, dstDepth;
   3366       GLenum status;
   3367 
   3368       srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
   3369       assert(srcImage->Border == 0);
   3370 
   3371       /* src size */
   3372       srcWidth = srcImage->Width;
   3373       srcHeight = srcImage->Height;
   3374       srcDepth = srcImage->Depth;
   3375 
   3376       /* new dst size */
   3377       dstWidth = MAX2(1, srcWidth / 2);
   3378       dstHeight = MAX2(1, srcHeight / 2);
   3379       dstDepth = MAX2(1, srcDepth / 2);
   3380 
   3381       if (dstWidth == srcImage->Width &&
   3382           dstHeight == srcImage->Height &&
   3383           dstDepth == srcImage->Depth) {
   3384          /* all done */
   3385          break;
   3386       }
   3387 
   3388       /* Allocate storage for the destination mipmap image(s) */
   3389 
   3390       /* Set MaxLevel large enough to hold the new level when we allocate it */
   3391       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
   3392 
   3393       if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel,
   3394                                       dstWidth, dstHeight, dstDepth,
   3395                                       srcImage->Border,
   3396                                       srcImage->InternalFormat,
   3397                                       srcImage->TexFormat)) {
   3398          /* All done.  We either ran out of memory or we would go beyond the
   3399           * last valid level of an immutable texture if we continued.
   3400           */
   3401          break;
   3402       }
   3403 
   3404       /* limit minification to src level */
   3405       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
   3406 
   3407       /* Set to draw into the current dstLevel */
   3408       if (target == GL_TEXTURE_1D) {
   3409          _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
   3410                                        GL_COLOR_ATTACHMENT0_EXT,
   3411                                        target,
   3412                                        texObj->Name,
   3413                                        dstLevel);
   3414       }
   3415       else if (target == GL_TEXTURE_3D) {
   3416          GLint zoffset = 0; /* XXX unfinished */
   3417          _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
   3418                                        GL_COLOR_ATTACHMENT0_EXT,
   3419                                        target,
   3420                                        texObj->Name,
   3421                                        dstLevel, zoffset);
   3422       }
   3423       else {
   3424          /* 2D / cube */
   3425          _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
   3426                                        GL_COLOR_ATTACHMENT0_EXT,
   3427                                        faceTarget,
   3428                                        texObj->Name,
   3429                                        dstLevel);
   3430       }
   3431 
   3432       _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
   3433 
   3434       /* sanity check */
   3435       status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
   3436       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   3437          _mesa_problem(ctx, "Unexpected incomplete framebuffer in "
   3438                        "_mesa_meta_GenerateMipmap()");
   3439          break;
   3440       }
   3441 
   3442       assert(dstWidth == ctx->DrawBuffer->Width);
   3443       assert(dstHeight == ctx->DrawBuffer->Height);
   3444 
   3445       /* setup viewport */
   3446       _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
   3447 
   3448       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   3449    }
   3450 
   3451    if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) {
   3452       _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);
   3453    }
   3454 
   3455    _mesa_lock_texture(ctx, texObj); /* relock */
   3456 
   3457    _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave);
   3458 
   3459    _mesa_meta_end(ctx);
   3460 
   3461    _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
   3462    if (genMipmapSave)
   3463       _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
   3464 
   3465    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
   3466 }
   3467 
   3468 
   3469 /**
   3470  * Determine the GL data type to use for the temporary image read with
   3471  * ReadPixels() and passed to Tex[Sub]Image().
   3472  */
   3473 static GLenum
   3474 get_temp_image_type(struct gl_context *ctx, gl_format format)
   3475 {
   3476    GLenum baseFormat;
   3477 
   3478    baseFormat = _mesa_get_format_base_format(format);
   3479 
   3480    switch (baseFormat) {
   3481    case GL_RGBA:
   3482    case GL_RGB:
   3483    case GL_RG:
   3484    case GL_RED:
   3485    case GL_ALPHA:
   3486    case GL_LUMINANCE:
   3487    case GL_LUMINANCE_ALPHA:
   3488    case GL_INTENSITY:
   3489       if (ctx->DrawBuffer->Visual.redBits <= 8) {
   3490          return GL_UNSIGNED_BYTE;
   3491       } else if (ctx->DrawBuffer->Visual.redBits <= 16) {
   3492          return GL_UNSIGNED_SHORT;
   3493       } else {
   3494          GLenum datatype = _mesa_get_format_datatype(format);
   3495          if (datatype == GL_INT || datatype == GL_UNSIGNED_INT)
   3496             return datatype;
   3497          return GL_FLOAT;
   3498       }
   3499    case GL_DEPTH_COMPONENT:
   3500       return GL_UNSIGNED_INT;
   3501    case GL_DEPTH_STENCIL:
   3502       return GL_UNSIGNED_INT_24_8;
   3503    default:
   3504       _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()",
   3505 		    baseFormat);
   3506       return 0;
   3507    }
   3508 }
   3509 
   3510 
   3511 /**
   3512  * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
   3513  * Have to be careful with locking and meta state for pixel transfer.
   3514  */
   3515 void
   3516 _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
   3517                            struct gl_texture_image *texImage,
   3518                            GLint xoffset, GLint yoffset, GLint zoffset,
   3519                            struct gl_renderbuffer *rb,
   3520                            GLint x, GLint y,
   3521                            GLsizei width, GLsizei height)
   3522 {
   3523    struct gl_texture_object *texObj = texImage->TexObject;
   3524    GLenum format, type;
   3525    GLint bpp;
   3526    void *buf;
   3527 
   3528    /* Choose format/type for temporary image buffer */
   3529    format = _mesa_get_format_base_format(texImage->TexFormat);
   3530    if (format == GL_LUMINANCE ||
   3531        format == GL_LUMINANCE_ALPHA ||
   3532        format == GL_INTENSITY) {
   3533       /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the
   3534        * temp image buffer because glReadPixels will do L=R+G+B which is
   3535        * not what we want (should be L=R).
   3536        */
   3537       format = GL_RGBA;
   3538    }
   3539 
   3540    type = get_temp_image_type(ctx, texImage->TexFormat);
   3541    if (_mesa_is_format_integer_color(texImage->TexFormat)) {
   3542       format = _mesa_base_format_to_integer_format(format);
   3543    }
   3544    bpp = _mesa_bytes_per_pixel(format, type);
   3545    if (bpp <= 0) {
   3546       _mesa_problem(ctx, "Bad bpp in _mesa_meta_CopyTexSubImage()");
   3547       return;
   3548    }
   3549 
   3550    /*
   3551     * Alloc image buffer (XXX could use a PBO)
   3552     */
   3553    buf = malloc(width * height * bpp);
   3554    if (!buf) {
   3555       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
   3556       return;
   3557    }
   3558 
   3559    _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
   3560 
   3561    /*
   3562     * Read image from framebuffer (disable pixel transfer ops)
   3563     */
   3564    _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER);
   3565    ctx->Driver.ReadPixels(ctx, x, y, width, height,
   3566 			  format, type, &ctx->Pack, buf);
   3567    _mesa_meta_end(ctx);
   3568 
   3569    _mesa_update_state(ctx); /* to update pixel transfer state */
   3570 
   3571    /*
   3572     * Store texture data (with pixel transfer ops)
   3573     */
   3574    _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE);
   3575 
   3576    ctx->Driver.TexSubImage(ctx, dims, texImage,
   3577                            xoffset, yoffset, zoffset, width, height, 1,
   3578                            format, type, buf, &ctx->Unpack);
   3579 
   3580    _mesa_meta_end(ctx);
   3581 
   3582    _mesa_lock_texture(ctx, texObj); /* re-lock */
   3583 
   3584    free(buf);
   3585 }
   3586 
   3587 
   3588 /**
   3589  * Decompress a texture image by drawing a quad with the compressed
   3590  * texture and reading the pixels out of the color buffer.
   3591  * \param slice  which slice of a 3D texture or layer of a 1D/2D texture
   3592  * \param destFormat  format, ala glReadPixels
   3593  * \param destType  type, ala glReadPixels
   3594  * \param dest  destination buffer
   3595  * \param destRowLength  dest image rowLength (ala GL_PACK_ROW_LENGTH)
   3596  */
   3597 static void
   3598 decompress_texture_image(struct gl_context *ctx,
   3599                          struct gl_texture_image *texImage,
   3600                          GLuint slice,
   3601                          GLenum destFormat, GLenum destType,
   3602                          GLvoid *dest)
   3603 {
   3604    struct decompress_state *decompress = &ctx->Meta->Decompress;
   3605    struct gl_texture_object *texObj = texImage->TexObject;
   3606    const GLint width = texImage->Width;
   3607    const GLint height = texImage->Height;
   3608    const GLenum target = texObj->Target;
   3609    GLenum faceTarget;
   3610    struct vertex {
   3611       GLfloat x, y, tex[3];
   3612    };
   3613    struct vertex verts[4];
   3614    GLuint fboDrawSave, fboReadSave;
   3615    GLuint rbSave;
   3616    GLuint samplerSave;
   3617 
   3618    if (slice > 0) {
   3619       assert(target == GL_TEXTURE_3D ||
   3620              target == GL_TEXTURE_2D_ARRAY);
   3621    }
   3622 
   3623    if (target == GL_TEXTURE_CUBE_MAP) {
   3624       faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
   3625    }
   3626    else {
   3627       faceTarget = target;
   3628    }
   3629 
   3630    /* save fbo bindings (not saved by _mesa_meta_begin()) */
   3631    fboDrawSave = ctx->DrawBuffer->Name;
   3632    fboReadSave = ctx->ReadBuffer->Name;
   3633    rbSave = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
   3634 
   3635    _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_PIXEL_STORE);
   3636 
   3637    samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ?
   3638          ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
   3639 
   3640    /* Create/bind FBO/renderbuffer */
   3641    if (decompress->FBO == 0) {
   3642       _mesa_GenFramebuffersEXT(1, &decompress->FBO);
   3643       _mesa_GenRenderbuffersEXT(1, &decompress->RBO);
   3644       _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO);
   3645       _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO);
   3646       _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
   3647                                        GL_COLOR_ATTACHMENT0_EXT,
   3648                                        GL_RENDERBUFFER_EXT,
   3649                                        decompress->RBO);
   3650    }
   3651    else {
   3652       _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO);
   3653    }
   3654 
   3655    /* alloc dest surface */
   3656    if (width > decompress->Width || height > decompress->Height) {
   3657       _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO);
   3658       _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA,
   3659                                    width, height);
   3660       decompress->Width = width;
   3661       decompress->Height = height;
   3662    }
   3663 
   3664    /* setup VBO data */
   3665    if (decompress->ArrayObj == 0) {
   3666       /* create vertex array object */
   3667       _mesa_GenVertexArrays(1, &decompress->ArrayObj);
   3668       _mesa_BindVertexArray(decompress->ArrayObj);
   3669 
   3670       /* create vertex array buffer */
   3671       _mesa_GenBuffersARB(1, &decompress->VBO);
   3672       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO);
   3673       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   3674                           NULL, GL_DYNAMIC_DRAW_ARB);
   3675 
   3676       /* setup vertex arrays */
   3677       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   3678       _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex));
   3679       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   3680       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   3681    }
   3682    else {
   3683       _mesa_BindVertexArray(decompress->ArrayObj);
   3684       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO);
   3685    }
   3686 
   3687    if (!decompress->Sampler) {
   3688       _mesa_GenSamplers(1, &decompress->Sampler);
   3689       _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler);
   3690       /* nearest filtering */
   3691       _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3692       _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3693       /* No sRGB decode or encode.*/
   3694       if (ctx->Extensions.EXT_texture_sRGB_decode) {
   3695          _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_SRGB_DECODE_EXT,
   3696                              GL_SKIP_DECODE_EXT);
   3697       }
   3698 
   3699    } else {
   3700       _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler);
   3701    }
   3702 
   3703    setup_texture_coords(faceTarget, slice, width, height,
   3704                         verts[0].tex,
   3705                         verts[1].tex,
   3706                         verts[2].tex,
   3707                         verts[3].tex);
   3708 
   3709    /* setup vertex positions */
   3710    verts[0].x = 0.0F;
   3711    verts[0].y = 0.0F;
   3712    verts[1].x = width;
   3713    verts[1].y = 0.0F;
   3714    verts[2].x = width;
   3715    verts[2].y = height;
   3716    verts[3].x = 0.0F;
   3717    verts[3].y = height;
   3718 
   3719    /* upload new vertex data */
   3720    _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   3721 
   3722    /* setup texture state */
   3723    _mesa_BindTexture(target, texObj->Name);
   3724    _mesa_set_enable(ctx, target, GL_TRUE);
   3725 
   3726    {
   3727       /* save texture object state */
   3728       const GLint baseLevelSave = texObj->BaseLevel;
   3729       const GLint maxLevelSave = texObj->MaxLevel;
   3730 
   3731       /* restrict sampling to the texture level of interest */
   3732       if (target != GL_TEXTURE_RECTANGLE_ARB) {
   3733          _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level);
   3734          _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level);
   3735       }
   3736 
   3737       /* No sRGB decode or encode.*/
   3738       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_framebuffer_sRGB)
   3739           || _mesa_is_gles3(ctx)) {
   3740          _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);
   3741       }
   3742 
   3743       /* render quad w/ texture into renderbuffer */
   3744       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   3745 
   3746       /* Restore texture object state, the texture binding will
   3747        * be restored by _mesa_meta_end().
   3748        */
   3749       if (target != GL_TEXTURE_RECTANGLE_ARB) {
   3750          _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
   3751          _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
   3752       }
   3753 
   3754    }
   3755 
   3756    /* read pixels from renderbuffer */
   3757    {
   3758       GLenum baseTexFormat = texImage->_BaseFormat;
   3759       GLenum destBaseFormat = _mesa_base_tex_format(ctx, destFormat);
   3760 
   3761       /* The pixel transfer state will be set to default values at this point
   3762        * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively
   3763        * turned off (as required by glGetTexImage) but we need to handle some
   3764        * special cases.  In particular, single-channel texture values are
   3765        * returned as red and two-channel texture values are returned as
   3766        * red/alpha.
   3767        */
   3768       if ((baseTexFormat == GL_LUMINANCE ||
   3769            baseTexFormat == GL_LUMINANCE_ALPHA ||
   3770            baseTexFormat == GL_INTENSITY) ||
   3771           /* If we're reading back an RGB(A) texture (using glGetTexImage) as
   3772 	   * luminance then we need to return L=tex(R).
   3773 	   */
   3774           ((baseTexFormat == GL_RGBA ||
   3775             baseTexFormat == GL_RGB  ||
   3776             baseTexFormat == GL_RG) &&
   3777           (destBaseFormat == GL_LUMINANCE ||
   3778            destBaseFormat == GL_LUMINANCE_ALPHA ||
   3779            destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
   3780            destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT))) {
   3781          /* Green and blue must be zero */
   3782          _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f);
   3783          _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f);
   3784       }
   3785 
   3786       _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest);
   3787    }
   3788 
   3789    /* disable texture unit */
   3790    _mesa_set_enable(ctx, target, GL_FALSE);
   3791 
   3792    _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave);
   3793 
   3794    _mesa_meta_end(ctx);
   3795 
   3796    /* restore fbo bindings */
   3797    if (fboDrawSave == fboReadSave) {
   3798       _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboDrawSave);
   3799    }
   3800    else {
   3801       _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboDrawSave);
   3802       _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fboReadSave);
   3803    }
   3804    _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbSave);
   3805 }
   3806 
   3807 
   3808 /**
   3809  * This is just a wrapper around _mesa_get_tex_image() and
   3810  * decompress_texture_image().  Meta functions should not be directly called
   3811  * from core Mesa.
   3812  */
   3813 void
   3814 _mesa_meta_GetTexImage(struct gl_context *ctx,
   3815                        GLenum format, GLenum type, GLvoid *pixels,
   3816                        struct gl_texture_image *texImage)
   3817 {
   3818    /* We can only use the decompress-with-blit method here if the texels are
   3819     * unsigned, normalized values.  We could handle signed and unnormalized
   3820     * with floating point renderbuffers...
   3821     */
   3822    if (_mesa_is_format_compressed(texImage->TexFormat) &&
   3823        _mesa_get_format_datatype(texImage->TexFormat)
   3824        == GL_UNSIGNED_NORMALIZED) {
   3825       struct gl_texture_object *texObj = texImage->TexObject;
   3826       const GLuint slice = 0; /* only 2D compressed textures for now */
   3827       /* Need to unlock the texture here to prevent deadlock... */
   3828       _mesa_unlock_texture(ctx, texObj);
   3829       decompress_texture_image(ctx, texImage, slice, format, type, pixels);
   3830       /* ... and relock it */
   3831       _mesa_lock_texture(ctx, texObj);
   3832    }
   3833    else {
   3834       _mesa_get_teximage(ctx, format, type, pixels, texImage);
   3835    }
   3836 }
   3837 
   3838 
   3839 /**
   3840  * Meta implementation of ctx->Driver.DrawTex() in terms
   3841  * of polygon rendering.
   3842  */
   3843 void
   3844 _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
   3845                    GLfloat width, GLfloat height)
   3846 {
   3847 #if FEATURE_OES_draw_texture
   3848    struct drawtex_state *drawtex = &ctx->Meta->DrawTex;
   3849    struct vertex {
   3850       GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2];
   3851    };
   3852    struct vertex verts[4];
   3853    GLuint i;
   3854 
   3855    _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION |
   3856                           MESA_META_SHADER |
   3857                           MESA_META_TRANSFORM |
   3858                           MESA_META_VERTEX |
   3859                           MESA_META_VIEWPORT));
   3860 
   3861    if (drawtex->ArrayObj == 0) {
   3862       /* one-time setup */
   3863       GLint active_texture;
   3864 
   3865       /* create vertex array object */
   3866       _mesa_GenVertexArrays(1, &drawtex->ArrayObj);
   3867       _mesa_BindVertexArray(drawtex->ArrayObj);
   3868 
   3869       /* create vertex array buffer */
   3870       _mesa_GenBuffersARB(1, &drawtex->VBO);
   3871       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
   3872       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
   3873                           NULL, GL_DYNAMIC_DRAW_ARB);
   3874 
   3875       /* client active texture is not part of the array object */
   3876       active_texture = ctx->Array.ActiveTexture;
   3877 
   3878       /* setup vertex arrays */
   3879       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
   3880       _mesa_EnableClientState(GL_VERTEX_ARRAY);
   3881       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
   3882          _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i);
   3883          _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
   3884          _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
   3885       }
   3886 
   3887       /* restore client active texture */
   3888       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture);
   3889    }
   3890    else {
   3891       _mesa_BindVertexArray(drawtex->ArrayObj);
   3892       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
   3893    }
   3894 
   3895    /* vertex positions, texcoords */
   3896    {
   3897       const GLfloat x1 = x + width;
   3898       const GLfloat y1 = y + height;
   3899 
   3900       z = CLAMP(z, 0.0, 1.0);
   3901       z = invert_z(z);
   3902 
   3903       verts[0].x = x;
   3904       verts[0].y = y;
   3905       verts[0].z = z;
   3906 
   3907       verts[1].x = x1;
   3908       verts[1].y = y;
   3909       verts[1].z = z;
   3910 
   3911       verts[2].x = x1;
   3912       verts[2].y = y1;
   3913       verts[2].z = z;
   3914 
   3915       verts[3].x = x;
   3916       verts[3].y = y1;
   3917       verts[3].z = z;
   3918 
   3919       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
   3920          const struct gl_texture_object *texObj;
   3921          const struct gl_texture_image *texImage;
   3922          GLfloat s, t, s1, t1;
   3923          GLuint tw, th;
   3924 
   3925          if (!ctx->Texture.Unit[i]._ReallyEnabled) {
   3926             GLuint j;
   3927             for (j = 0; j < 4; j++) {
   3928                verts[j].st[i][0] = 0.0f;
   3929                verts[j].st[i][1] = 0.0f;
   3930             }
   3931             continue;
   3932          }
   3933 
   3934          texObj = ctx->Texture.Unit[i]._Current;
   3935          texImage = texObj->Image[0][texObj->BaseLevel];
   3936          tw = texImage->Width2;
   3937          th = texImage->Height2;
   3938 
   3939          s = (GLfloat) texObj->CropRect[0] / tw;
   3940          t = (GLfloat) texObj->CropRect[1] / th;
   3941          s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw;
   3942          t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th;
   3943 
   3944          verts[0].st[i][0] = s;
   3945          verts[0].st[i][1] = t;
   3946 
   3947          verts[1].st[i][0] = s1;
   3948          verts[1].st[i][1] = t;
   3949 
   3950          verts[2].st[i][0] = s1;
   3951          verts[2].st[i][1] = t1;
   3952 
   3953          verts[3].st[i][0] = s;
   3954          verts[3].st[i][1] = t1;
   3955       }
   3956 
   3957       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
   3958    }
   3959 
   3960    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
   3961 
   3962    _mesa_meta_end(ctx);
   3963 #endif /* FEATURE_OES_draw_texture */
   3964 }
   3965