OSDN Git Service

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