f9b4755988bf9c73141ea7f95de81b656b3fe2cc
[profile/ivi/mesa.git] / src / mesa / drivers / common / meta.c
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/formats.h"
48 #include "main/image.h"
49 #include "main/macros.h"
50 #include "main/matrix.h"
51 #include "main/mipmap.h"
52 #include "main/pbo.h"
53 #include "main/polygon.h"
54 #include "main/readpix.h"
55 #include "main/scissor.h"
56 #include "main/shaderapi.h"
57 #include "main/shaderobj.h"
58 #include "main/state.h"
59 #include "main/stencil.h"
60 #include "main/texobj.h"
61 #include "main/texenv.h"
62 #include "main/teximage.h"
63 #include "main/texparam.h"
64 #include "main/texstate.h"
65 #include "main/uniforms.h"
66 #include "main/varray.h"
67 #include "main/viewport.h"
68 #include "program/program.h"
69 #include "swrast/swrast.h"
70 #include "drivers/common/meta.h"
71
72
73 /** Return offset in bytes of the field within a vertex struct */
74 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
75
76
77 /**
78  * Flags passed to _mesa_meta_begin().
79  */
80 /*@{*/
81 #define META_ALL              ~0x0
82 #define META_ALPHA_TEST        0x1
83 #define META_BLEND             0x2  /**< includes logicop */
84 #define META_COLOR_MASK        0x4
85 #define META_DEPTH_TEST        0x8
86 #define META_FOG              0x10
87 #define META_PIXEL_STORE      0x20
88 #define META_PIXEL_TRANSFER   0x40
89 #define META_RASTERIZATION    0x80
90 #define META_SCISSOR         0x100
91 #define META_SHADER          0x200
92 #define META_STENCIL_TEST    0x400
93 #define META_TRANSFORM       0x800 /**< modelview/projection matrix state */
94 #define META_TEXTURE        0x1000
95 #define META_VERTEX         0x2000
96 #define META_VIEWPORT       0x4000
97 #define META_CLAMP_FRAGMENT_COLOR 0x8000
98 #define META_CLAMP_VERTEX_COLOR 0x10000
99 #define META_CONDITIONAL_RENDER 0x20000
100 #define META_CLIP          0x40000
101 /*@}*/
102
103
104 /**
105  * State which we may save/restore across meta ops.
106  * XXX this may be incomplete...
107  */
108 struct save_state
109 {
110    GLbitfield SavedState;  /**< bitmask of META_* flags */
111
112    /** META_ALPHA_TEST */
113    GLboolean AlphaEnabled;
114    GLenum AlphaFunc;
115    GLclampf AlphaRef;
116
117    /** META_BLEND */
118    GLbitfield BlendEnabled;
119    GLboolean ColorLogicOpEnabled;
120
121    /** META_COLOR_MASK */
122    GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
123
124    /** META_DEPTH_TEST */
125    struct gl_depthbuffer_attrib Depth;
126
127    /** META_FOG */
128    GLboolean Fog;
129
130    /** META_PIXEL_STORE */
131    struct gl_pixelstore_attrib Pack, Unpack;
132
133    /** META_PIXEL_TRANSFER */
134    GLfloat RedBias, RedScale;
135    GLfloat GreenBias, GreenScale;
136    GLfloat BlueBias, BlueScale;
137    GLfloat AlphaBias, AlphaScale;
138    GLfloat DepthBias, DepthScale;
139    GLboolean MapColorFlag;
140
141    /** META_RASTERIZATION */
142    GLenum FrontPolygonMode, BackPolygonMode;
143    GLboolean PolygonOffset;
144    GLboolean PolygonSmooth;
145    GLboolean PolygonStipple;
146    GLboolean PolygonCull;
147
148    /** META_SCISSOR */
149    struct gl_scissor_attrib Scissor;
150
151    /** META_SHADER */
152    GLboolean VertexProgramEnabled;
153    struct gl_vertex_program *VertexProgram;
154    GLboolean FragmentProgramEnabled;
155    struct gl_fragment_program *FragmentProgram;
156    struct gl_shader_program *VertexShader;
157    struct gl_shader_program *GeometryShader;
158    struct gl_shader_program *FragmentShader;
159    struct gl_shader_program *ActiveShader;
160
161    /** META_STENCIL_TEST */
162    struct gl_stencil_attrib Stencil;
163
164    /** META_TRANSFORM */
165    GLenum MatrixMode;
166    GLfloat ModelviewMatrix[16];
167    GLfloat ProjectionMatrix[16];
168    GLfloat TextureMatrix[16];
169
170    /** META_CLIP */
171    GLbitfield ClipPlanesEnabled;
172
173    /** META_TEXTURE */
174    GLuint ActiveUnit;
175    GLuint ClientActiveUnit;
176    /** for unit[0] only */
177    struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
178    /** mask of TEXTURE_2D_BIT, etc */
179    GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
180    GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
181    GLuint EnvMode;  /* unit[0] only */
182
183    /** META_VERTEX */
184    struct gl_array_object *ArrayObj;
185    struct gl_buffer_object *ArrayBufferObj;
186
187    /** META_VIEWPORT */
188    GLint ViewportX, ViewportY, ViewportW, ViewportH;
189    GLclampd DepthNear, DepthFar;
190
191    /** META_CLAMP_FRAGMENT_COLOR */
192    GLenum ClampFragmentColor;
193
194    /** META_CLAMP_VERTEX_COLOR */
195    GLenum ClampVertexColor;
196
197    /** META_CONDITIONAL_RENDER */
198    struct gl_query_object *CondRenderQuery;
199    GLenum CondRenderMode;
200
201    /** Miscellaneous (always disabled) */
202    GLboolean Lighting;
203 };
204
205
206 /**
207  * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
208  * This is currently shared by all the meta ops.  But we could create a
209  * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
210  */
211 struct temp_texture
212 {
213    GLuint TexObj;
214    GLenum Target;         /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
215    GLsizei MinSize;       /**< Min texture size to allocate */
216    GLsizei MaxSize;       /**< Max possible texture size */
217    GLboolean NPOT;        /**< Non-power of two size OK? */
218    GLsizei Width, Height; /**< Current texture size */
219    GLenum IntFormat;
220    GLfloat Sright, Ttop;  /**< right, top texcoords */
221 };
222
223
224 /**
225  * State for glBlitFramebufer()
226  */
227 struct blit_state
228 {
229    GLuint ArrayObj;
230    GLuint VBO;
231    GLuint DepthFP;
232 };
233
234
235 /**
236  * State for glClear()
237  */
238 struct clear_state
239 {
240    GLuint ArrayObj;
241    GLuint VBO;
242    GLuint ShaderProg;
243    GLint ColorLocation;
244 };
245
246
247 /**
248  * State for glCopyPixels()
249  */
250 struct copypix_state
251 {
252    GLuint ArrayObj;
253    GLuint VBO;
254 };
255
256
257 /**
258  * State for glDrawPixels()
259  */
260 struct drawpix_state
261 {
262    GLuint ArrayObj;
263
264    GLuint StencilFP;  /**< Fragment program for drawing stencil images */
265    GLuint DepthFP;  /**< Fragment program for drawing depth images */
266 };
267
268
269 /**
270  * State for glBitmap()
271  */
272 struct bitmap_state
273 {
274    GLuint ArrayObj;
275    GLuint VBO;
276    struct temp_texture Tex;  /**< separate texture from other meta ops */
277 };
278
279
280 /**
281  * State for _mesa_meta_generate_mipmap()
282  */
283 struct gen_mipmap_state
284 {
285    GLuint ArrayObj;
286    GLuint VBO;
287    GLuint FBO;
288 };
289
290 #define MAX_META_OPS_DEPTH      2
291 /**
292  * All per-context meta state.
293  */
294 struct gl_meta_state
295 {
296    /** Stack of state saved during meta-ops */
297    struct save_state Save[MAX_META_OPS_DEPTH];
298    /** Save stack depth */
299    GLuint SaveStackDepth;
300
301    struct temp_texture TempTex;
302
303    struct blit_state Blit;    /**< For _mesa_meta_BlitFramebuffer() */
304    struct clear_state Clear;  /**< For _mesa_meta_Clear() */
305    struct copypix_state CopyPix;  /**< For _mesa_meta_CopyPixels() */
306    struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
307    struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
308    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
309 };
310
311
312 /**
313  * Initialize meta-ops for a context.
314  * To be called once during context creation.
315  */
316 void
317 _mesa_meta_init(struct gl_context *ctx)
318 {
319    ASSERT(!ctx->Meta);
320
321    ctx->Meta = CALLOC_STRUCT(gl_meta_state);
322 }
323
324
325 /**
326  * Free context meta-op state.
327  * To be called once during context destruction.
328  */
329 void
330 _mesa_meta_free(struct gl_context *ctx)
331 {
332    /* Note: Any textures, VBOs, etc, that we allocate should get
333     * freed by the normal context destruction code.  But this would be
334     * the place to free other meta data someday.
335     */
336    free(ctx->Meta);
337    ctx->Meta = NULL;
338 }
339
340
341 /**
342  * Enter meta state.  This is like a light-weight version of glPushAttrib
343  * but it also resets most GL state back to default values.
344  *
345  * \param state  bitmask of META_* flags indicating which attribute groups
346  *               to save and reset to their defaults
347  */
348 static void
349 _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
350 {
351    struct save_state *save;
352
353    /* hope MAX_META_OPS_DEPTH is large enough */
354    assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);
355
356    save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
357    memset(save, 0, sizeof(*save));
358    save->SavedState = state;
359
360    if (state & META_ALPHA_TEST) {
361       save->AlphaEnabled = ctx->Color.AlphaEnabled;
362       save->AlphaFunc = ctx->Color.AlphaFunc;
363       save->AlphaRef = ctx->Color.AlphaRef;
364       if (ctx->Color.AlphaEnabled)
365          _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
366    }
367
368    if (state & META_BLEND) {
369       save->BlendEnabled = ctx->Color.BlendEnabled;
370       if (ctx->Color.BlendEnabled) {
371          if (ctx->Extensions.EXT_draw_buffers2) {
372             GLuint i;
373             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
374                _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
375             }
376          }
377          else {
378             _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
379          }
380       }
381       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
382       if (ctx->Color.ColorLogicOpEnabled)
383          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
384    }
385
386    if (state & META_COLOR_MASK) {
387       memcpy(save->ColorMask, ctx->Color.ColorMask,
388              sizeof(ctx->Color.ColorMask));
389       if (!ctx->Color.ColorMask[0][0] ||
390           !ctx->Color.ColorMask[0][1] ||
391           !ctx->Color.ColorMask[0][2] ||
392           !ctx->Color.ColorMask[0][3])
393          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
394    }
395
396    if (state & META_DEPTH_TEST) {
397       save->Depth = ctx->Depth; /* struct copy */
398       if (ctx->Depth.Test)
399          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
400    }
401
402    if (state & META_FOG) {
403       save->Fog = ctx->Fog.Enabled;
404       if (ctx->Fog.Enabled)
405          _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
406    }
407
408    if (state & META_PIXEL_STORE) {
409       save->Pack = ctx->Pack;
410       save->Unpack = ctx->Unpack;
411       ctx->Pack = ctx->DefaultPacking;
412       ctx->Unpack = ctx->DefaultPacking;
413    }
414
415    if (state & META_PIXEL_TRANSFER) {
416       save->RedScale = ctx->Pixel.RedScale;
417       save->RedBias = ctx->Pixel.RedBias;
418       save->GreenScale = ctx->Pixel.GreenScale;
419       save->GreenBias = ctx->Pixel.GreenBias;
420       save->BlueScale = ctx->Pixel.BlueScale;
421       save->BlueBias = ctx->Pixel.BlueBias;
422       save->AlphaScale = ctx->Pixel.AlphaScale;
423       save->AlphaBias = ctx->Pixel.AlphaBias;
424       save->MapColorFlag = ctx->Pixel.MapColorFlag;
425       ctx->Pixel.RedScale = 1.0F;
426       ctx->Pixel.RedBias = 0.0F;
427       ctx->Pixel.GreenScale = 1.0F;
428       ctx->Pixel.GreenBias = 0.0F;
429       ctx->Pixel.BlueScale = 1.0F;
430       ctx->Pixel.BlueBias = 0.0F;
431       ctx->Pixel.AlphaScale = 1.0F;
432       ctx->Pixel.AlphaBias = 0.0F;
433       ctx->Pixel.MapColorFlag = GL_FALSE;
434       /* XXX more state */
435       ctx->NewState |=_NEW_PIXEL;
436    }
437
438    if (state & META_RASTERIZATION) {
439       save->FrontPolygonMode = ctx->Polygon.FrontMode;
440       save->BackPolygonMode = ctx->Polygon.BackMode;
441       save->PolygonOffset = ctx->Polygon.OffsetFill;
442       save->PolygonSmooth = ctx->Polygon.SmoothFlag;
443       save->PolygonStipple = ctx->Polygon.StippleFlag;
444       save->PolygonCull = ctx->Polygon.CullFlag;
445       _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
446       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
447       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
448       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
449       _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
450    }
451
452    if (state & META_SCISSOR) {
453       save->Scissor = ctx->Scissor; /* struct copy */
454       _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE);
455    }
456
457    if (state & META_SHADER) {
458       if (ctx->Extensions.ARB_vertex_program) {
459          save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
460          _mesa_reference_vertprog(ctx, &save->VertexProgram,
461                                   ctx->VertexProgram.Current);
462          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
463       }
464
465       if (ctx->Extensions.ARB_fragment_program) {
466          save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
467          _mesa_reference_fragprog(ctx, &save->FragmentProgram,
468                                   ctx->FragmentProgram.Current);
469          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
470       }
471
472       if (ctx->Extensions.ARB_shader_objects) {
473          _mesa_reference_shader_program(ctx, &save->VertexShader,
474                                         ctx->Shader.CurrentVertexProgram);
475          _mesa_reference_shader_program(ctx, &save->GeometryShader,
476                                         ctx->Shader.CurrentGeometryProgram);
477          _mesa_reference_shader_program(ctx, &save->FragmentShader,
478                                         ctx->Shader.CurrentFragmentProgram);
479          _mesa_reference_shader_program(ctx, &save->ActiveShader,
480                                         ctx->Shader.CurrentFragmentProgram);
481
482          _mesa_UseProgramObjectARB(0);
483       }
484    }
485
486    if (state & META_STENCIL_TEST) {
487       save->Stencil = ctx->Stencil; /* struct copy */
488       if (ctx->Stencil.Enabled)
489          _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
490       /* NOTE: other stencil state not reset */
491    }
492
493    if (state & META_TEXTURE) {
494       GLuint u, tgt;
495
496       save->ActiveUnit = ctx->Texture.CurrentUnit;
497       save->ClientActiveUnit = ctx->Array.ActiveTexture;
498       save->EnvMode = ctx->Texture.Unit[0].EnvMode;
499
500       /* Disable all texture units */
501       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
502          save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
503          save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
504          if (ctx->Texture.Unit[u].Enabled ||
505              ctx->Texture.Unit[u].TexGenEnabled) {
506             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
507             _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
508             _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
509             _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
510             if (ctx->Extensions.ARB_texture_cube_map)
511                _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
512             _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
513             _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
514             _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
515             _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
516             _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
517          }
518       }
519
520       /* save current texture objects for unit[0] only */
521       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
522          _mesa_reference_texobj(&save->CurrentTexture[tgt],
523                                 ctx->Texture.Unit[0].CurrentTex[tgt]);
524       }
525
526       /* set defaults for unit[0] */
527       _mesa_ActiveTextureARB(GL_TEXTURE0);
528       _mesa_ClientActiveTextureARB(GL_TEXTURE0);
529       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
530    }
531
532    if (state & META_TRANSFORM) {
533       GLuint activeTexture = ctx->Texture.CurrentUnit;
534       memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
535              16 * sizeof(GLfloat));
536       memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
537              16 * sizeof(GLfloat));
538       memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
539              16 * sizeof(GLfloat));
540       save->MatrixMode = ctx->Transform.MatrixMode;
541       /* set 1:1 vertex:pixel coordinate transform */
542       _mesa_ActiveTextureARB(GL_TEXTURE0);
543       _mesa_MatrixMode(GL_TEXTURE);
544       _mesa_LoadIdentity();
545       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
546       _mesa_MatrixMode(GL_MODELVIEW);
547       _mesa_LoadIdentity();
548       _mesa_MatrixMode(GL_PROJECTION);
549       _mesa_LoadIdentity();
550       _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
551                   0.0, ctx->DrawBuffer->Height,
552                   -1.0, 1.0);
553    }
554
555    if (state & META_CLIP) {
556       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
557       if (ctx->Transform.ClipPlanesEnabled) {
558          GLuint i;
559          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
560             _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
561          }
562       }
563    }
564
565    if (state & META_VERTEX) {
566       /* save vertex array object state */
567       _mesa_reference_array_object(ctx, &save->ArrayObj,
568                                    ctx->Array.ArrayObj);
569       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
570                                     ctx->Array.ArrayBufferObj);
571       /* set some default state? */
572    }
573
574    if (state & META_VIEWPORT) {
575       /* save viewport state */
576       save->ViewportX = ctx->Viewport.X;
577       save->ViewportY = ctx->Viewport.Y;
578       save->ViewportW = ctx->Viewport.Width;
579       save->ViewportH = ctx->Viewport.Height;
580       /* set viewport to match window size */
581       if (ctx->Viewport.X != 0 ||
582           ctx->Viewport.Y != 0 ||
583           ctx->Viewport.Width != ctx->DrawBuffer->Width ||
584           ctx->Viewport.Height != ctx->DrawBuffer->Height) {
585          _mesa_set_viewport(ctx, 0, 0,
586                             ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
587       }
588       /* save depth range state */
589       save->DepthNear = ctx->Viewport.Near;
590       save->DepthFar = ctx->Viewport.Far;
591       /* set depth range to default */
592       _mesa_DepthRange(0.0, 1.0);
593    }
594
595    if (state & META_CLAMP_FRAGMENT_COLOR) {
596       save->ClampFragmentColor = ctx->Color.ClampFragmentColor;
597
598       /* Generally in here we want to do clamping according to whether
599        * it's for the pixel path (ClampFragmentColor is GL_TRUE),
600        * regardless of the internal implementation of the metaops.
601        */
602       if (ctx->Color.ClampFragmentColor != GL_TRUE)
603          _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
604    }
605
606    if (state & META_CLAMP_VERTEX_COLOR) {
607       save->ClampVertexColor = ctx->Light.ClampVertexColor;
608
609       /* Generally in here we never want vertex color clamping --
610        * result clamping is only dependent on fragment clamping.
611        */
612       _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
613    }
614
615    if (state & META_CONDITIONAL_RENDER) {
616       save->CondRenderQuery = ctx->Query.CondRenderQuery;
617       save->CondRenderMode = ctx->Query.CondRenderMode;
618
619       if (ctx->Query.CondRenderQuery)
620          _mesa_EndConditionalRender();
621    }
622
623    /* misc */
624    {
625       save->Lighting = ctx->Light.Enabled;
626       if (ctx->Light.Enabled)
627          _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
628    }
629 }
630
631
632 /**
633  * Leave meta state.  This is like a light-weight version of glPopAttrib().
634  */
635 static void
636 _mesa_meta_end(struct gl_context *ctx)
637 {
638    struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth];
639    const GLbitfield state = save->SavedState;
640
641    if (state & META_ALPHA_TEST) {
642       if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
643          _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
644       _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
645    }
646
647    if (state & META_BLEND) {
648       if (ctx->Color.BlendEnabled != save->BlendEnabled) {
649          if (ctx->Extensions.EXT_draw_buffers2) {
650             GLuint i;
651             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
652                _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
653             }
654          }
655          else {
656             _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
657          }
658       }
659       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
660          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
661    }
662
663    if (state & META_COLOR_MASK) {
664       GLuint i;
665       for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
666          if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
667             if (i == 0) {
668                _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
669                                save->ColorMask[i][2], save->ColorMask[i][3]);
670             }
671             else {
672                _mesa_ColorMaskIndexed(i,
673                                       save->ColorMask[i][0],
674                                       save->ColorMask[i][1],
675                                       save->ColorMask[i][2],
676                                       save->ColorMask[i][3]);
677             }
678          }
679       }
680    }
681
682    if (state & META_DEPTH_TEST) {
683       if (ctx->Depth.Test != save->Depth.Test)
684          _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
685       _mesa_DepthFunc(save->Depth.Func);
686       _mesa_DepthMask(save->Depth.Mask);
687    }
688
689    if (state & META_FOG) {
690       _mesa_set_enable(ctx, GL_FOG, save->Fog);
691    }
692
693    if (state & META_PIXEL_STORE) {
694       ctx->Pack = save->Pack;
695       ctx->Unpack = save->Unpack;
696    }
697
698    if (state & META_PIXEL_TRANSFER) {
699       ctx->Pixel.RedScale = save->RedScale;
700       ctx->Pixel.RedBias = save->RedBias;
701       ctx->Pixel.GreenScale = save->GreenScale;
702       ctx->Pixel.GreenBias = save->GreenBias;
703       ctx->Pixel.BlueScale = save->BlueScale;
704       ctx->Pixel.BlueBias = save->BlueBias;
705       ctx->Pixel.AlphaScale = save->AlphaScale;
706       ctx->Pixel.AlphaBias = save->AlphaBias;
707       ctx->Pixel.MapColorFlag = save->MapColorFlag;
708       /* XXX more state */
709       ctx->NewState |=_NEW_PIXEL;
710    }
711
712    if (state & META_RASTERIZATION) {
713       _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
714       _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
715       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
716       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
717       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
718       _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
719    }
720
721    if (state & META_SCISSOR) {
722       _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
723       _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
724                     save->Scissor.Width, save->Scissor.Height);
725    }
726
727    if (state & META_SHADER) {
728       if (ctx->Extensions.ARB_vertex_program) {
729          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
730                           save->VertexProgramEnabled);
731          _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, 
732                                   save->VertexProgram);
733          _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL);
734       }
735
736       if (ctx->Extensions.ARB_fragment_program) {
737          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
738                           save->FragmentProgramEnabled);
739          _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
740                                   save->FragmentProgram);
741          _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
742       }
743
744       if (ctx->Extensions.ARB_vertex_shader)
745          _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
746
747       if (ctx->Extensions.ARB_geometry_shader4)
748          _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
749                                   save->GeometryShader);
750
751       if (ctx->Extensions.ARB_fragment_shader)
752          _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
753                                   save->FragmentShader);
754
755       _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram,
756                                      save->ActiveShader);
757    }
758
759    if (state & META_STENCIL_TEST) {
760       const struct gl_stencil_attrib *stencil = &save->Stencil;
761
762       _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
763       _mesa_ClearStencil(stencil->Clear);
764       if (ctx->Extensions.EXT_stencil_two_side) {
765          _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
766                           stencil->TestTwoSide);
767          _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
768                                     ? GL_BACK : GL_FRONT);
769       }
770       /* front state */
771       _mesa_StencilFuncSeparate(GL_FRONT,
772                                 stencil->Function[0],
773                                 stencil->Ref[0],
774                                 stencil->ValueMask[0]);
775       _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
776       _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
777                               stencil->ZFailFunc[0],
778                               stencil->ZPassFunc[0]);
779       /* back state */
780       _mesa_StencilFuncSeparate(GL_BACK,
781                                 stencil->Function[1],
782                                 stencil->Ref[1],
783                                 stencil->ValueMask[1]);
784       _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
785       _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
786                               stencil->ZFailFunc[1],
787                               stencil->ZPassFunc[1]);
788    }
789
790    if (state & META_TEXTURE) {
791       GLuint u, tgt;
792
793       ASSERT(ctx->Texture.CurrentUnit == 0);
794
795       /* restore texenv for unit[0] */
796       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
797
798       /* restore texture objects for unit[0] only */
799       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
800          _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
801                                 save->CurrentTexture[tgt]);
802          _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
803       }
804
805       /* Re-enable textures, texgen */
806       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
807          if (save->TexEnabled[u]) {
808             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
809
810             if (save->TexEnabled[u] & TEXTURE_1D_BIT)
811                _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
812             if (save->TexEnabled[u] & TEXTURE_2D_BIT)
813                _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
814             if (save->TexEnabled[u] & TEXTURE_3D_BIT)
815                _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
816             if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
817                _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
818             if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
819                _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
820          }
821
822          if (save->TexGenEnabled[u]) {
823             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
824
825             if (save->TexGenEnabled[u] & S_BIT)
826                _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
827             if (save->TexGenEnabled[u] & T_BIT)
828                _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
829             if (save->TexGenEnabled[u] & R_BIT)
830                _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
831             if (save->TexGenEnabled[u] & Q_BIT)
832                _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
833          }
834       }
835
836       /* restore current unit state */
837       _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
838       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
839    }
840
841    if (state & META_TRANSFORM) {
842       GLuint activeTexture = ctx->Texture.CurrentUnit;
843       _mesa_ActiveTextureARB(GL_TEXTURE0);
844       _mesa_MatrixMode(GL_TEXTURE);
845       _mesa_LoadMatrixf(save->TextureMatrix);
846       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
847
848       _mesa_MatrixMode(GL_MODELVIEW);
849       _mesa_LoadMatrixf(save->ModelviewMatrix);
850
851       _mesa_MatrixMode(GL_PROJECTION);
852       _mesa_LoadMatrixf(save->ProjectionMatrix);
853
854       _mesa_MatrixMode(save->MatrixMode);
855    }
856
857    if (state & META_CLIP) {
858       if (save->ClipPlanesEnabled) {
859          GLuint i;
860          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
861             if (save->ClipPlanesEnabled & (1 << i)) {
862                _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
863             }
864          }
865       }
866    }
867
868    if (state & META_VERTEX) {
869       /* restore vertex buffer object */
870       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
871       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
872
873       /* restore vertex array object */
874       _mesa_BindVertexArray(save->ArrayObj->Name);
875       _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
876    }
877
878    if (state & META_VIEWPORT) {
879       if (save->ViewportX != ctx->Viewport.X ||
880           save->ViewportY != ctx->Viewport.Y ||
881           save->ViewportW != ctx->Viewport.Width ||
882           save->ViewportH != ctx->Viewport.Height) {
883          _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
884                             save->ViewportW, save->ViewportH);
885       }
886       _mesa_DepthRange(save->DepthNear, save->DepthFar);
887    }
888
889    if (state & META_CLAMP_FRAGMENT_COLOR) {
890       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor);
891    }
892
893    if (state & META_CLAMP_VERTEX_COLOR) {
894       _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor);
895    }
896
897    if (state & META_CONDITIONAL_RENDER) {
898       if (save->CondRenderQuery)
899          _mesa_BeginConditionalRender(save->CondRenderQuery->Id,
900                                       save->CondRenderMode);
901    }
902
903    /* misc */
904    if (save->Lighting) {
905       _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
906    }
907 }
908
909
910 /**
911  * Convert Z from a normalized value in the range [0, 1] to an object-space
912  * Z coordinate in [-1, +1] so that drawing at the new Z position with the
913  * default/identity ortho projection results in the original Z value.
914  * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z
915  * value comes from the clear value or raster position.
916  */
917 static INLINE GLfloat
918 invert_z(GLfloat normZ)
919 {
920    GLfloat objZ = 1.0 - 2.0 * normZ;
921    return objZ;
922 }
923
924
925 /**
926  * One-time init for a temp_texture object.
927  * Choose tex target, compute max tex size, etc.
928  */
929 static void
930 init_temp_texture(struct gl_context *ctx, struct temp_texture *tex)
931 {
932    /* prefer texture rectangle */
933    if (ctx->Extensions.NV_texture_rectangle) {
934       tex->Target = GL_TEXTURE_RECTANGLE;
935       tex->MaxSize = ctx->Const.MaxTextureRectSize;
936       tex->NPOT = GL_TRUE;
937    }
938    else {
939       /* use 2D texture, NPOT if possible */
940       tex->Target = GL_TEXTURE_2D;
941       tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
942       tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
943    }
944    tex->MinSize = 16;  /* 16 x 16 at least */
945    assert(tex->MaxSize > 0);
946
947    _mesa_GenTextures(1, &tex->TexObj);
948 }
949
950
951 /**
952  * Return pointer to temp_texture info for non-bitmap ops.
953  * This does some one-time init if needed.
954  */
955 static struct temp_texture *
956 get_temp_texture(struct gl_context *ctx)
957 {
958    struct temp_texture *tex = &ctx->Meta->TempTex;
959
960    if (!tex->TexObj) {
961       init_temp_texture(ctx, tex);
962    }
963
964    return tex;
965 }
966
967
968 /**
969  * Return pointer to temp_texture info for _mesa_meta_bitmap().
970  * We use a separate texture for bitmaps to reduce texture
971  * allocation/deallocation.
972  */
973 static struct temp_texture *
974 get_bitmap_temp_texture(struct gl_context *ctx)
975 {
976    struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
977
978    if (!tex->TexObj) {
979       init_temp_texture(ctx, tex);
980    }
981
982    return tex;
983 }
984
985
986 /**
987  * Compute the width/height of texture needed to draw an image of the
988  * given size.  Return a flag indicating whether the current texture
989  * can be re-used (glTexSubImage2D) or if a new texture needs to be
990  * allocated (glTexImage2D).
991  * Also, compute s/t texcoords for drawing.
992  *
993  * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
994  */
995 static GLboolean
996 alloc_texture(struct temp_texture *tex,
997               GLsizei width, GLsizei height, GLenum intFormat)
998 {
999    GLboolean newTex = GL_FALSE;
1000
1001    ASSERT(width <= tex->MaxSize);
1002    ASSERT(height <= tex->MaxSize);
1003
1004    if (width > tex->Width ||
1005        height > tex->Height ||
1006        intFormat != tex->IntFormat) {
1007       /* alloc new texture (larger or different format) */
1008
1009       if (tex->NPOT) {
1010          /* use non-power of two size */
1011          tex->Width = MAX2(tex->MinSize, width);
1012          tex->Height = MAX2(tex->MinSize, height);
1013       }
1014       else {
1015          /* find power of two size */
1016          GLsizei w, h;
1017          w = h = tex->MinSize;
1018          while (w < width)
1019             w *= 2;
1020          while (h < height)
1021             h *= 2;
1022          tex->Width = w;
1023          tex->Height = h;
1024       }
1025
1026       tex->IntFormat = intFormat;
1027
1028       newTex = GL_TRUE;
1029    }
1030
1031    /* compute texcoords */
1032    if (tex->Target == GL_TEXTURE_RECTANGLE) {
1033       tex->Sright = (GLfloat) width;
1034       tex->Ttop = (GLfloat) height;
1035    }
1036    else {
1037       tex->Sright = (GLfloat) width / tex->Width;
1038       tex->Ttop = (GLfloat) height / tex->Height;
1039    }
1040
1041    return newTex;
1042 }
1043
1044
1045 /**
1046  * Setup/load texture for glCopyPixels or glBlitFramebuffer.
1047  */
1048 static void
1049 setup_copypix_texture(struct temp_texture *tex,
1050                       GLboolean newTex,
1051                       GLint srcX, GLint srcY,
1052                       GLsizei width, GLsizei height, GLenum intFormat,
1053                       GLenum filter)
1054 {
1055    _mesa_BindTexture(tex->Target, tex->TexObj);
1056    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
1057    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
1058    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1059
1060    /* copy framebuffer image to texture */
1061    if (newTex) {
1062       /* create new tex image */
1063       if (tex->Width == width && tex->Height == height) {
1064          /* create new tex with framebuffer data */
1065          _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
1066                               srcX, srcY, width, height, 0);
1067       }
1068       else {
1069          /* create empty texture */
1070          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1071                           tex->Width, tex->Height, 0,
1072                           intFormat, GL_UNSIGNED_BYTE, NULL);
1073          /* load image */
1074          _mesa_CopyTexSubImage2D(tex->Target, 0,
1075                                  0, 0, srcX, srcY, width, height);
1076       }
1077    }
1078    else {
1079       /* replace existing tex image */
1080       _mesa_CopyTexSubImage2D(tex->Target, 0,
1081                               0, 0, srcX, srcY, width, height);
1082    }
1083 }
1084
1085
1086 /**
1087  * Setup/load texture for glDrawPixels.
1088  */
1089 static void
1090 setup_drawpix_texture(struct gl_context *ctx,
1091                       struct temp_texture *tex,
1092                       GLboolean newTex,
1093                       GLenum texIntFormat,
1094                       GLsizei width, GLsizei height,
1095                       GLenum format, GLenum type,
1096                       const GLvoid *pixels)
1097 {
1098    _mesa_BindTexture(tex->Target, tex->TexObj);
1099    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1100    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1101    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1102
1103    /* copy pixel data to texture */
1104    if (newTex) {
1105       /* create new tex image */
1106       if (tex->Width == width && tex->Height == height) {
1107          /* create new tex and load image data */
1108          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1109                           tex->Width, tex->Height, 0, format, type, pixels);
1110       }
1111       else {
1112          struct gl_buffer_object *save_unpack_obj = NULL;
1113
1114          _mesa_reference_buffer_object(ctx, &save_unpack_obj,
1115                                        ctx->Unpack.BufferObj);
1116          _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1117          /* create empty texture */
1118          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1119                           tex->Width, tex->Height, 0, format, type, NULL);
1120          if (save_unpack_obj != NULL)
1121             _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
1122                                 save_unpack_obj->Name);
1123          /* load image */
1124          _mesa_TexSubImage2D(tex->Target, 0,
1125                              0, 0, width, height, format, type, pixels);
1126       }
1127    }
1128    else {
1129       /* replace existing tex image */
1130       _mesa_TexSubImage2D(tex->Target, 0,
1131                           0, 0, width, height, format, type, pixels);
1132    }
1133 }
1134
1135
1136
1137 /**
1138  * One-time init for drawing depth pixels.
1139  */
1140 static void
1141 init_blit_depth_pixels(struct gl_context *ctx)
1142 {
1143    static const char *program =
1144       "!!ARBfp1.0\n"
1145       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1146       "END \n";
1147    char program2[200];
1148    struct blit_state *blit = &ctx->Meta->Blit;
1149    struct temp_texture *tex = get_temp_texture(ctx);
1150    const char *texTarget;
1151
1152    assert(blit->DepthFP == 0);
1153
1154    /* replace %s with "RECT" or "2D" */
1155    assert(strlen(program) + 4 < sizeof(program2));
1156    if (tex->Target == GL_TEXTURE_RECTANGLE)
1157       texTarget = "RECT";
1158    else
1159       texTarget = "2D";
1160    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1161
1162    _mesa_GenPrograms(1, &blit->DepthFP);
1163    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1164    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1165                           strlen(program2), (const GLubyte *) program2);
1166 }
1167
1168
1169 /**
1170  * Try to do a glBlitFramebuffer using no-copy texturing.
1171  * We can do this when the src renderbuffer is actually a texture.
1172  * But if the src buffer == dst buffer we cannot do this.
1173  *
1174  * \return new buffer mask indicating the buffers left to blit using the
1175  *         normal path.
1176  */
1177 static GLbitfield
1178 blitframebuffer_texture(struct gl_context *ctx,
1179                         GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1180                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1181                         GLbitfield mask, GLenum filter)
1182 {
1183    if (mask & GL_COLOR_BUFFER_BIT) {
1184       const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
1185       const struct gl_framebuffer *readFb = ctx->ReadBuffer;
1186       const struct gl_renderbuffer_attachment *drawAtt =
1187          &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
1188       const struct gl_renderbuffer_attachment *readAtt =
1189          &readFb->Attachment[readFb->_ColorReadBufferIndex];
1190
1191       if (readAtt && readAtt->Texture) {
1192          const struct gl_texture_object *texObj = readAtt->Texture;
1193          const GLuint srcLevel = readAtt->TextureLevel;
1194          const GLenum minFilterSave = texObj->Sampler.MinFilter;
1195          const GLenum magFilterSave = texObj->Sampler.MagFilter;
1196          const GLint baseLevelSave = texObj->BaseLevel;
1197          const GLint maxLevelSave = texObj->MaxLevel;
1198          const GLenum wrapSSave = texObj->Sampler.WrapS;
1199          const GLenum wrapTSave = texObj->Sampler.WrapT;
1200          const GLenum srgbSave = texObj->Sampler.sRGBDecode;
1201          const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;
1202          const GLenum target = texObj->Target;
1203
1204          if (drawAtt->Texture == readAtt->Texture) {
1205             /* Can't use same texture as both the source and dest.  We need
1206              * to handle overlapping blits and besides, some hw may not
1207              * support this.
1208              */
1209             return mask;
1210          }
1211
1212          if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
1213             /* Can't handle other texture types at this time */
1214             return mask;
1215          }
1216
1217          /*
1218          printf("Blit from texture!\n");
1219          printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);
1220          printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);
1221          */
1222
1223          /* Prepare src texture state */
1224          _mesa_BindTexture(target, texObj->Name);
1225          _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
1226          _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
1227          if (target != GL_TEXTURE_RECTANGLE_ARB) {
1228             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
1229             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
1230          }
1231          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1232          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1233
1234          /* Always do our blits with no sRGB decode or encode.*/
1235          if (ctx->Extensions.EXT_texture_sRGB_decode) {
1236             _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
1237                                 GL_SKIP_DECODE_EXT);
1238          }
1239          _mesa_Disable(GL_FRAMEBUFFER_SRGB_EXT);
1240
1241          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1242          _mesa_set_enable(ctx, target, GL_TRUE);
1243
1244          /* Prepare vertex data (the VBO was previously created and bound) */
1245          {
1246             struct vertex {
1247                GLfloat x, y, s, t;
1248             };
1249             struct vertex verts[4];
1250             GLfloat s0, t0, s1, t1;
1251
1252             if (target == GL_TEXTURE_2D) {
1253                const struct gl_texture_image *texImage
1254                    = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
1255                s0 = srcX0 / (float) texImage->Width;
1256                s1 = srcX1 / (float) texImage->Width;
1257                t0 = srcY0 / (float) texImage->Height;
1258                t1 = srcY1 / (float) texImage->Height;
1259             }
1260             else {
1261                assert(target == GL_TEXTURE_RECTANGLE_ARB);
1262                s0 = srcX0;
1263                s1 = srcX1;
1264                t0 = srcY0;
1265                t1 = srcY1;
1266             }
1267
1268             verts[0].x = (GLfloat) dstX0;
1269             verts[0].y = (GLfloat) dstY0;
1270             verts[1].x = (GLfloat) dstX1;
1271             verts[1].y = (GLfloat) dstY0;
1272             verts[2].x = (GLfloat) dstX1;
1273             verts[2].y = (GLfloat) dstY1;
1274             verts[3].x = (GLfloat) dstX0;
1275             verts[3].y = (GLfloat) dstY1;
1276
1277             verts[0].s = s0;
1278             verts[0].t = t0;
1279             verts[1].s = s1;
1280             verts[1].t = t0;
1281             verts[2].s = s1;
1282             verts[2].t = t1;
1283             verts[3].s = s0;
1284             verts[3].t = t1;
1285
1286             _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1287          }
1288
1289          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1290
1291          /* Restore texture object state, the texture binding will
1292           * be restored by _mesa_meta_end().
1293           */
1294          _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
1295          _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
1296          if (target != GL_TEXTURE_RECTANGLE_ARB) {
1297             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
1298             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
1299          }
1300          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
1301          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
1302          if (ctx->Extensions.EXT_texture_sRGB_decode) {
1303             _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, srgbSave);
1304          }
1305          if (ctx->Extensions.EXT_texture_sRGB_decode && fbo_srgb_save) {
1306             _mesa_Enable(GL_FRAMEBUFFER_SRGB_EXT);
1307          }
1308
1309          /* Done with color buffer */
1310          mask &= ~GL_COLOR_BUFFER_BIT;
1311       }
1312    }
1313
1314    return mask;
1315 }
1316
1317
1318 /**
1319  * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
1320  * of texture mapping and polygon rendering.
1321  */
1322 void
1323 _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
1324                            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1325                            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1326                            GLbitfield mask, GLenum filter)
1327 {
1328    struct blit_state *blit = &ctx->Meta->Blit;
1329    struct temp_texture *tex = get_temp_texture(ctx);
1330    const GLsizei maxTexSize = tex->MaxSize;
1331    const GLint srcX = MIN2(srcX0, srcX1);
1332    const GLint srcY = MIN2(srcY0, srcY1);
1333    const GLint srcW = abs(srcX1 - srcX0);
1334    const GLint srcH = abs(srcY1 - srcY0);
1335    const GLboolean srcFlipX = srcX1 < srcX0;
1336    const GLboolean srcFlipY = srcY1 < srcY0;
1337    struct vertex {
1338       GLfloat x, y, s, t;
1339    };
1340    struct vertex verts[4];
1341    GLboolean newTex;
1342
1343    if (srcW > maxTexSize || srcH > maxTexSize) {
1344       /* XXX avoid this fallback */
1345       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1346                               dstX0, dstY0, dstX1, dstY1, mask, filter);
1347       return;
1348    }
1349
1350    if (srcFlipX) {
1351       GLint tmp = dstX0;
1352       dstX0 = dstX1;
1353       dstX1 = tmp;
1354    }
1355
1356    if (srcFlipY) {
1357       GLint tmp = dstY0;
1358       dstY0 = dstY1;
1359       dstY1 = tmp;
1360    }
1361
1362    /* only scissor effects blit so save/clear all other relevant state */
1363    _mesa_meta_begin(ctx, ~META_SCISSOR);
1364
1365    if (blit->ArrayObj == 0) {
1366       /* one-time setup */
1367
1368       /* create vertex array object */
1369       _mesa_GenVertexArrays(1, &blit->ArrayObj);
1370       _mesa_BindVertexArray(blit->ArrayObj);
1371
1372       /* create vertex array buffer */
1373       _mesa_GenBuffersARB(1, &blit->VBO);
1374       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1375       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1376                           NULL, GL_DYNAMIC_DRAW_ARB);
1377
1378       /* setup vertex arrays */
1379       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1380       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1381       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1382       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1383    }
1384    else {
1385       _mesa_BindVertexArray(blit->ArrayObj);
1386       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1387    }
1388
1389    /* Try faster, direct texture approach first */
1390    mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
1391                                   dstX0, dstY0, dstX1, dstY1, mask, filter);
1392    if (mask == 0x0) {
1393       _mesa_meta_end(ctx);
1394       return;
1395    }
1396
1397    /* Continue with "normal" approach which involves copying the src rect
1398     * into a temporary texture and is "blitted" by drawing a textured quad.
1399     */
1400
1401    newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
1402
1403    /* vertex positions/texcoords (after texture allocation!) */
1404    {
1405       verts[0].x = (GLfloat) dstX0;
1406       verts[0].y = (GLfloat) dstY0;
1407       verts[1].x = (GLfloat) dstX1;
1408       verts[1].y = (GLfloat) dstY0;
1409       verts[2].x = (GLfloat) dstX1;
1410       verts[2].y = (GLfloat) dstY1;
1411       verts[3].x = (GLfloat) dstX0;
1412       verts[3].y = (GLfloat) dstY1;
1413
1414       verts[0].s = 0.0F;
1415       verts[0].t = 0.0F;
1416       verts[1].s = tex->Sright;
1417       verts[1].t = 0.0F;
1418       verts[2].s = tex->Sright;
1419       verts[2].t = tex->Ttop;
1420       verts[3].s = 0.0F;
1421       verts[3].t = tex->Ttop;
1422
1423       /* upload new vertex data */
1424       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1425    }
1426
1427    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1428
1429    if (mask & GL_COLOR_BUFFER_BIT) {
1430       setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
1431                             GL_RGBA, filter);
1432       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1433       mask &= ~GL_COLOR_BUFFER_BIT;
1434    }
1435
1436    if (mask & GL_DEPTH_BUFFER_BIT) {
1437       GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
1438       if (tmp) {
1439          if (!blit->DepthFP)
1440             init_blit_depth_pixels(ctx);
1441
1442          /* maybe change tex format here */
1443          newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
1444
1445          _mesa_ReadPixels(srcX, srcY, srcW, srcH,
1446                           GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1447
1448          setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
1449                                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1450
1451          _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1452          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1453          _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1454          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1455          _mesa_DepthFunc(GL_ALWAYS);
1456          _mesa_DepthMask(GL_TRUE);
1457
1458          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1459          mask &= ~GL_DEPTH_BUFFER_BIT;
1460
1461          free(tmp);
1462       }
1463    }
1464
1465    if (mask & GL_STENCIL_BUFFER_BIT) {
1466       /* XXX can't easily do stencil */
1467    }
1468
1469    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1470
1471    _mesa_meta_end(ctx);
1472
1473    if (mask) {
1474       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1475                               dstX0, dstY0, dstX1, dstY1, mask, filter);
1476    }
1477 }
1478
1479
1480 /**
1481  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1482  */
1483 void
1484 _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
1485 {
1486    struct clear_state *clear = &ctx->Meta->Clear;
1487    struct vertex {
1488       GLfloat x, y, z, r, g, b, a;
1489    };
1490    struct vertex verts[4];
1491    /* save all state but scissor, pixel pack/unpack */
1492    GLbitfield metaSave = (META_ALL -
1493                           META_SCISSOR -
1494                           META_PIXEL_STORE -
1495                           META_CONDITIONAL_RENDER);
1496    const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
1497
1498    if (buffers & BUFFER_BITS_COLOR) {
1499       /* if clearing color buffers, don't save/restore colormask */
1500       metaSave -= META_COLOR_MASK;
1501    }
1502
1503    _mesa_meta_begin(ctx, metaSave);
1504
1505    if (clear->ArrayObj == 0) {
1506       /* one-time setup */
1507
1508       /* create vertex array object */
1509       _mesa_GenVertexArrays(1, &clear->ArrayObj);
1510       _mesa_BindVertexArray(clear->ArrayObj);
1511
1512       /* create vertex array buffer */
1513       _mesa_GenBuffersARB(1, &clear->VBO);
1514       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1515
1516       /* setup vertex arrays */
1517       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1518       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1519       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1520       _mesa_EnableClientState(GL_COLOR_ARRAY);
1521    }
1522    else {
1523       _mesa_BindVertexArray(clear->ArrayObj);
1524       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1525    }
1526
1527    /* GL_COLOR_BUFFER_BIT */
1528    if (buffers & BUFFER_BITS_COLOR) {
1529       /* leave colormask, glDrawBuffer state as-is */
1530
1531       /* Clears never have the color clamped. */
1532       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
1533    }
1534    else {
1535       ASSERT(metaSave & META_COLOR_MASK);
1536       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1537    }
1538
1539    /* GL_DEPTH_BUFFER_BIT */
1540    if (buffers & BUFFER_BIT_DEPTH) {
1541       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1542       _mesa_DepthFunc(GL_ALWAYS);
1543       _mesa_DepthMask(GL_TRUE);
1544    }
1545    else {
1546       assert(!ctx->Depth.Test);
1547    }
1548
1549    /* GL_STENCIL_BUFFER_BIT */
1550    if (buffers & BUFFER_BIT_STENCIL) {
1551       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1552       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1553                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
1554       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1555                                 ctx->Stencil.Clear & stencilMax,
1556                                 ctx->Stencil.WriteMask[0]);
1557    }
1558    else {
1559       assert(!ctx->Stencil.Enabled);
1560    }
1561
1562    /* vertex positions/colors */
1563    {
1564       const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
1565       const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
1566       const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
1567       const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
1568       const GLfloat z = invert_z(ctx->Depth.Clear);
1569       GLuint i;
1570
1571       verts[0].x = x0;
1572       verts[0].y = y0;
1573       verts[0].z = z;
1574       verts[1].x = x1;
1575       verts[1].y = y0;
1576       verts[1].z = z;
1577       verts[2].x = x1;
1578       verts[2].y = y1;
1579       verts[2].z = z;
1580       verts[3].x = x0;
1581       verts[3].y = y1;
1582       verts[3].z = z;
1583
1584       /* vertex colors */
1585       for (i = 0; i < 4; i++) {
1586          verts[i].r = ctx->Color.ClearColorUnclamped[0];
1587          verts[i].g = ctx->Color.ClearColorUnclamped[1];
1588          verts[i].b = ctx->Color.ClearColorUnclamped[2];
1589          verts[i].a = ctx->Color.ClearColorUnclamped[3];
1590       }
1591
1592       /* upload new vertex data */
1593       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
1594                           GL_DYNAMIC_DRAW_ARB);
1595    }
1596
1597    /* draw quad */
1598    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1599
1600    _mesa_meta_end(ctx);
1601 }
1602
1603 static void
1604 meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
1605 {
1606    const char *vs_source =
1607       "attribute vec4 position;\n"
1608       "void main()\n"
1609       "{\n"
1610       "   gl_Position = position;\n"
1611       "}\n";
1612    const char *fs_source =
1613       "uniform vec4 color;\n"
1614       "void main()\n"
1615       "{\n"
1616       "   gl_FragColor = color;\n"
1617       "}\n";
1618    GLuint vs, fs;
1619
1620    if (clear->ArrayObj != 0)
1621       return;
1622
1623    /* create vertex array object */
1624    _mesa_GenVertexArrays(1, &clear->ArrayObj);
1625    _mesa_BindVertexArray(clear->ArrayObj);
1626
1627    /* create vertex array buffer */
1628    _mesa_GenBuffersARB(1, &clear->VBO);
1629    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1630
1631    /* setup vertex arrays */
1632    _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
1633    _mesa_EnableVertexAttribArrayARB(0);
1634
1635    vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER);
1636    _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL);
1637    _mesa_CompileShaderARB(vs);
1638
1639    fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
1640    _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL);
1641    _mesa_CompileShaderARB(fs);
1642
1643    clear->ShaderProg = _mesa_CreateProgramObjectARB();
1644    _mesa_AttachShader(clear->ShaderProg, fs);
1645    _mesa_AttachShader(clear->ShaderProg, vs);
1646    _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position");
1647    _mesa_LinkProgramARB(clear->ShaderProg);
1648
1649    clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg,
1650                                                       "color");
1651 }
1652
1653 /**
1654  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1655  */
1656 void
1657 _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
1658 {
1659    struct clear_state *clear = &ctx->Meta->Clear;
1660    GLbitfield metaSave;
1661    const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
1662    struct gl_framebuffer *fb = ctx->DrawBuffer;
1663    const float x0 = ((float)fb->_Xmin / fb->Width)  * 2.0f - 1.0f;
1664    const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f;
1665    const float x1 = ((float)fb->_Xmax / fb->Width)  * 2.0f - 1.0f;
1666    const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f;
1667    const float z = -invert_z(ctx->Depth.Clear);
1668    struct vertex {
1669       GLfloat x, y, z;
1670    } verts[4];
1671
1672    metaSave = (META_ALPHA_TEST |
1673                META_BLEND |
1674                META_DEPTH_TEST |
1675                META_RASTERIZATION |
1676                META_SHADER |
1677                META_STENCIL_TEST |
1678                META_VERTEX |
1679                META_VIEWPORT |
1680                META_CLIP |
1681                META_CLAMP_FRAGMENT_COLOR);
1682
1683    if (!(buffers & BUFFER_BITS_COLOR)) {
1684       /* We'll use colormask to disable color writes.  Otherwise,
1685        * respect color mask
1686        */
1687       metaSave |= META_COLOR_MASK;
1688    }
1689
1690    _mesa_meta_begin(ctx, metaSave);
1691
1692    meta_glsl_clear_init(ctx, clear);
1693
1694    _mesa_UseProgramObjectARB(clear->ShaderProg);
1695    _mesa_Uniform4fvARB(clear->ColorLocation, 1,
1696                        ctx->Color.ClearColorUnclamped);
1697
1698    _mesa_BindVertexArray(clear->ArrayObj);
1699    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1700
1701    /* GL_COLOR_BUFFER_BIT */
1702    if (buffers & BUFFER_BITS_COLOR) {
1703       /* leave colormask, glDrawBuffer state as-is */
1704
1705       /* Clears never have the color clamped. */
1706       _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
1707    }
1708    else {
1709       ASSERT(metaSave & META_COLOR_MASK);
1710       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1711    }
1712
1713    /* GL_DEPTH_BUFFER_BIT */
1714    if (buffers & BUFFER_BIT_DEPTH) {
1715       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1716       _mesa_DepthFunc(GL_ALWAYS);
1717       _mesa_DepthMask(GL_TRUE);
1718    }
1719    else {
1720       assert(!ctx->Depth.Test);
1721    }
1722
1723    /* GL_STENCIL_BUFFER_BIT */
1724    if (buffers & BUFFER_BIT_STENCIL) {
1725       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1726       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1727                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
1728       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1729                                 ctx->Stencil.Clear & stencilMax,
1730                                 ctx->Stencil.WriteMask[0]);
1731    }
1732    else {
1733       assert(!ctx->Stencil.Enabled);
1734    }
1735
1736    /* vertex positions */
1737    verts[0].x = x0;
1738    verts[0].y = y0;
1739    verts[0].z = z;
1740    verts[1].x = x1;
1741    verts[1].y = y0;
1742    verts[1].z = z;
1743    verts[2].x = x1;
1744    verts[2].y = y1;
1745    verts[2].z = z;
1746    verts[3].x = x0;
1747    verts[3].y = y1;
1748    verts[3].z = z;
1749
1750    /* upload new vertex data */
1751    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
1752                        GL_DYNAMIC_DRAW_ARB);
1753
1754    /* draw quad */
1755    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1756
1757    _mesa_meta_end(ctx);
1758 }
1759
1760 /**
1761  * Meta implementation of ctx->Driver.CopyPixels() in terms
1762  * of texture mapping and polygon rendering and GLSL shaders.
1763  */
1764 void
1765 _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
1766                       GLsizei width, GLsizei height,
1767                       GLint dstX, GLint dstY, GLenum type)
1768 {
1769    struct copypix_state *copypix = &ctx->Meta->CopyPix;
1770    struct temp_texture *tex = get_temp_texture(ctx);
1771    struct vertex {
1772       GLfloat x, y, z, s, t;
1773    };
1774    struct vertex verts[4];
1775    GLboolean newTex;
1776    GLenum intFormat = GL_RGBA;
1777
1778    if (type != GL_COLOR ||
1779        ctx->_ImageTransferState ||
1780        ctx->Fog.Enabled ||
1781        width > tex->MaxSize ||
1782        height > tex->MaxSize) {
1783       /* XXX avoid this fallback */
1784       _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
1785       return;
1786    }
1787
1788    /* Most GL state applies to glCopyPixels, but a there's a few things
1789     * we need to override:
1790     */
1791    _mesa_meta_begin(ctx, (META_RASTERIZATION |
1792                           META_SHADER |
1793                           META_TEXTURE |
1794                           META_TRANSFORM |
1795                           META_CLIP |
1796                           META_VERTEX |
1797                           META_VIEWPORT));
1798
1799    if (copypix->ArrayObj == 0) {
1800       /* one-time setup */
1801
1802       /* create vertex array object */
1803       _mesa_GenVertexArrays(1, &copypix->ArrayObj);
1804       _mesa_BindVertexArray(copypix->ArrayObj);
1805
1806       /* create vertex array buffer */
1807       _mesa_GenBuffersARB(1, &copypix->VBO);
1808       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1809       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1810                           NULL, GL_DYNAMIC_DRAW_ARB);
1811
1812       /* setup vertex arrays */
1813       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1814       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1815       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1816       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1817    }
1818    else {
1819       _mesa_BindVertexArray(copypix->ArrayObj);
1820       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1821    }
1822
1823    newTex = alloc_texture(tex, width, height, intFormat);
1824
1825    /* vertex positions, texcoords (after texture allocation!) */
1826    {
1827       const GLfloat dstX0 = (GLfloat) dstX;
1828       const GLfloat dstY0 = (GLfloat) dstY;
1829       const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
1830       const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
1831       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
1832
1833       verts[0].x = dstX0;
1834       verts[0].y = dstY0;
1835       verts[0].z = z;
1836       verts[0].s = 0.0F;
1837       verts[0].t = 0.0F;
1838       verts[1].x = dstX1;
1839       verts[1].y = dstY0;
1840       verts[1].z = z;
1841       verts[1].s = tex->Sright;
1842       verts[1].t = 0.0F;
1843       verts[2].x = dstX1;
1844       verts[2].y = dstY1;
1845       verts[2].z = z;
1846       verts[2].s = tex->Sright;
1847       verts[2].t = tex->Ttop;
1848       verts[3].x = dstX0;
1849       verts[3].y = dstY1;
1850       verts[3].z = z;
1851       verts[3].s = 0.0F;
1852       verts[3].t = tex->Ttop;
1853
1854       /* upload new vertex data */
1855       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1856    }
1857
1858    /* Alloc/setup texture */
1859    setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
1860                          GL_RGBA, GL_NEAREST);
1861
1862    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1863
1864    /* draw textured quad */
1865    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1866
1867    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1868
1869    _mesa_meta_end(ctx);
1870 }
1871
1872
1873
1874 /**
1875  * When the glDrawPixels() image size is greater than the max rectangle
1876  * texture size we use this function to break the glDrawPixels() image
1877  * into tiles which fit into the max texture size.
1878  */
1879 static void
1880 tiled_draw_pixels(struct gl_context *ctx,
1881                   GLint tileSize,
1882                   GLint x, GLint y, GLsizei width, GLsizei height,
1883                   GLenum format, GLenum type,
1884                   const struct gl_pixelstore_attrib *unpack,
1885                   const GLvoid *pixels)
1886 {
1887    struct gl_pixelstore_attrib tileUnpack = *unpack;
1888    GLint i, j;
1889
1890    if (tileUnpack.RowLength == 0)
1891       tileUnpack.RowLength = width;
1892
1893    for (i = 0; i < width; i += tileSize) {
1894       const GLint tileWidth = MIN2(tileSize, width - i);
1895       const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
1896
1897       tileUnpack.SkipPixels = unpack->SkipPixels + i;
1898
1899       for (j = 0; j < height; j += tileSize) {
1900          const GLint tileHeight = MIN2(tileSize, height - j);
1901          const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
1902
1903          tileUnpack.SkipRows = unpack->SkipRows + j;
1904
1905          _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
1906                                format, type, &tileUnpack, pixels);
1907       }
1908    }
1909 }
1910
1911
1912 /**
1913  * One-time init for drawing stencil pixels.
1914  */
1915 static void
1916 init_draw_stencil_pixels(struct gl_context *ctx)
1917 {
1918    /* This program is run eight times, once for each stencil bit.
1919     * The stencil values to draw are found in an 8-bit alpha texture.
1920     * We read the texture/stencil value and test if bit 'b' is set.
1921     * If the bit is not set, use KIL to kill the fragment.
1922     * Finally, we use the stencil test to update the stencil buffer.
1923     *
1924     * The basic algorithm for checking if a bit is set is:
1925     *   if (is_odd(value / (1 << bit)))
1926     *      result is one (or non-zero).
1927     *   else
1928     *      result is zero.
1929     * The program parameter contains three values:
1930     *   parm.x = 255 / (1 << bit)
1931     *   parm.y = 0.5
1932     *   parm.z = 0.0
1933     */
1934    static const char *program =
1935       "!!ARBfp1.0\n"
1936       "PARAM parm = program.local[0]; \n"
1937       "TEMP t; \n"
1938       "TEX t, fragment.texcoord[0], texture[0], %s; \n"   /* NOTE %s here! */
1939       "# t = t * 255 / bit \n"
1940       "MUL t.x, t.a, parm.x; \n"
1941       "# t = (int) t \n"
1942       "FRC t.y, t.x; \n"
1943       "SUB t.x, t.x, t.y; \n"
1944       "# t = t * 0.5 \n"
1945       "MUL t.x, t.x, parm.y; \n"
1946       "# t = fract(t.x) \n"
1947       "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
1948       "# t.x = (t.x == 0 ? 1 : 0) \n"
1949       "SGE t.x, -t.x, parm.z; \n"
1950       "KIL -t.x; \n"
1951       "# for debug only \n"
1952       "#MOV result.color, t.x; \n"
1953       "END \n";
1954    char program2[1000];
1955    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1956    struct temp_texture *tex = get_temp_texture(ctx);
1957    const char *texTarget;
1958
1959    assert(drawpix->StencilFP == 0);
1960
1961    /* replace %s with "RECT" or "2D" */
1962    assert(strlen(program) + 4 < sizeof(program2));
1963    if (tex->Target == GL_TEXTURE_RECTANGLE)
1964       texTarget = "RECT";
1965    else
1966       texTarget = "2D";
1967    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1968
1969    _mesa_GenPrograms(1, &drawpix->StencilFP);
1970    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1971    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1972                           strlen(program2), (const GLubyte *) program2);
1973 }
1974
1975
1976 /**
1977  * One-time init for drawing depth pixels.
1978  */
1979 static void
1980 init_draw_depth_pixels(struct gl_context *ctx)
1981 {
1982    static const char *program =
1983       "!!ARBfp1.0\n"
1984       "PARAM color = program.local[0]; \n"
1985       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1986       "MOV result.color, color; \n"
1987       "END \n";
1988    char program2[200];
1989    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1990    struct temp_texture *tex = get_temp_texture(ctx);
1991    const char *texTarget;
1992
1993    assert(drawpix->DepthFP == 0);
1994
1995    /* replace %s with "RECT" or "2D" */
1996    assert(strlen(program) + 4 < sizeof(program2));
1997    if (tex->Target == GL_TEXTURE_RECTANGLE)
1998       texTarget = "RECT";
1999    else
2000       texTarget = "2D";
2001    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
2002
2003    _mesa_GenPrograms(1, &drawpix->DepthFP);
2004    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
2005    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
2006                           strlen(program2), (const GLubyte *) program2);
2007 }
2008
2009
2010 /**
2011  * Meta implementation of ctx->Driver.DrawPixels() in terms
2012  * of texture mapping and polygon rendering.
2013  */
2014 void
2015 _mesa_meta_DrawPixels(struct gl_context *ctx,
2016                       GLint x, GLint y, GLsizei width, GLsizei height,
2017                       GLenum format, GLenum type,
2018                       const struct gl_pixelstore_attrib *unpack,
2019                       const GLvoid *pixels)
2020 {
2021    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
2022    struct temp_texture *tex = get_temp_texture(ctx);
2023    const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
2024    const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
2025    struct vertex {
2026       GLfloat x, y, z, s, t;
2027    };
2028    struct vertex verts[4];
2029    GLenum texIntFormat;
2030    GLboolean fallback, newTex;
2031    GLbitfield metaExtraSave = 0x0;
2032    GLuint vbo;
2033
2034    /*
2035     * Determine if we can do the glDrawPixels with texture mapping.
2036     */
2037    fallback = GL_FALSE;
2038    if (ctx->_ImageTransferState ||
2039        ctx->Fog.Enabled) {
2040       fallback = GL_TRUE;
2041    }
2042
2043    if (_mesa_is_color_format(format)) {
2044       /* use more compact format when possible */
2045       /* XXX disable special case for GL_LUMINANCE for now to work around
2046        * apparent i965 driver bug (see bug #23670).
2047        */
2048       if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
2049          texIntFormat = format;
2050       else
2051          texIntFormat = GL_RGBA;
2052
2053       /* If we're not supposed to clamp the resulting color, then just
2054        * promote our texture to fully float.  We could do better by
2055        * just going for the matching set of channels, in floating
2056        * point.
2057        */
2058       if (ctx->Color.ClampFragmentColor != GL_TRUE &&
2059           ctx->Extensions.ARB_texture_float)
2060          texIntFormat = GL_RGBA32F;
2061    }
2062    else if (_mesa_is_stencil_format(format)) {
2063       if (ctx->Extensions.ARB_fragment_program &&
2064           ctx->Pixel.IndexShift == 0 &&
2065           ctx->Pixel.IndexOffset == 0 &&
2066           type == GL_UNSIGNED_BYTE) {
2067          /* We'll store stencil as alpha.  This only works for GLubyte
2068           * image data because of how incoming values are mapped to alpha
2069           * in [0,1].
2070           */
2071          texIntFormat = GL_ALPHA;
2072          metaExtraSave = (META_COLOR_MASK |
2073                           META_DEPTH_TEST |
2074                           META_SHADER |
2075                           META_STENCIL_TEST);
2076       }
2077       else {
2078          fallback = GL_TRUE;
2079       }
2080    }
2081    else if (_mesa_is_depth_format(format)) {
2082       if (ctx->Extensions.ARB_depth_texture &&
2083           ctx->Extensions.ARB_fragment_program) {
2084          texIntFormat = GL_DEPTH_COMPONENT;
2085          metaExtraSave = (META_SHADER);
2086       }
2087       else {
2088          fallback = GL_TRUE;
2089       }
2090    }
2091    else {
2092       fallback = GL_TRUE;
2093    }
2094
2095    if (fallback) {
2096       _swrast_DrawPixels(ctx, x, y, width, height,
2097                          format, type, unpack, pixels);
2098       return;
2099    }
2100
2101    /*
2102     * Check image size against max texture size, draw as tiles if needed.
2103     */
2104    if (width > tex->MaxSize || height > tex->MaxSize) {
2105       tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
2106                         format, type, unpack, pixels);
2107       return;
2108    }
2109
2110    /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
2111     * but a there's a few things we need to override:
2112     */
2113    _mesa_meta_begin(ctx, (META_RASTERIZATION |
2114                           META_SHADER |
2115                           META_TEXTURE |
2116                           META_TRANSFORM |
2117                           META_CLIP |
2118                           META_VERTEX |
2119                           META_VIEWPORT |
2120                           META_CLAMP_FRAGMENT_COLOR |
2121                           metaExtraSave));
2122
2123    newTex = alloc_texture(tex, width, height, texIntFormat);
2124
2125    /* vertex positions, texcoords (after texture allocation!) */
2126    {
2127       const GLfloat x0 = (GLfloat) x;
2128       const GLfloat y0 = (GLfloat) y;
2129       const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
2130       const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
2131       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
2132
2133       verts[0].x = x0;
2134       verts[0].y = y0;
2135       verts[0].z = z;
2136       verts[0].s = 0.0F;
2137       verts[0].t = 0.0F;
2138       verts[1].x = x1;
2139       verts[1].y = y0;
2140       verts[1].z = z;
2141       verts[1].s = tex->Sright;
2142       verts[1].t = 0.0F;
2143       verts[2].x = x1;
2144       verts[2].y = y1;
2145       verts[2].z = z;
2146       verts[2].s = tex->Sright;
2147       verts[2].t = tex->Ttop;
2148       verts[3].x = x0;
2149       verts[3].y = y1;
2150       verts[3].z = z;
2151       verts[3].s = 0.0F;
2152       verts[3].t = tex->Ttop;
2153    }
2154
2155    if (drawpix->ArrayObj == 0) {
2156       /* one-time setup: create vertex array object */
2157       _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
2158    }
2159    _mesa_BindVertexArray(drawpix->ArrayObj);
2160
2161    /* create vertex array buffer */
2162    _mesa_GenBuffersARB(1, &vbo);
2163    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
2164    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2165                        verts, GL_DYNAMIC_DRAW_ARB);
2166
2167    /* setup vertex arrays */
2168    _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2169    _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2170    _mesa_EnableClientState(GL_VERTEX_ARRAY);
2171    _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2172
2173    /* set given unpack params */
2174    ctx->Unpack = *unpack;
2175
2176    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
2177
2178    if (_mesa_is_stencil_format(format)) {
2179       /* Drawing stencil */
2180       GLint bit;
2181
2182       if (!drawpix->StencilFP)
2183          init_draw_stencil_pixels(ctx);
2184
2185       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2186                             GL_ALPHA, type, pixels);
2187
2188       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
2189
2190       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
2191
2192       /* set all stencil bits to 0 */
2193       _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2194       _mesa_StencilFunc(GL_ALWAYS, 0, 255);
2195       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2196   
2197       /* set stencil bits to 1 where needed */
2198       _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2199
2200       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
2201       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
2202
2203       for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
2204          const GLuint mask = 1 << bit;
2205          if (mask & origStencilMask) {
2206             _mesa_StencilFunc(GL_ALWAYS, mask, mask);
2207             _mesa_StencilMask(mask);
2208
2209             _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
2210                                              255.0 / mask, 0.5, 0.0, 0.0);
2211
2212             _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2213          }
2214       }
2215    }
2216    else if (_mesa_is_depth_format(format)) {
2217       /* Drawing depth */
2218       if (!drawpix->DepthFP)
2219          init_draw_depth_pixels(ctx);
2220
2221       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
2222       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
2223
2224       /* polygon color = current raster color */
2225       _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
2226                                         ctx->Current.RasterColor);
2227
2228       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2229                             format, type, pixels);
2230
2231       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2232    }
2233    else {
2234       /* Drawing RGBA */
2235       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2236                             format, type, pixels);
2237       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2238    }
2239
2240    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
2241
2242    _mesa_DeleteBuffersARB(1, &vbo);
2243
2244    /* restore unpack params */
2245    ctx->Unpack = unpackSave;
2246
2247    _mesa_meta_end(ctx);
2248 }
2249
2250 static GLboolean
2251 alpha_test_raster_color(struct gl_context *ctx)
2252 {
2253    GLfloat alpha = ctx->Current.RasterColor[ACOMP];
2254    GLfloat ref = ctx->Color.AlphaRef;
2255
2256    switch (ctx->Color.AlphaFunc) {
2257       case GL_NEVER:
2258          return GL_FALSE;
2259       case GL_LESS:
2260          return alpha < ref;
2261       case GL_EQUAL:
2262          return alpha == ref;
2263       case GL_LEQUAL:
2264          return alpha <= ref;
2265       case GL_GREATER:
2266          return alpha > ref;
2267       case GL_NOTEQUAL:
2268          return alpha != ref;
2269       case GL_GEQUAL:
2270          return alpha >= ref;
2271       case GL_ALWAYS:
2272          return GL_TRUE;
2273       default:
2274          assert(0);
2275          return GL_FALSE;
2276    }
2277 }
2278
2279 /**
2280  * Do glBitmap with a alpha texture quad.  Use the alpha test to cull
2281  * the 'off' bits.  A bitmap cache as in the gallium/mesa state
2282  * tracker would improve performance a lot.
2283  */
2284 void
2285 _mesa_meta_Bitmap(struct gl_context *ctx,
2286                   GLint x, GLint y, GLsizei width, GLsizei height,
2287                   const struct gl_pixelstore_attrib *unpack,
2288                   const GLubyte *bitmap1)
2289 {
2290    struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
2291    struct temp_texture *tex = get_bitmap_temp_texture(ctx);
2292    const GLenum texIntFormat = GL_ALPHA;
2293    const struct gl_pixelstore_attrib unpackSave = *unpack;
2294    GLubyte fg, bg;
2295    struct vertex {
2296       GLfloat x, y, z, s, t, r, g, b, a;
2297    };
2298    struct vertex verts[4];
2299    GLboolean newTex;
2300    GLubyte *bitmap8;
2301
2302    /*
2303     * Check if swrast fallback is needed.
2304     */
2305    if (ctx->_ImageTransferState ||
2306        ctx->FragmentProgram._Enabled ||
2307        ctx->Fog.Enabled ||
2308        ctx->Texture._EnabledUnits ||
2309        width > tex->MaxSize ||
2310        height > tex->MaxSize) {
2311       _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
2312       return;
2313    }
2314
2315    if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
2316       return;
2317
2318    /* Most GL state applies to glBitmap (like blending, stencil, etc),
2319     * but a there's a few things we need to override:
2320     */
2321    _mesa_meta_begin(ctx, (META_ALPHA_TEST |
2322                           META_PIXEL_STORE |
2323                           META_RASTERIZATION |
2324                           META_SHADER |
2325                           META_TEXTURE |
2326                           META_TRANSFORM |
2327                           META_CLIP |
2328                           META_VERTEX |
2329                           META_VIEWPORT));
2330
2331    if (bitmap->ArrayObj == 0) {
2332       /* one-time setup */
2333
2334       /* create vertex array object */
2335       _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
2336       _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
2337
2338       /* create vertex array buffer */
2339       _mesa_GenBuffersARB(1, &bitmap->VBO);
2340       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
2341       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2342                           NULL, GL_DYNAMIC_DRAW_ARB);
2343
2344       /* setup vertex arrays */
2345       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2346       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2347       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
2348       _mesa_EnableClientState(GL_VERTEX_ARRAY);
2349       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2350       _mesa_EnableClientState(GL_COLOR_ARRAY);
2351    }
2352    else {
2353       _mesa_BindVertexArray(bitmap->ArrayObj);
2354       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
2355    }
2356
2357    newTex = alloc_texture(tex, width, height, texIntFormat);
2358
2359    /* vertex positions, texcoords, colors (after texture allocation!) */
2360    {
2361       const GLfloat x0 = (GLfloat) x;
2362       const GLfloat y0 = (GLfloat) y;
2363       const GLfloat x1 = (GLfloat) (x + width);
2364       const GLfloat y1 = (GLfloat) (y + height);
2365       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
2366       GLuint i;
2367
2368       verts[0].x = x0;
2369       verts[0].y = y0;
2370       verts[0].z = z;
2371       verts[0].s = 0.0F;
2372       verts[0].t = 0.0F;
2373       verts[1].x = x1;
2374       verts[1].y = y0;
2375       verts[1].z = z;
2376       verts[1].s = tex->Sright;
2377       verts[1].t = 0.0F;
2378       verts[2].x = x1;
2379       verts[2].y = y1;
2380       verts[2].z = z;
2381       verts[2].s = tex->Sright;
2382       verts[2].t = tex->Ttop;
2383       verts[3].x = x0;
2384       verts[3].y = y1;
2385       verts[3].z = z;
2386       verts[3].s = 0.0F;
2387       verts[3].t = tex->Ttop;
2388
2389       for (i = 0; i < 4; i++) {
2390          verts[i].r = ctx->Current.RasterColor[0];
2391          verts[i].g = ctx->Current.RasterColor[1];
2392          verts[i].b = ctx->Current.RasterColor[2];
2393          verts[i].a = ctx->Current.RasterColor[3];
2394       }
2395
2396       /* upload new vertex data */
2397       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2398    }
2399
2400    /* choose different foreground/background alpha values */
2401    CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
2402    bg = (fg > 127 ? 0 : 255);
2403
2404    bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
2405    if (!bitmap1) {
2406       _mesa_meta_end(ctx);
2407       return;
2408    }
2409
2410    bitmap8 = (GLubyte *) malloc(width * height);
2411    if (bitmap8) {
2412       memset(bitmap8, bg, width * height);
2413       _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
2414                           bitmap8, width, fg);
2415
2416       _mesa_set_enable(ctx, tex->Target, GL_TRUE);
2417
2418       _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
2419       _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
2420
2421       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2422                             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
2423
2424       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2425
2426       _mesa_set_enable(ctx, tex->Target, GL_FALSE);
2427
2428       free(bitmap8);
2429    }
2430
2431    _mesa_unmap_pbo_source(ctx, &unpackSave);
2432
2433    _mesa_meta_end(ctx);
2434 }
2435
2436
2437 /**
2438  * Check if the call to _mesa_meta_GenerateMipmap() will require a
2439  * software fallback.  The fallback path will require that the texture
2440  * images are mapped.
2441  * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
2442  */
2443 GLboolean
2444 _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
2445                                           struct gl_texture_object *texObj)
2446 {
2447    const GLuint fboSave = ctx->DrawBuffer->Name;
2448    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
2449    struct gl_texture_image *baseImage;
2450    GLuint srcLevel;
2451    GLenum status;
2452
2453    /* check for fallbacks */
2454    if (!ctx->Extensions.EXT_framebuffer_object ||
2455        target == GL_TEXTURE_3D) {
2456       return GL_TRUE;
2457    }
2458
2459    srcLevel = texObj->BaseLevel;
2460    baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
2461    if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) {
2462       return GL_TRUE;
2463    }
2464
2465    /*
2466     * Test that we can actually render in the texture's format.
2467     */
2468    if (!mipmap->FBO)
2469       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
2470    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
2471
2472    if (target == GL_TEXTURE_1D) {
2473       _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
2474                                     GL_COLOR_ATTACHMENT0_EXT,
2475                                     target, texObj->Name, srcLevel);
2476    }
2477 #if 0
2478    /* other work is needed to enable 3D mipmap generation */
2479    else if (target == GL_TEXTURE_3D) {
2480       GLint zoffset = 0;
2481       _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
2482                                     GL_COLOR_ATTACHMENT0_EXT,
2483                                     target, texObj->Name, srcLevel, zoffset);
2484    }
2485 #endif
2486    else {
2487       /* 2D / cube */
2488       _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2489                                     GL_COLOR_ATTACHMENT0_EXT,
2490                                     target, texObj->Name, srcLevel);
2491    }
2492
2493    status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
2494
2495    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2496
2497    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2498       return GL_TRUE;
2499    }
2500
2501    return GL_FALSE;
2502 }
2503
2504
2505 /**
2506  * Called via ctx->Driver.GenerateMipmap()
2507  * Note: texture borders and 3D texture support not yet complete.
2508  */
2509 void
2510 _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
2511                           struct gl_texture_object *texObj)
2512 {
2513    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
2514    struct vertex {
2515       GLfloat x, y, s, t, r;
2516    };
2517    struct vertex verts[4];
2518    const GLuint baseLevel = texObj->BaseLevel;
2519    const GLuint maxLevel = texObj->MaxLevel;
2520    const GLenum minFilterSave = texObj->Sampler.MinFilter;
2521    const GLenum magFilterSave = texObj->Sampler.MagFilter;
2522    const GLint maxLevelSave = texObj->MaxLevel;
2523    const GLboolean genMipmapSave = texObj->GenerateMipmap;
2524    const GLenum wrapSSave = texObj->Sampler.WrapS;
2525    const GLenum wrapTSave = texObj->Sampler.WrapT;
2526    const GLenum wrapRSave = texObj->Sampler.WrapR;
2527    const GLuint fboSave = ctx->DrawBuffer->Name;
2528    const GLuint original_active_unit = ctx->Texture.CurrentUnit;
2529    GLenum faceTarget;
2530    GLuint dstLevel;
2531    GLuint border = 0;
2532
2533    if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
2534       _mesa_generate_mipmap(ctx, target, texObj);
2535       return;
2536    }
2537
2538    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
2539        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
2540       faceTarget = target;
2541       target = GL_TEXTURE_CUBE_MAP;
2542    }
2543    else {
2544       faceTarget = target;
2545    }
2546
2547    _mesa_meta_begin(ctx, META_ALL);
2548
2549    if (original_active_unit != 0)
2550       _mesa_BindTexture(target, texObj->Name);
2551
2552    if (mipmap->ArrayObj == 0) {
2553       /* one-time setup */
2554
2555       /* create vertex array object */
2556       _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
2557       _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
2558
2559       /* create vertex array buffer */
2560       _mesa_GenBuffersARB(1, &mipmap->VBO);
2561       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
2562       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2563                           NULL, GL_DYNAMIC_DRAW_ARB);
2564
2565       /* setup vertex arrays */
2566       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2567       _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2568       _mesa_EnableClientState(GL_VERTEX_ARRAY);
2569       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2570    }
2571    else {
2572       _mesa_BindVertexArray(mipmap->ArrayObj);
2573       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
2574    }
2575
2576    if (!mipmap->FBO) {
2577       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
2578    }
2579    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
2580
2581    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2582    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2583    _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
2584    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2585    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2586    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2587
2588    _mesa_set_enable(ctx, target, GL_TRUE);
2589
2590    /* setup texcoords once (XXX what about border?) */
2591    switch (faceTarget) {
2592    case GL_TEXTURE_1D:
2593    case GL_TEXTURE_2D:
2594       verts[0].s = 0.0F;
2595       verts[0].t = 0.0F;
2596       verts[0].r = 0.0F;
2597       verts[1].s = 1.0F;
2598       verts[1].t = 0.0F;
2599       verts[1].r = 0.0F;
2600       verts[2].s = 1.0F;
2601       verts[2].t = 1.0F;
2602       verts[2].r = 0.0F;
2603       verts[3].s = 0.0F;
2604       verts[3].t = 1.0F;
2605       verts[3].r = 0.0F;
2606       break;
2607    case GL_TEXTURE_3D:
2608       abort();
2609       break;
2610    default:
2611       /* cube face */
2612       {
2613          static const GLfloat st[4][2] = {
2614             {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
2615          };
2616          GLuint i;
2617
2618          /* loop over quad verts */
2619          for (i = 0; i < 4; i++) {
2620             /* Compute sc = +/-scale and tc = +/-scale.
2621              * Not +/-1 to avoid cube face selection ambiguity near the edges,
2622              * though that can still sometimes happen with this scale factor...
2623              */
2624             const GLfloat scale = 0.9999f;
2625             const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
2626             const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
2627
2628             switch (faceTarget) {
2629             case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2630                verts[i].s = 1.0f;
2631                verts[i].t = -tc;
2632                verts[i].r = -sc;
2633                break;
2634             case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2635                verts[i].s = -1.0f;
2636                verts[i].t = -tc;
2637                verts[i].r = sc;
2638                break;
2639             case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2640                verts[i].s = sc;
2641                verts[i].t = 1.0f;
2642                verts[i].r = tc;
2643                break;
2644             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2645                verts[i].s = sc;
2646                verts[i].t = -1.0f;
2647                verts[i].r = -tc;
2648                break;
2649             case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2650                verts[i].s = sc;
2651                verts[i].t = -tc;
2652                verts[i].r = 1.0f;
2653                break;
2654             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2655                verts[i].s = -sc;
2656                verts[i].t = -tc;
2657                verts[i].r = -1.0f;
2658                break;
2659             default:
2660                assert(0);
2661             }
2662          }
2663       }
2664    }
2665
2666    _mesa_set_enable(ctx, target, GL_TRUE);
2667
2668    /* setup vertex positions */
2669    {
2670       verts[0].x = 0.0F;
2671       verts[0].y = 0.0F;
2672       verts[1].x = 1.0F;
2673       verts[1].y = 0.0F;
2674       verts[2].x = 1.0F;
2675       verts[2].y = 1.0F;
2676       verts[3].x = 0.0F;
2677       verts[3].y = 1.0F;
2678       
2679       /* upload new vertex data */
2680       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2681    }
2682
2683    /* setup projection matrix */
2684    _mesa_MatrixMode(GL_PROJECTION);
2685    _mesa_LoadIdentity();
2686    _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
2687
2688    /* texture is already locked, unlock now */
2689    _mesa_unlock_texture(ctx, texObj);
2690
2691    for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
2692       const struct gl_texture_image *srcImage;
2693       const GLuint srcLevel = dstLevel - 1;
2694       GLsizei srcWidth, srcHeight, srcDepth;
2695       GLsizei dstWidth, dstHeight, dstDepth;
2696       GLenum status;
2697
2698       srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
2699       assert(srcImage->Border == 0); /* XXX we can fix this */
2700
2701       /* src size w/out border */
2702       srcWidth = srcImage->Width - 2 * border;
2703       srcHeight = srcImage->Height - 2 * border;
2704       srcDepth = srcImage->Depth - 2 * border;
2705
2706       /* new dst size w/ border */
2707       dstWidth = MAX2(1, srcWidth / 2) + 2 * border;
2708       dstHeight = MAX2(1, srcHeight / 2) + 2 * border;
2709       dstDepth = MAX2(1, srcDepth / 2) + 2 * border;
2710
2711       if (dstWidth == srcImage->Width &&
2712           dstHeight == srcImage->Height &&
2713           dstDepth == srcImage->Depth) {
2714          /* all done */
2715          break;
2716       }
2717
2718       /* Set MaxLevel large enough to hold the new level when we allocate it  */
2719       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
2720
2721       /* Create empty dest image */
2722       if (target == GL_TEXTURE_1D) {
2723          _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
2724                           dstWidth, border,
2725                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2726       }
2727       else if (target == GL_TEXTURE_3D) {
2728          _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
2729                           dstWidth, dstHeight, dstDepth, border,
2730                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2731       }
2732       else {
2733          /* 2D or cube */
2734          _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
2735                           dstWidth, dstHeight, border,
2736                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2737
2738          if (target == GL_TEXTURE_CUBE_MAP) {
2739             /* If texturing from a cube, we need to make sure all src faces
2740              * have been defined (even if we're not sampling from them.)
2741              * Otherwise the texture object will be 'incomplete' and
2742              * texturing from it will not be allowed.
2743              */
2744             GLuint face;
2745             for (face = 0; face < 6; face++) {
2746                if (!texObj->Image[face][srcLevel] ||
2747                    texObj->Image[face][srcLevel]->Width != srcWidth) {
2748                   _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
2749                                    srcLevel, srcImage->InternalFormat,
2750                                    srcWidth, srcHeight, border,
2751                                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2752                }
2753             }
2754          }
2755       }
2756
2757       /* limit minification to src level */
2758       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
2759
2760       /* Set to draw into the current dstLevel */
2761       if (target == GL_TEXTURE_1D) {
2762          _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
2763                                        GL_COLOR_ATTACHMENT0_EXT,
2764                                        target,
2765                                        texObj->Name,
2766                                        dstLevel);
2767       }
2768       else if (target == GL_TEXTURE_3D) {
2769          GLint zoffset = 0; /* XXX unfinished */
2770          _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
2771                                        GL_COLOR_ATTACHMENT0_EXT,
2772                                        target,
2773                                        texObj->Name,
2774                                        dstLevel, zoffset);
2775       }
2776       else {
2777          /* 2D / cube */
2778          _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2779                                        GL_COLOR_ATTACHMENT0_EXT,
2780                                        faceTarget,
2781                                        texObj->Name,
2782                                        dstLevel);
2783       }
2784
2785       _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
2786
2787       /* sanity check */
2788       status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
2789       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2790          abort();
2791          break;
2792       }
2793
2794       assert(dstWidth == ctx->DrawBuffer->Width);
2795       assert(dstHeight == ctx->DrawBuffer->Height);
2796
2797       /* setup viewport */
2798       _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
2799
2800       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2801    }
2802
2803    _mesa_lock_texture(ctx, texObj); /* relock */
2804
2805    _mesa_meta_end(ctx);
2806
2807    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
2808    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
2809    _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
2810    _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
2811    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
2812    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
2813    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave);
2814
2815    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2816 }
2817
2818
2819 /**
2820  * Determine the GL data type to use for the temporary image read with
2821  * ReadPixels() and passed to Tex[Sub]Image().
2822  */
2823 static GLenum
2824 get_temp_image_type(struct gl_context *ctx, GLenum baseFormat)
2825 {
2826    switch (baseFormat) {
2827    case GL_RGBA:
2828    case GL_RGB:
2829    case GL_ALPHA:
2830    case GL_LUMINANCE:
2831    case GL_LUMINANCE_ALPHA:
2832    case GL_INTENSITY:
2833       if (ctx->DrawBuffer->Visual.redBits <= 8)
2834          return GL_UNSIGNED_BYTE;
2835       else if (ctx->DrawBuffer->Visual.redBits <= 8)
2836          return GL_UNSIGNED_SHORT;
2837       else
2838          return GL_FLOAT;
2839    case GL_DEPTH_COMPONENT:
2840       return GL_UNSIGNED_INT;
2841    case GL_DEPTH_STENCIL:
2842       return GL_UNSIGNED_INT_24_8;
2843    default:
2844       _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
2845       return 0;
2846    }
2847 }
2848
2849
2850 /**
2851  * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
2852  * Have to be careful with locking and meta state for pixel transfer.
2853  */
2854 static void
2855 copy_tex_sub_image(struct gl_context *ctx,
2856                    GLuint dims, GLenum target, GLint level,
2857                    GLint xoffset, GLint yoffset, GLint zoffset,
2858                    GLint x, GLint y,
2859                    GLsizei width, GLsizei height)
2860 {
2861    struct gl_texture_object *texObj;
2862    struct gl_texture_image *texImage;
2863    GLenum format, type;
2864    GLint bpp;
2865    void *buf;
2866
2867    texObj = _mesa_get_current_tex_object(ctx, target);
2868    texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2869
2870    /* Choose format/type for temporary image buffer */
2871    format = _mesa_get_format_base_format(texImage->TexFormat);
2872    if (format == GL_LUMINANCE ||
2873        format == GL_LUMINANCE_ALPHA ||
2874        format == GL_INTENSITY) {
2875       /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the
2876        * temp image buffer because glReadPixels will do L=R+G+B which is
2877        * not what we want (should be L=R).
2878        */
2879       format = GL_RGBA;
2880    }
2881
2882    type = get_temp_image_type(ctx, format);
2883    bpp = _mesa_bytes_per_pixel(format, type);
2884    if (bpp <= 0) {
2885       _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()");
2886       return;
2887    }
2888
2889    /*
2890     * Alloc image buffer (XXX could use a PBO)
2891     */
2892    buf = malloc(width * height * bpp);
2893    if (!buf) {
2894       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
2895       return;
2896    }
2897
2898    _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
2899
2900    /*
2901     * Read image from framebuffer (disable pixel transfer ops)
2902     */
2903    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2904    ctx->Driver.ReadPixels(ctx, x, y, width, height,
2905                           format, type, &ctx->Pack, buf);
2906    _mesa_meta_end(ctx);
2907
2908    _mesa_update_state(ctx); /* to update pixel transfer state */
2909
2910    /*
2911     * Store texture data (with pixel transfer ops)
2912     */
2913    _mesa_meta_begin(ctx, META_PIXEL_STORE);
2914    if (target == GL_TEXTURE_1D) {
2915       ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
2916                                 width, format, type, buf,
2917                                 &ctx->Unpack, texObj, texImage);
2918    }
2919    else if (target == GL_TEXTURE_3D) {
2920       ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
2921                                 width, height, 1, format, type, buf,
2922                                 &ctx->Unpack, texObj, texImage);
2923    }
2924    else {
2925       ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
2926                                 width, height, format, type, buf,
2927                                 &ctx->Unpack, texObj, texImage);
2928    }
2929    _mesa_meta_end(ctx);
2930
2931    _mesa_lock_texture(ctx, texObj); /* re-lock */
2932
2933    free(buf);
2934 }
2935
2936
2937 void
2938 _mesa_meta_CopyTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
2939                              GLint xoffset,
2940                              GLint x, GLint y, GLsizei width)
2941 {
2942    copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
2943                       x, y, width, 1);
2944 }
2945
2946
2947 void
2948 _mesa_meta_CopyTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
2949                              GLint xoffset, GLint yoffset,
2950                              GLint x, GLint y,
2951                              GLsizei width, GLsizei height)
2952 {
2953    copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
2954                       x, y, width, height);
2955 }
2956
2957
2958 void
2959 _mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
2960                              GLint xoffset, GLint yoffset, GLint zoffset,
2961                              GLint x, GLint y,
2962                              GLsizei width, GLsizei height)
2963 {
2964    copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
2965                       x, y, width, height);
2966 }
2967
2968
2969 void
2970 _mesa_meta_CopyColorTable(struct gl_context *ctx,
2971                           GLenum target, GLenum internalformat,
2972                           GLint x, GLint y, GLsizei width)
2973 {
2974    GLfloat *buf;
2975
2976    buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
2977    if (!buf) {
2978       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
2979       return;
2980    }
2981
2982    /*
2983     * Read image from framebuffer (disable pixel transfer ops)
2984     */
2985    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2986    ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2987                           GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2988
2989    _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
2990
2991    _mesa_meta_end(ctx);
2992
2993    free(buf);
2994 }
2995
2996
2997 void
2998 _mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start,
2999                              GLint x, GLint y, GLsizei width)
3000 {
3001    GLfloat *buf;
3002
3003    buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
3004    if (!buf) {
3005       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
3006       return;
3007    }
3008
3009    /*
3010     * Read image from framebuffer (disable pixel transfer ops)
3011     */
3012    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
3013    ctx->Driver.ReadPixels(ctx, x, y, width, 1,
3014                           GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
3015
3016    _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
3017
3018    _mesa_meta_end(ctx);
3019
3020    free(buf);
3021 }