OSDN Git Service

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